| Index: tools/clang/scripts/update.py
 | 
| diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
 | 
| index 7c4a21442abf18cdf71b76aabe13281e2bf05b06..30d9ce91e62365b42f7f5984671aa877781740ab 100755
 | 
| --- a/tools/clang/scripts/update.py
 | 
| +++ b/tools/clang/scripts/update.py
 | 
| @@ -6,6 +6,7 @@
 | 
|  """Windows can't run .sh files, so this is a Python implementation of
 | 
|  update.sh. This script should replace update.sh on all platforms eventually."""
 | 
|  
 | 
| +import argparse
 | 
|  import os
 | 
|  import re
 | 
|  import shutil
 | 
| @@ -24,12 +25,13 @@ LLVM_WIN_REVISION = 'HEAD'
 | 
|  # in bringup. Use a pinned revision to make it slightly more stable.
 | 
|  if (re.search(r'\b(asan)=1', os.environ.get('GYP_DEFINES', '')) and
 | 
|      not 'LLVM_FORCE_HEAD_REVISION' in os.environ):
 | 
| -  LLVM_WIN_REVISION = '232554'
 | 
| +  LLVM_WIN_REVISION = '235793'
 | 
|  
 | 
|  # Path constants. (All of these should be absolute paths.)
 | 
|  THIS_DIR = os.path.abspath(os.path.dirname(__file__))
 | 
|  CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
 | 
|  LLVM_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm')
 | 
| +CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
 | 
|  LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
 | 
|                                'Release+Asserts')
 | 
|  COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
 | 
| @@ -129,6 +131,32 @@ def Checkout(name, url, dir):
 | 
|    RunCommand(command)
 | 
|  
 | 
|  
 | 
| +def DeleteChromeToolsShim():
 | 
| +  shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
 | 
| +
 | 
| +
 | 
| +def CreateChromeToolsShim():
 | 
| +  """Hooks the Chrome tools into the LLVM build.
 | 
| +
 | 
| +  Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
 | 
| +  detects implicit tools in the tools subdirectory, so this helper install a
 | 
| +  shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
 | 
| +
 | 
| +  Note that the shim directory name intentionally has no - or _. The implicit
 | 
| +  tool detection logic munges them in a weird way."""
 | 
| +  assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
 | 
| +  os.mkdir(CHROME_TOOLS_SHIM_DIR)
 | 
| +  with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
 | 
| +    f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
 | 
| +            'Do not edit.\n')
 | 
| +    f.write('# Since tools/clang is located in another directory, use the \n')
 | 
| +    f.write('# two arg version to specify where build artifacts go. CMake\n')
 | 
| +    f.write('# disallows reuse of the same binary dir for multiple source\n')
 | 
| +    f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
 | 
| +    f.write('add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
 | 
| +            '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
 | 
| +
 | 
| +
 | 
|  def AddCMakeToPath():
 | 
|    """Look for CMake and add it to PATH if it's not there already."""
 | 
|    try:
 | 
| @@ -181,30 +209,38 @@ def SubversionCmakeArg():
 | 
|    return ''
 | 
|  
 | 
|  
 | 
| -def UpdateClang():
 | 
| +def UpdateClang(args):
 | 
|    print 'Updating Clang to %s...' % (LLVM_WIN_REVISION)
 | 
|    if LLVM_WIN_REVISION != 'HEAD' and ReadStampFile() == LLVM_WIN_REVISION:
 | 
|      print 'Already up to date.'
 | 
|      return 0
 | 
|  
 | 
|    AddCMakeToPath()
 | 
| -  ClobberChromiumBuildFiles()
 | 
| +  if args.clobber:
 | 
| +    ClobberChromiumBuildFiles()
 | 
|  
 | 
|    # Reset the stamp file in case the build is unsuccessful.
 | 
|    WriteStampFile('')
 | 
|  
 | 
| +  DeleteChromeToolsShim();
 | 
|    Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
 | 
|    Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
 | 
|    Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
 | 
|    Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
 | 
| +  CreateChromeToolsShim();
 | 
|  
 | 
|    if not os.path.exists(LLVM_BUILD_DIR):
 | 
|      os.makedirs(LLVM_BUILD_DIR)
 | 
|    os.chdir(LLVM_BUILD_DIR)
 | 
|  
 | 
| +  cmake_args = ['-GNinja', '-DCMAKE_BUILD_TYPE=Release',
 | 
| +                '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(),
 | 
| +                '-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(
 | 
| +                    CHROMIUM_DIR, 'tools', 'clang'),
 | 
| +                '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
 | 
| +
 | 
|    RunCommand(GetVSVersion().SetupScript('x64') +
 | 
| -             ['&&', 'cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=Release',
 | 
| -              '-DLLVM_ENABLE_ASSERTIONS=ON', SubversionCmakeArg(), LLVM_DIR])
 | 
| +             ['&&', 'cmake'] + cmake_args + [LLVM_DIR])
 | 
|    RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all'])
 | 
|  
 | 
|    # Do an x86 build of compiler-rt to get the 32-bit ASan run-time.
 | 
| @@ -213,8 +249,7 @@ def UpdateClang():
 | 
|      os.makedirs(COMPILER_RT_BUILD_DIR)
 | 
|    os.chdir(COMPILER_RT_BUILD_DIR)
 | 
|    RunCommand(GetVSVersion().SetupScript('x86') +
 | 
| -             ['&&', 'cmake', '-GNinja', '-DCMAKE_BUILD_TYPE=Release',
 | 
| -              '-DLLVM_ENABLE_ASSERTIONS=ON', LLVM_DIR])
 | 
| +             ['&&', 'cmake'] + cmake_args + [LLVM_DIR])
 | 
|    RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt'])
 | 
|  
 | 
|    # TODO(hans): Make this (and the .gypi and .isolate files) version number
 | 
| @@ -276,7 +311,13 @@ def main():
 | 
|      print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
 | 
|      return 0
 | 
|  
 | 
| -  return UpdateClang()
 | 
| +  parser = argparse.ArgumentParser(description='Build Clang.')
 | 
| +  parser.add_argument('--no-clobber', dest='clobber', action='store_false')
 | 
| +  parser.add_argument('--tools', nargs='*', default=['plugins'])
 | 
| +  # For now, this flag is only used for the non-Windows flow, but argparser gets
 | 
| +  # mad if it sees a flag it doesn't recognize.
 | 
| +  parser.add_argument('--if-needed', action='store_true')
 | 
| +  return UpdateClang(parser.parse_args())
 | 
|  
 | 
|  
 | 
|  if __name__ == '__main__':
 | 
| 
 |