Update from https://crrev.com/305340

Added a few #includes of base/compiler_specific.h for upstream cleanup.

Changed callers for cc::BeginFrameArgs and cc::RendererSettings API
changes.

Review URL: https://codereview.chromium.org/754433003
diff --git a/tools/android/checkstyle/checkstyle.py b/tools/android/checkstyle/checkstyle.py
index c8ad04f..0c260bb 100644
--- a/tools/android/checkstyle/checkstyle.py
+++ b/tools/android/checkstyle/checkstyle.py
@@ -13,7 +13,7 @@
     os.path.join(os.path.dirname(__file__),
                  os.pardir, os.pardir, os.pardir))
 CHECKSTYLE_ROOT = os.path.join(CHROMIUM_SRC, 'third_party', 'checkstyle',
-                               'checkstyle-5.9-all.jar')
+                               'checkstyle-6.1-all.jar')
 
 
 def RunCheckstyle(input_api, output_api, style_file):
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index 46b19e9..c43f779 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -91,7 +91,7 @@
     </module>
     <module name="LineLength">
       <property name="severity" value="error"/>
-      <property name="ignorePattern" value="^import.*$" />
+      <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
       <property name="max" value="100"/>
     </module>
     <module name="LeftCurly">
@@ -138,6 +138,17 @@
       <property name="allowLineBreaks" value="true"/>
       <property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
     </module>
+    <module name="GenericWhitespace">
+      <property name="severity" value="error"/>
+      <message key="ws.followed"
+       value="GenericWhitespace ''{0}'' is followed by whitespace."/>
+       <message key="ws.preceded"
+       value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
+       <message key="ws.illegalFollow"
+       value="GenericWhitespace ''{0}'' should followed by whitespace."/>
+       <message key="ws.notPreceded"
+       value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
+    </module>
     <module name="EmptyStatement">
       <property name="severity" value="error"/>
     </module>
@@ -166,22 +177,22 @@
     </module>
     <!-- TODO(aurimas): make OperatorWrap into an error once all the warnings are fixed. -->
     <module name="OperatorWrap">
-      <property name="severity" value="warning"/>
+      <property name="severity" value="error"/>
       <property name="option" value="NL" />
       <property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR " />
     </module>
     <module name="OperatorWrap">
-     <property name="severity" value="warning"/>
+     <property name="severity" value="error"/>
      <property name="option" value="eol"/>
      <property name="tokens" value="ASSIGN"/>
     </module>
     <module name="SeparatorWrap">
-      <property name="severity" value="warning"/>
+      <property name="severity" value="error"/>
       <property name="tokens" value="DOT"/>
       <property name="option" value="nl"/>
     </module>
     <module name="SeparatorWrap">
-      <property name="severity" value="warning"/>
+      <property name="severity" value="error"/>
       <property name="tokens" value="COMMA"/>
       <property name="option" value="EOL"/>
     </module>
diff --git a/tools/clang/plugins/ChromeClassTester.cpp b/tools/clang/plugins/ChromeClassTester.cpp
index c8bc543..7e36653 100644
--- a/tools/clang/plugins/ChromeClassTester.cpp
+++ b/tools/clang/plugins/ChromeClassTester.cpp
@@ -206,7 +206,7 @@
   // Enum type with _LAST members where _LAST doesn't mean last enum value.
   ignored_record_names_.insert("ServerFieldType");
 
-  // Used heavily in ui_unittests and once in views_unittests. Fixing this
+  // Used heavily in ui_base_unittests and once in views_unittests. Fixing this
   // isn't worth the overhead of an additional library.
   ignored_record_names_.insert("TestAnimationDelegate");
 
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 0a230e0..f08ca71 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -724,28 +724,37 @@
       the_end(record->field_end());
   SourceLocation weak_ptr_factory_location;  // Invalid initially.
   for (; iter != the_end; ++iter) {
-    // If we enter the loop but have already seen a matching WeakPtrFactory,
-    // it means there is at least one member after the factory.
-    if (weak_ptr_factory_location.isValid()) {
-      diagnostic().Report(weak_ptr_factory_location,
-                          diag_weak_ptr_factory_order_);
-    }
     const TemplateSpecializationType* template_spec_type =
         iter->getType().getTypePtr()->getAs<TemplateSpecializationType>();
+    bool param_is_weak_ptr_factory_to_self = false;
     if (template_spec_type) {
       const TemplateDecl* template_decl =
           template_spec_type->getTemplateName().getAsTemplateDecl();
-      if (template_decl && template_spec_type->getNumArgs() >= 1) {
+      if (template_decl && template_spec_type->getNumArgs() == 1) {
         if (template_decl->getNameAsString().compare("WeakPtrFactory") == 0 &&
             GetNamespace(template_decl) == "base") {
+          // Only consider WeakPtrFactory members which are specialized for the
+          // owning class.
           const TemplateArgument& arg = template_spec_type->getArg(0);
           if (arg.getAsType().getTypePtr()->getAsCXXRecordDecl() ==
               record->getTypeForDecl()->getAsCXXRecordDecl()) {
-            weak_ptr_factory_location = iter->getLocation();
+            if (!weak_ptr_factory_location.isValid()) {
+              // Save the first matching WeakPtrFactory member for the
+              // diagnostic.
+              weak_ptr_factory_location = iter->getLocation();
+            }
+            param_is_weak_ptr_factory_to_self = true;
           }
         }
       }
     }
+    // If we've already seen a WeakPtrFactory<OwningType> and this param is not
+    // one of those, it means there is at least one member after a factory.
+    if (weak_ptr_factory_location.isValid() &&
+        !param_is_weak_ptr_factory_to_self) {
+      diagnostic().Report(weak_ptr_factory_location,
+                          diag_weak_ptr_factory_order_);
+    }
   }
 }
 
diff --git a/tools/clang/plugins/tests/weak_ptr_factory.cpp b/tools/clang/plugins/tests/weak_ptr_factory.cpp
index 79c23b4..50de97c 100644
--- a/tools/clang/plugins/tests/weak_ptr_factory.cpp
+++ b/tools/clang/plugins/tests/weak_ptr_factory.cpp
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "weak_ptr_factory.h"
+
 namespace should_succeed {
 
 class OnlyMember {
@@ -27,6 +28,13 @@
   base::WeakPtrFactory<FirstFactoryRefersToOtherType> factory_;
 };
 
+class TwoFactories {
+  bool bool_member_;
+  int int_member_;
+  base::WeakPtrFactory<TwoFactories> factory1_;
+  base::WeakPtrFactory<TwoFactories> factory2_;
+};
+
 }  // namespace should_succeed
 
 namespace should_fail {
@@ -42,6 +50,13 @@
   int int_member_;
 };
 
+class TwoFactoriesOneBad {
+  bool bool_member_;
+  base::WeakPtrFactory<TwoFactoriesOneBad> factory1_;
+  int int_member_;
+  base::WeakPtrFactory<TwoFactoriesOneBad> factory2_;
+};
+
 }  // namespace should_fail
 
 int main() {
diff --git a/tools/clang/plugins/tests/weak_ptr_factory.txt b/tools/clang/plugins/tests/weak_ptr_factory.txt
index f9c2c0a..820b7db 100644
--- a/tools/clang/plugins/tests/weak_ptr_factory.txt
+++ b/tools/clang/plugins/tests/weak_ptr_factory.txt
@@ -1,7 +1,10 @@
-weak_ptr_factory.cpp:35:38: warning: [chromium-style] WeakPtrFactory members which refer to their outer class must be the last member in the outer class definition.
+weak_ptr_factory.cpp:43:38: warning: [chromium-style] WeakPtrFactory members which refer to their outer class must be the last member in the outer class definition.
   base::WeakPtrFactory<FactoryFirst> factory_;
                                      ^
-weak_ptr_factory.cpp:41:39: warning: [chromium-style] WeakPtrFactory members which refer to their outer class must be the last member in the outer class definition.
+weak_ptr_factory.cpp:49:39: warning: [chromium-style] WeakPtrFactory members which refer to their outer class must be the last member in the outer class definition.
   base::WeakPtrFactory<FactoryMiddle> factory_;
                                       ^
-2 warnings generated.
+weak_ptr_factory.cpp:55:44: warning: [chromium-style] WeakPtrFactory members which refer to their outer class must be the last member in the outer class definition.
+  base::WeakPtrFactory<TwoFactoriesOneBad> factory1_;
+                                           ^
+3 warnings generated.
diff --git a/tools/clang/rewrite_scoped_refptr/CMakeLists.txt b/tools/clang/rewrite_scoped_refptr/CMakeLists.txt
index 9b0184d..aa47400 100644
--- a/tools/clang/rewrite_scoped_refptr/CMakeLists.txt
+++ b/tools/clang/rewrite_scoped_refptr/CMakeLists.txt
@@ -2,6 +2,7 @@
   BitReader
   MCParser
   Option
+  X86AsmParser
   )
 
 add_llvm_executable(rewrite_scoped_refptr
diff --git a/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
index fe9d860..e11d5f9 100644
--- a/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
+++ b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
@@ -22,6 +22,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/support/TargetSelect.h"
 
 using namespace clang::ast_matchers;
 using clang::tooling::CommonOptionsParser;
@@ -255,6 +256,10 @@
 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
 
 int main(int argc, const char* argv[]) {
+  // TODO(dcheng): Clang tooling should do this itself.
+  // http://llvm.org/bugs/show_bug.cgi?id=21627
+  llvm::InitializeNativeTarget();
+  llvm::InitializeNativeTargetAsmParser();
   llvm::cl::OptionCategory category("Remove scoped_refptr conversions");
   CommonOptionsParser options(argc, argv, category);
   clang::tooling::ClangTool tool(options.getCompilations(),
diff --git a/tools/clang/scripts/generate_win_compdb.py b/tools/clang/scripts/generate_win_compdb.py
new file mode 100755
index 0000000..32f5f75
--- /dev/null
+++ b/tools/clang/scripts/generate_win_compdb.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Clang tools on Windows are still a bit busted. The tooling can't handle
+backslashes in paths, doesn't understand how to read .rsp files, etc. In
+addition, ninja generates compile commands prefixed with the ninja msvc helper,
+which also confuses clang. This script generates a compile DB that should mostly
+work until clang tooling can be improved upstream.
+"""
+
+import os
+import re
+import json
+import shlex
+import subprocess
+import sys
+
+
+_NINJA_MSVC_WRAPPER = re.compile('ninja -t msvc -e .+? -- ')
+_RSP_RE = re.compile(r' (@(.+?\.rsp)) ')
+
+
+def _ProcessEntry(e):
+  # Strip off the ninja -t msvc wrapper.
+  e['command'] = _NINJA_MSVC_WRAPPER.sub('', e['command'])
+
+  # Prepend --driver-mode=cl to the command's arguments.
+  # Escape backslashes so shlex doesn't try to interpret them.
+  escaped_command = e['command'].replace('\\', '\\\\')
+  split_command = shlex.split(escaped_command)
+  e['command'] = ' '.join(
+      split_command[:1] + ['--driver-mode=cl'] + split_command[1:])
+
+  # Expand the contents of the response file, if any.
+  # http://llvm.org/bugs/show_bug.cgi?id=21634
+  try:
+    match = _RSP_RE.search(e['command'])
+    rsp_path = os.path.join(e['directory'], match.group(2))
+    rsp_contents = file(rsp_path).read()
+    e['command'] = ''.join([
+        e['command'][:match.start(1)],
+        rsp_contents,
+        e['command'][match.end(1):]])
+  except IOError:
+    pass
+
+  # TODO(dcheng): This should be implemented in Clang tooling.
+  # http://llvm.org/bugs/show_bug.cgi?id=19687
+  # Finally, use slashes instead of backslashes to avoid bad escaping by the
+  # tooling. This should really only matter for command, but we do it for all
+  # keys for consistency.
+  e['directory'] = e['directory'].replace('\\', '/')
+  e['command'] = e['command'].replace('\\', '/')
+  e['file'] = e['file'].replace('\\', '/')
+
+  return e
+
+
+def main(argv):
+  # First, generate the compile database.
+  print 'Generating compile DB with ninja...'
+  compile_db_as_json = subprocess.check_output(shlex.split(
+      'ninja -C out/Debug -t compdb cc cxx objc objcxx'))
+
+  compile_db = json.loads(compile_db_as_json)
+  print 'Read in %d entries from the compile db' % len(compile_db)
+  compile_db = [_ProcessEntry(e) for e in compile_db]
+  original_length = len(compile_db)
+
+  # Filter out NaCl stuff. The clang tooling chokes on them.
+  compile_db = [e for e in compile_db if '_nacl.cc.pdb' not in e['command']
+      and '_nacl_win64.cc.pdb' not in e['command']]
+  print 'Filtered out %d entries...' % (original_length - len(compile_db))
+  f = file('out/Debug/compile_commands.json', 'w')
+  f.write(json.dumps(compile_db, indent=2))
+  print 'Done!'
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))
diff --git a/tools/clang/scripts/run_tool.py b/tools/clang/scripts/run_tool.py
index 61417e4..3725ca3 100755
--- a/tools/clang/scripts/run_tool.py
+++ b/tools/clang/scripts/run_tool.py
@@ -9,6 +9,9 @@
 If you want to run the tool across all Chromium code:
 run_tool.py <tool> <path/to/compiledb>
 
+If you want to include all files mentioned in the compilation database:
+run_tool.py <tool> <path/to/compiledb> --all
+
 If you only want to run the tool across just chrome/browser and content/browser:
 run_tool.py <tool> <path/to/compiledb> chrome/browser content/browser
 
@@ -37,6 +40,7 @@
 
 import collections
 import functools
+import json
 import multiprocessing
 import os.path
 import pipes
@@ -67,6 +71,20 @@
   return [os.path.realpath(p) for p in output.splitlines()]
 
 
+def _GetFilesFromCompileDB(build_directory):
+  """ Gets the list of files mentioned in the compilation database.
+
+  Args:
+    build_directory: Directory that contains the compile database.
+  """
+  compiledb_path = os.path.join(build_directory, 'compile_commands.json')
+  with open(compiledb_path, 'rb') as compiledb_file:
+    json_commands = json.load(compiledb_file)
+
+  return [os.path.join(entry['directory'], entry['file'])
+          for entry in json_commands]
+
+
 def _ExtractEditsFromStdout(build_directory, stdout):
   """Extracts generated list of edits from the tool's stdout.
 
@@ -295,7 +313,10 @@
   if not os.path.isfile(clang_format_diff_path) or sys.platform == 'win32':
     clang_format_diff_path = None
 
-  filenames = frozenset(_GetFilesFromGit(argv[2:]))
+  if len(argv) == 3 and argv[2] == '--all':
+    filenames = frozenset(_GetFilesFromCompileDB(argv[1]))
+  else:
+    filenames = frozenset(_GetFilesFromGit(argv[2:]))
   # Filter out files that aren't C/C++/Obj-C/Obj-C++.
   extensions = frozenset(('.c', '.cc', '.m', '.mm'))
   dispatcher = _CompilerDispatcher(argv[0], argv[1],
diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh
index e576cac..ad534ad 100755
--- a/tools/clang/scripts/update.sh
+++ b/tools/clang/scripts/update.sh
@@ -704,7 +704,8 @@
       --platform=android-14 \
       --install-dir="${LLVM_BUILD_DIR}/android-toolchain" \
       --system=linux-x86_64 \
-      --stl=stlport
+      --stl=stlport \
+      --toolchain=arm-linux-androideabi-4.9
 
   # Android NDK r9d copies a broken unwind.h into the toolchain, see
   # http://crbug.com/357890
diff --git a/tools/clang/translation_unit/CMakeLists.txt b/tools/clang/translation_unit/CMakeLists.txt
new file mode 100644
index 0000000..9b4fd8b
--- /dev/null
+++ b/tools/clang/translation_unit/CMakeLists.txt
@@ -0,0 +1,26 @@
+set(LLVM_LINK_COMPONENTS
+  BitReader
+  MCParser
+  Option
+  )
+
+add_llvm_executable(translation_unit
+  TranslationUnitGenerator.cpp
+  )
+
+target_link_libraries(translation_unit
+  clangAST
+  clangASTMatchers
+  clangAnalysis
+  clangBasic
+  clangDriver
+  clangEdit
+  clangFrontend
+  clangLex
+  clangParse
+  clangSema
+  clangSerialization
+  clangTooling
+  )
+
+cr_install(TARGETS translation_unit RUNTIME DESTINATION bin)
diff --git a/tools/clang/translation_unit/TranslationUnitGenerator.cpp b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
new file mode 100644
index 0000000..df9eaeb
--- /dev/null
+++ b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
@@ -0,0 +1,218 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This implements a Clang tool to generate compilation information that is
+// sufficient to recompile the code with clang. For each compilation unit, all
+// source files which are necessary for compiling it are determined. For each
+// compilation unit, a file is created containing a list of all file paths of
+// included files.
+
+#include <assert.h>
+#include <unistd.h>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <set>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/CommandLine.h"
+
+using clang::tooling::CommonOptionsParser;
+using std::set;
+using std::stack;
+using std::string;
+using std::vector;
+
+namespace {
+// Set of preprocessor callbacks used to record files included.
+class IncludeFinderPPCallbacks : public clang::PPCallbacks {
+ public:
+  IncludeFinderPPCallbacks(clang::SourceManager* source_manager,
+                           string* main_source_file,
+                           set<string>* source_file_paths)
+      : source_manager_(source_manager),
+        main_source_file_(main_source_file),
+        source_file_paths_(source_file_paths) {}
+  void FileChanged(clang::SourceLocation /*loc*/,
+                   clang::PPCallbacks::FileChangeReason reason,
+                   clang::SrcMgr::CharacteristicKind /*file_type*/,
+                   clang::FileID /*prev_fid*/) override;
+  void AddFile(const string& path);
+  void InclusionDirective(clang::SourceLocation hash_loc,
+                          const clang::Token& include_tok,
+                          llvm::StringRef file_name,
+                          bool is_angled,
+                          clang::CharSourceRange range,
+                          const clang::FileEntry* file,
+                          llvm::StringRef search_path,
+                          llvm::StringRef relative_path,
+                          const clang::Module* imported) override;
+  void EndOfMainFile() override;
+
+ private:
+  clang::SourceManager* const source_manager_;
+  string* const main_source_file_;
+  set<string>* const source_file_paths_;
+  // The path of the file that was last referenced by an inclusion directive,
+  // normalized for includes that are relative to a different source file.
+  string last_inclusion_directive_;
+  // The stack of currently parsed files. top() gives the current file.
+  stack<string> current_files_;
+};
+
+void IncludeFinderPPCallbacks::FileChanged(
+    clang::SourceLocation /*loc*/,
+    clang::PPCallbacks::FileChangeReason reason,
+    clang::SrcMgr::CharacteristicKind /*file_type*/,
+    clang::FileID /*prev_fid*/) {
+  if (reason == clang::PPCallbacks::EnterFile) {
+    if (!last_inclusion_directive_.empty()) {
+      current_files_.push(last_inclusion_directive_);
+    } else {
+      current_files_.push(
+          source_manager_->getFileEntryForID(source_manager_->getMainFileID())
+              ->getName());
+    }
+  } else if (reason == ExitFile) {
+    current_files_.pop();
+  }
+  // Other reasons are not interesting for us.
+}
+
+void IncludeFinderPPCallbacks::AddFile(const string& path) {
+  source_file_paths_->insert(path);
+}
+
+void IncludeFinderPPCallbacks::InclusionDirective(
+    clang::SourceLocation hash_loc,
+    const clang::Token& include_tok,
+    llvm::StringRef file_name,
+    bool is_angled,
+    clang::CharSourceRange range,
+    const clang::FileEntry* file,
+    llvm::StringRef search_path,
+    llvm::StringRef relative_path,
+    const clang::Module* imported) {
+  if (!file)
+    return;
+
+  assert(!current_files_.top().empty());
+  const clang::DirectoryEntry* const search_path_entry =
+      source_manager_->getFileManager().getDirectory(search_path);
+  const clang::DirectoryEntry* const current_file_parent_entry =
+      source_manager_->getFileManager()
+          .getFile(current_files_.top().c_str())
+          ->getDir();
+
+  // If the include file was found relatively to the current file's parent
+  // directory or a search path, we need to normalize it. This is necessary
+  // because llvm internalizes the path by which an inode was first accessed,
+  // and always returns that path afterwards. If we do not normalize this
+  // we will get an error when we replay the compilation, as the virtual
+  // file system is not aware of inodes.
+  if (search_path_entry == current_file_parent_entry) {
+    string parent =
+        llvm::sys::path::parent_path(current_files_.top().c_str()).str();
+
+    // If the file is a top level file ("file.cc"), we normalize to a path
+    // relative to "./".
+    if (parent.empty() || parent == "/")
+      parent = ".";
+
+    // Otherwise we take the literal path as we stored it for the current
+    // file, and append the relative path.
+    last_inclusion_directive_ = parent + "/" + relative_path.str();
+  } else if (!search_path.empty()) {
+    last_inclusion_directive_ = string(search_path) + "/" + relative_path.str();
+  } else {
+    last_inclusion_directive_ = file_name.str();
+  }
+  AddFile(last_inclusion_directive_);
+}
+
+void IncludeFinderPPCallbacks::EndOfMainFile() {
+  const clang::FileEntry* main_file =
+      source_manager_->getFileEntryForID(source_manager_->getMainFileID());
+  assert(*main_source_file_ == main_file->getName());
+  AddFile(main_file->getName());
+}
+
+class CompilationIndexerAction : public clang::PreprocessorFrontendAction {
+ public:
+  CompilationIndexerAction() {}
+  void ExecuteAction() override;
+
+  // Runs the preprocessor over the translation unit.
+  // This triggers the PPCallbacks we register to intercept all required
+  // files for the compilation.
+  void Preprocess();
+  void EndSourceFileAction() override;
+
+ private:
+  // Set up the state extracted during the compilation, and run Clang over the
+  // input.
+  string main_source_file_;
+  // Maps file names to their contents as read by Clang's source manager.
+  set<string> source_file_paths_;
+};
+
+void CompilationIndexerAction::ExecuteAction() {
+  vector<clang::FrontendInputFile> inputs =
+      getCompilerInstance().getFrontendOpts().Inputs;
+  assert(inputs.size() == 1);
+  main_source_file_ = inputs[0].getFile();
+
+  Preprocess();
+}
+
+void CompilationIndexerAction::Preprocess() {
+  clang::Preprocessor& preprocessor = getCompilerInstance().getPreprocessor();
+  preprocessor.addPPCallbacks(llvm::make_unique<IncludeFinderPPCallbacks>(
+      &getCompilerInstance().getSourceManager(),
+      &main_source_file_,
+      &source_file_paths_));
+  preprocessor.IgnorePragmas();
+  preprocessor.SetSuppressIncludeNotFoundError(true);
+  preprocessor.EnterMainSourceFile();
+  clang::Token token;
+  do {
+    preprocessor.Lex(token);
+  } while (token.isNot(clang::tok::eof));
+}
+
+void CompilationIndexerAction::EndSourceFileAction() {
+  std::ofstream out(main_source_file_ + ".filepaths");
+  for (string path : source_file_paths_) {
+    out << path << std::endl;
+  }
+}
+}  // namespace
+
+static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
+
+int main(int argc, const char* argv[]) {
+  llvm::cl::OptionCategory category("TranslationUnitGenerator Tool");
+  CommonOptionsParser options(argc, argv, category);
+  std::unique_ptr<clang::tooling::FrontendActionFactory> frontend_factory =
+      clang::tooling::newFrontendActionFactory<CompilationIndexerAction>();
+  clang::tooling::ClangTool tool(options.getCompilations(),
+                                 options.getSourcePathList());
+  // This clang tool does not actually produce edits, but run_tool.py expects
+  // this. So we just print an empty edit block.
+  llvm::outs() << "==== BEGIN EDITS ====\n";
+  llvm::outs() << "==== END EDITS ====\n";
+  return tool.run(frontend_factory.get());
+}
diff --git a/tools/clang/translation_unit/test_files/binomial.h b/tools/clang/translation_unit/test_files/binomial.h
new file mode 100644
index 0000000..c67b273
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/binomial.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#ifndef TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_BINOMIAL_H_
+#define TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_BINOMIAL_H_
+
+int binomial(int n, int k) {
+  return k > 0 ? binomial(n - 1, k - 1) * n / k : 1;
+}
+
+#endif  // TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_BINOMIAL_H_
diff --git a/tools/clang/translation_unit/test_files/test.cc b/tools/clang/translation_unit/test_files/test.cc
new file mode 100644
index 0000000..e735f55
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/test.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test.h"
+
+#include "binomial.h"
+
+// Notice that "binomial.h" is included both here and in the "test.h" file.
+// The tool should however print the path to this header file only once.
+
+int main() {
+  // Just some nonesense calculations.
+  int result = calculateNumberOfWaysToDistributeNItemsAmongKPersons(10, 5);
+  return result + binomial(42, 1);
+}
diff --git a/tools/clang/translation_unit/test_files/test.cc.filepaths.expected b/tools/clang/translation_unit/test_files/test.cc.filepaths.expected
new file mode 100644
index 0000000..3dc4421
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/test.cc.filepaths.expected
@@ -0,0 +1,3 @@
+./binomial.h
+./test.cc
+./test.h
diff --git a/tools/clang/translation_unit/test_files/test.h b/tools/clang/translation_unit/test_files/test.h
new file mode 100644
index 0000000..8cc20ce
--- /dev/null
+++ b/tools/clang/translation_unit/test_files/test.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_TEST_H_
+#define TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_TEST_H_
+
+#include "binomial.h"
+
+// Number of ways to distribute n items of the same thing to k persons; each
+// person should get at least one item.
+int calculateNumberOfWaysToDistributeNItemsAmongKPersons(int n, int k) {
+  return binomial(n - 1, k - 1);
+}
+
+#endif  // TOOLS_CLANG_TRANSLATION_UNIT_TEST_FILES_TEST_H_
diff --git a/tools/clang/translation_unit/test_translation_unit.py b/tools/clang/translation_unit/test_translation_unit.py
new file mode 100755
index 0000000..eb5cce8
--- /dev/null
+++ b/tools/clang/translation_unit/test_translation_unit.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Test for TranslationUnitGenerator tool."""
+
+import difflib
+import glob
+import json
+import ntpath
+import os
+import os.path
+import subprocess
+import sys
+
+
+def _GenerateCompileCommands(files):
+  """Returns a JSON string containing a compilation database for the input."""
+  return json.dumps([{'directory': '.',
+                      'command': 'clang++ -fsyntax-only -std=c++11 -c %s' % f,
+                      'file': f} for f in files], indent=2)
+
+
+def _NumberOfTestsToString(tests):
+  """Returns an English sentence describing the number of tests."""
+  return "%d test%s" % (tests, 's' if tests != 1 else '')
+
+
+# Before running this test script, please build the translation_unit clang tool
+# first. This is explained here:
+# https://code.google.com/p/chromium/wiki/ClangToolRefactoring
+def main():
+  tools_clang_directory = os.path.dirname(os.path.dirname(
+      os.path.realpath(__file__)))
+  tools_clang_scripts_directory = os.path.join(tools_clang_directory, 'scripts')
+  test_directory_for_tool = os.path.join(
+      tools_clang_directory, 'translation_unit', 'test_files')
+  compile_database = os.path.join(test_directory_for_tool,
+                                  'compile_commands.json')
+  source_files = glob.glob(os.path.join(test_directory_for_tool, '*.cc'))
+
+  # Generate a temporary compilation database to run the tool over.
+  with open(compile_database, 'w') as f:
+    f.write(_GenerateCompileCommands(source_files))
+
+  args = ['python',
+          os.path.join(tools_clang_scripts_directory, 'run_tool.py'),
+          'translation_unit',
+          test_directory_for_tool]
+  args.extend(source_files)
+  run_tool = subprocess.Popen(args, stdout=subprocess.PIPE)
+  stdout, _ = run_tool.communicate()
+  if run_tool.returncode != 0:
+    print 'run_tool failed:\n%s' % stdout
+    sys.exit(1)
+
+  passed = 0
+  failed = 0
+  for actual in source_files:
+    actual += '.filepaths'
+    expected = actual + '.expected'
+    print '[ RUN      ] %s' % os.path.relpath(actual)
+    expected_output = actual_output = None
+    with open(expected, 'r') as f:
+      expected_output = f.readlines()
+    with open(actual, 'r') as f:
+      actual_output = f.readlines()
+    has_same_filepaths = True
+    for expected_line, actual_line in zip(expected_output, actual_output):
+      if ntpath.basename(expected_line) != ntpath.basename(actual_line):
+        sys.stdout.write(ntpath.basename(expected_line))
+        sys.stdout.write(ntpath.basename(actual_line))
+        has_same_filepaths = False
+        break
+    if not has_same_filepaths:
+      failed += 1
+      for line in difflib.unified_diff(expected_output, actual_output,
+                                       fromfile=os.path.relpath(expected),
+                                       tofile=os.path.relpath(actual)):
+        sys.stdout.write(line)
+      print '[  FAILED  ] %s' % os.path.relpath(actual)
+      # Don't clean up the file on failure, so the results can be referenced
+      # more easily.
+      continue
+    print '[       OK ] %s' % os.path.relpath(actual)
+    passed += 1
+    os.remove(actual)
+
+  if failed == 0:
+    os.remove(compile_database)
+
+  print '[==========] %s ran.' % _NumberOfTestsToString(len(source_files))
+  if passed > 0:
+    print '[  PASSED  ] %s.' % _NumberOfTestsToString(passed)
+  if failed > 0:
+    print '[  FAILED  ] %s.' % _NumberOfTestsToString(failed)
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index 8f5432f..677cb63 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -470,6 +470,9 @@
   def TestUIBaseUnit(self):
     return self.SimpleTest("chrome", "ui_base_unittests")
 
+  def TestUIChromeOS(self):
+    return self.SimpleTest("chrome", "ui_chromeos_unittests")
+
   def TestURL(self):
     return self.SimpleTest("chrome", "url_unittests")
 
@@ -712,6 +715,7 @@
     "sync_integration_tests": TestSyncIntegration,
     "sync_integration": TestSyncIntegration,
     "ui_base_unit": TestUIBaseUnit,       "ui_base_unittests": TestUIBaseUnit,
+    "ui_chromeos": TestUIChromeOS, "ui_chromeos_unittests": TestUIChromeOS,
     "unit": TestUnit,            "unit_tests": TestUnit,
     "url": TestURL,              "url_unittests": TestURL,
     "views": TestViews,          "views_unittests": TestViews,
diff --git a/tools/valgrind/gtest_exclude/base_unittests.gtest.txt b/tools/valgrind/gtest_exclude/base_unittests.gtest.txt
index aa85c27..74a4ac5 100644
--- a/tools/valgrind/gtest_exclude/base_unittests.gtest.txt
+++ b/tools/valgrind/gtest_exclude/base_unittests.gtest.txt
@@ -27,3 +27,6 @@
 
 # Crashes under Valgrind, see http://crbug.com/355436
 OutOfMemoryHandledTest.Unchecked*
+
+# Fail under Valgrind, see http://crbug.com/431702
+ProcMapsTest.ReadProcMaps
diff --git a/tools/valgrind/gtest_exclude/components_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/components_unittests.gtest-drmemory_win32.txt
new file mode 100644
index 0000000..a8edd28
--- /dev/null
+++ b/tools/valgrind/gtest_exclude/components_unittests.gtest-drmemory_win32.txt
@@ -0,0 +1,3 @@
+# http://crbug.com/435320
+MetricsServiceTest.InitialStabilityLogAfterCrash
+MetricsServiceTest.InitialStabilityLogAtProviderRequest
diff --git a/tools/valgrind/gtest_exclude/content_unittests.gtest.txt b/tools/valgrind/gtest_exclude/content_unittests.gtest.txt
index 3376b22..03eb062 100644
--- a/tools/valgrind/gtest_exclude/content_unittests.gtest.txt
+++ b/tools/valgrind/gtest_exclude/content_unittests.gtest.txt
@@ -10,3 +10,6 @@
 
 # http://crbug.com/430391
 WebDataConsumerHandleImplTest.*
+
+# http://crbug.com/435441
+PluginLoaderPosixTest.*