Creating branches/google/stable and tags/google/stable/2019-05-14 from r360103

git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/branches/google/stable@360714 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37e3e87..d32b4b9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,20 +1,15 @@
-option(CLANGD_BUILD_XPC "Build XPC Support For Clangd." OFF)
-if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-  set(CLANGD_BUILD_XPC ON CACHE BOOL "" FORCE)
-endif ()
-
 add_subdirectory(clang-apply-replacements)
 add_subdirectory(clang-reorder-fields)
 add_subdirectory(modularize)
 add_subdirectory(clang-tidy)
 add_subdirectory(clang-tidy-vs)
 
-add_subdirectory(change-namespace)
+add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)
-add_subdirectory(clang-query)
+add_subdirectory(clang-include-fixer)
 add_subdirectory(clang-move)
+add_subdirectory(clang-query)
 add_subdirectory(clangd)
-add_subdirectory(include-fixer)
 add_subdirectory(pp-trace)
 add_subdirectory(tool-template)
 
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 44864d4..24806ab 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,5 +1,240 @@
 ==============================================================================
-LLVM Release License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+   `LICENSE` file at the top containing the specific license and restrictions
+   which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+   file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
 ==============================================================================
 University of Illinois/NCSA
 Open Source License
@@ -41,23 +276,3 @@
 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 WITH THE
 SOFTWARE.
-
-==============================================================================
-The LLVM software contains code written by third parties.  Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the LLVM Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program             Directory
--------             ---------
-clang-tidy          clang-tidy/cert
-clang-tidy          clang-tidy/hicpp
diff --git a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
index da9ae0c..34f5c75 100644
--- a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
+++ b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h
@@ -1,9 +1,8 @@
 //===-- ApplyReplacements.h - Deduplicate and apply replacements -- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
index b479922..4a6707b 100644
--- a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
+++ b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
@@ -1,9 +1,8 @@
 //===-- ApplyReplacements.cpp - Apply and deduplicate replacements --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -20,6 +19,7 @@
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Core/Diagnostic.h"
 #include "clang/Tooling/DiagnosticsYaml.h"
 #include "clang/Tooling/ReplacementsYaml.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -170,9 +170,11 @@
 
   for (const auto &TU : TUDs)
     for (const auto &D : TU.Diagnostics)
-      for (const auto &Fix : D.Fix)
-        for (const tooling::Replacement &R : Fix.second)
-          AddToGroup(R, true);
+      if (const auto *ChoosenFix = tooling::selectFirstFix(D)) {
+        for (const auto &Fix : *ChoosenFix)
+          for (const tooling::Replacement &R : Fix.second)
+            AddToGroup(R, true);
+      }
 
   // Sort replacements per file to keep consistent behavior when
   // clang-apply-replacements run on differents machine.
diff --git a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
index 8977b13..ffd1e65 100644
--- a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
+++ b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp
@@ -1,9 +1,8 @@
 //===-- ClangApplyReplacementsMain.cpp - Main file for the tool -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/change-namespace/CMakeLists.txt b/clang-change-namespace/CMakeLists.txt
similarity index 100%
rename from change-namespace/CMakeLists.txt
rename to clang-change-namespace/CMakeLists.txt
diff --git a/change-namespace/ChangeNamespace.cpp b/clang-change-namespace/ChangeNamespace.cpp
similarity index 99%
rename from change-namespace/ChangeNamespace.cpp
rename to clang-change-namespace/ChangeNamespace.cpp
index 7a71031..eb73263 100644
--- a/change-namespace/ChangeNamespace.cpp
+++ b/clang-change-namespace/ChangeNamespace.cpp
@@ -1,9 +1,8 @@
 //===-- ChangeNamespace.cpp - Change namespace implementation -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "ChangeNamespace.h"
diff --git a/change-namespace/ChangeNamespace.h b/clang-change-namespace/ChangeNamespace.h
similarity index 97%
rename from change-namespace/ChangeNamespace.h
rename to clang-change-namespace/ChangeNamespace.h
index cfe3cbc..293d5ce 100644
--- a/change-namespace/ChangeNamespace.h
+++ b/clang-change-namespace/ChangeNamespace.h
@@ -1,9 +1,8 @@
 //===-- ChangeNamespace.h -- Change namespace  ------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/change-namespace/tool/CMakeLists.txt b/clang-change-namespace/tool/CMakeLists.txt
similarity index 100%
rename from change-namespace/tool/CMakeLists.txt
rename to clang-change-namespace/tool/CMakeLists.txt
diff --git a/change-namespace/tool/ClangChangeNamespace.cpp b/clang-change-namespace/tool/ClangChangeNamespace.cpp
similarity index 95%
rename from change-namespace/tool/ClangChangeNamespace.cpp
rename to clang-change-namespace/tool/ClangChangeNamespace.cpp
index 180e8c3..d5f0655 100644
--- a/change-namespace/tool/ClangChangeNamespace.cpp
+++ b/clang-change-namespace/tool/ClangChangeNamespace.cpp
@@ -1,9 +1,8 @@
-//===-- ClangIncludeFixer.cpp - Standalone change namespace ---------------===//
+//===-- ClangChangeNamespace.cpp - Standalone change namespace ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // This tool can be used to change the surrounding namespaces of class/function
diff --git a/clang-doc/BitcodeReader.cpp b/clang-doc/BitcodeReader.cpp
index 20cdc50..04e5d7d 100644
--- a/clang-doc/BitcodeReader.cpp
+++ b/clang-doc/BitcodeReader.cpp
@@ -1,9 +1,8 @@
 //===--  BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/BitcodeReader.h b/clang-doc/BitcodeReader.h
index ec3f6b0..2642a2c 100644
--- a/clang-doc/BitcodeReader.h
+++ b/clang-doc/BitcodeReader.h
@@ -1,9 +1,8 @@
 //===--  BitcodeReader.h - ClangDoc Bitcode Reader --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/BitcodeWriter.cpp b/clang-doc/BitcodeWriter.cpp
index bc990fa..232c3f1 100644
--- a/clang-doc/BitcodeWriter.cpp
+++ b/clang-doc/BitcodeWriter.cpp
@@ -1,9 +1,8 @@
 //===--  BitcodeWriter.cpp - ClangDoc Bitcode Writer ------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/BitcodeWriter.h b/clang-doc/BitcodeWriter.h
index 12a31ea..9deba83 100644
--- a/clang-doc/BitcodeWriter.h
+++ b/clang-doc/BitcodeWriter.h
@@ -1,9 +1,8 @@
 //===--  BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/ClangDoc.cpp b/clang-doc/ClangDoc.cpp
index a11c584..ec32f01 100644
--- a/clang-doc/ClangDoc.cpp
+++ b/clang-doc/ClangDoc.cpp
@@ -1,9 +1,8 @@
 //===-- ClangDoc.cpp - ClangDoc ---------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/ClangDoc.h b/clang-doc/ClangDoc.h
index 59e9a92..f3820d2 100644
--- a/clang-doc/ClangDoc.h
+++ b/clang-doc/ClangDoc.h
@@ -1,9 +1,8 @@
 //===-- ClangDoc.h - ClangDoc -----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/Generators.cpp b/clang-doc/Generators.cpp
index 5a0d0c5..e3b672a 100644
--- a/clang-doc/Generators.cpp
+++ b/clang-doc/Generators.cpp
@@ -1,9 +1,8 @@
-//===---- Generator.cpp - Generator Registry ---------------------*- C++-*-===//
+//===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/Generators.h b/clang-doc/Generators.h
index 90a81e8..25e5e0b 100644
--- a/clang-doc/Generators.h
+++ b/clang-doc/Generators.h
@@ -1,9 +1,8 @@
 //===-- Generators.h - ClangDoc Generator ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // Generator classes for converting declaration information into documentation
diff --git a/clang-doc/MDGenerator.cpp b/clang-doc/MDGenerator.cpp
index 5deb510..d778420 100644
--- a/clang-doc/MDGenerator.cpp
+++ b/clang-doc/MDGenerator.cpp
@@ -1,9 +1,8 @@
 //===-- MDGenerator.cpp - Markdown Generator --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/Mapper.cpp b/clang-doc/Mapper.cpp
index 0b00bd1..654096d 100644
--- a/clang-doc/Mapper.cpp
+++ b/clang-doc/Mapper.cpp
@@ -1,9 +1,8 @@
 //===-- Mapper.cpp - ClangDoc Mapper ----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/Mapper.h b/clang-doc/Mapper.h
index a0b1ac2..fe2a8e2 100644
--- a/clang-doc/Mapper.h
+++ b/clang-doc/Mapper.h
@@ -1,9 +1,8 @@
 //===-- Mapper.h - ClangDoc Mapper ------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/Representation.cpp b/clang-doc/Representation.cpp
index eacf11a..398d102 100644
--- a/clang-doc/Representation.cpp
+++ b/clang-doc/Representation.cpp
@@ -1,9 +1,8 @@
 ///===-- Representation.cpp - ClangDoc Representation -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/Representation.h b/clang-doc/Representation.h
index 48f8f3d..ad12ec4 100644
--- a/clang-doc/Representation.h
+++ b/clang-doc/Representation.h
@@ -1,9 +1,8 @@
 ///===-- Representation.h - ClangDoc Representation -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/Serialize.cpp b/clang-doc/Serialize.cpp
index eb72c19..2bd54cf 100644
--- a/clang-doc/Serialize.cpp
+++ b/clang-doc/Serialize.cpp
@@ -1,9 +1,8 @@
-//===-- Serializer.cpp - ClangDoc Serializer --------------------*- C++ -*-===//
+//===-- Serialize.cpp - ClangDoc Serializer ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-doc/Serialize.h b/clang-doc/Serialize.h
index d89dac8..3a2c93d 100644
--- a/clang-doc/Serialize.h
+++ b/clang-doc/Serialize.h
@@ -1,9 +1,8 @@
 //===-- Serializer.h - ClangDoc Serializer ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-doc/YAMLGenerator.cpp b/clang-doc/YAMLGenerator.cpp
index e093901..94fb9f9 100644
--- a/clang-doc/YAMLGenerator.cpp
+++ b/clang-doc/YAMLGenerator.cpp
@@ -1,9 +1,8 @@
-//===--  ClangDocYAML.cpp - ClangDoc YAML -----------------------*- C++ -*-===//
+//===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // Implementation of the YAML generator, converting decl info into YAML output.
diff --git a/clang-doc/tool/CMakeLists.txt b/clang-doc/tool/CMakeLists.txt
index d7f28cf..35f99ea 100644
--- a/clang-doc/tool/CMakeLists.txt
+++ b/clang-doc/tool/CMakeLists.txt
@@ -1,6 +1,6 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
 
-add_clang_executable(clang-doc
+add_clang_tool(clang-doc
   ClangDocMain.cpp
   )
 
diff --git a/clang-doc/tool/ClangDocMain.cpp b/clang-doc/tool/ClangDocMain.cpp
index 71ca2d9..2b44869 100644
--- a/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-doc/tool/ClangDocMain.cpp
@@ -1,9 +1,8 @@
 //===-- ClangDocMain.cpp - ClangDoc -----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include-fixer/CMakeLists.txt b/clang-include-fixer/CMakeLists.txt
similarity index 100%
rename from include-fixer/CMakeLists.txt
rename to clang-include-fixer/CMakeLists.txt
diff --git a/include-fixer/FuzzySymbolIndex.cpp b/clang-include-fixer/FuzzySymbolIndex.cpp
similarity index 94%
rename from include-fixer/FuzzySymbolIndex.cpp
rename to clang-include-fixer/FuzzySymbolIndex.cpp
index d91f455..099d738 100644
--- a/include-fixer/FuzzySymbolIndex.cpp
+++ b/clang-include-fixer/FuzzySymbolIndex.cpp
@@ -1,9 +1,8 @@
 //===--- FuzzySymbolIndex.cpp - Lookup symbols for autocomplete -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "FuzzySymbolIndex.h"
diff --git a/include-fixer/FuzzySymbolIndex.h b/clang-include-fixer/FuzzySymbolIndex.h
similarity index 86%
rename from include-fixer/FuzzySymbolIndex.h
rename to clang-include-fixer/FuzzySymbolIndex.h
index 245191e..27bfadf 100644
--- a/include-fixer/FuzzySymbolIndex.h
+++ b/clang-include-fixer/FuzzySymbolIndex.h
@@ -1,9 +1,8 @@
 //===--- FuzzySymbolIndex.h - Lookup symbols for autocomplete ---*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -32,7 +31,7 @@
 // Implementations may choose to truncate results, refuse short queries, etc.
 class FuzzySymbolIndex : public SymbolIndex {
 public:
-  // Loads the specified include-fixer database and returns an index serving it.
+  // Loads the specified clang-include-fixer database and returns an index serving it.
   static llvm::Expected<std::unique_ptr<FuzzySymbolIndex>>
   createFromYAML(llvm::StringRef File);
 
diff --git a/include-fixer/InMemorySymbolIndex.cpp b/clang-include-fixer/InMemorySymbolIndex.cpp
similarity index 78%
rename from include-fixer/InMemorySymbolIndex.cpp
rename to clang-include-fixer/InMemorySymbolIndex.cpp
index 14753bd..e785893 100644
--- a/include-fixer/InMemorySymbolIndex.cpp
+++ b/clang-include-fixer/InMemorySymbolIndex.cpp
@@ -1,9 +1,8 @@
 //===-- InMemorySymbolIndex.cpp--------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/InMemorySymbolIndex.h b/clang-include-fixer/InMemorySymbolIndex.h
similarity index 82%
rename from include-fixer/InMemorySymbolIndex.h
rename to clang-include-fixer/InMemorySymbolIndex.h
index 0e1310e..bea8be9 100644
--- a/include-fixer/InMemorySymbolIndex.h
+++ b/clang-include-fixer/InMemorySymbolIndex.h
@@ -1,9 +1,8 @@
 //===-- InMemorySymbolIndex.h -----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/include-fixer/IncludeFixer.cpp b/clang-include-fixer/IncludeFixer.cpp
similarity index 97%
rename from include-fixer/IncludeFixer.cpp
rename to clang-include-fixer/IncludeFixer.cpp
index c6dfd7f..d364021 100644
--- a/include-fixer/IncludeFixer.cpp
+++ b/clang-include-fixer/IncludeFixer.cpp
@@ -1,9 +1,8 @@
 //===-- IncludeFixer.cpp - Include inserter based on sema callbacks -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,7 +16,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
-#define DEBUG_TYPE "include-fixer"
+#define DEBUG_TYPE "clang-include-fixer"
 
 using namespace clang;
 
@@ -349,8 +348,8 @@
   //
   // We use conservative behavior for detecting the same unidentified symbol
   // here. The symbols which have the same ScopedQualifier and RawIdentifier
-  // are considered equal. So that include-fixer avoids false positives, and
-  // always adds missing qualifiers to correct symbols.
+  // are considered equal. So that clang-include-fixer avoids false positives,
+  // and always adds missing qualifiers to correct symbols.
   if (!GenerateDiagnostics && !QuerySymbolInfos.empty()) {
     if (ScopedQualifiers == QuerySymbolInfos.front().ScopedQualifiers &&
         Query == QuerySymbolInfos.front().RawIdentifier) {
diff --git a/include-fixer/IncludeFixer.h b/clang-include-fixer/IncludeFixer.h
similarity index 95%
rename from include-fixer/IncludeFixer.h
rename to clang-include-fixer/IncludeFixer.h
index 13092a3..ccab65d 100644
--- a/include-fixer/IncludeFixer.h
+++ b/clang-include-fixer/IncludeFixer.h
@@ -1,9 +1,8 @@
 //===-- IncludeFixer.h - Include inserter -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -68,7 +67,7 @@
 ///
 /// \param Code The source code.
 /// \param Context The context which contains all information for creating
-/// include-fixer replacements.
+/// clang-include-fixer replacements.
 /// \param Style clang-format style being used.
 /// \param AddQualifiers  Whether we should add qualifiers to all instances of
 /// an unidentified symbol.
diff --git a/include-fixer/IncludeFixerContext.cpp b/clang-include-fixer/IncludeFixerContext.cpp
similarity index 95%
rename from include-fixer/IncludeFixerContext.cpp
rename to clang-include-fixer/IncludeFixerContext.cpp
index 8106e20..a9fef45 100644
--- a/include-fixer/IncludeFixerContext.cpp
+++ b/clang-include-fixer/IncludeFixerContext.cpp
@@ -1,9 +1,8 @@
 //===-- IncludeFixerContext.cpp - Include fixer context ---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/IncludeFixerContext.h b/clang-include-fixer/IncludeFixerContext.h
similarity index 93%
rename from include-fixer/IncludeFixerContext.h
rename to clang-include-fixer/IncludeFixerContext.h
index 3c44574..bbb87e2 100644
--- a/include-fixer/IncludeFixerContext.h
+++ b/clang-include-fixer/IncludeFixerContext.h
@@ -1,9 +1,8 @@
 //===-- IncludeFixerContext.h - Include fixer context -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/SymbolIndex.h b/clang-include-fixer/SymbolIndex.h
similarity index 84%
rename from include-fixer/SymbolIndex.h
rename to clang-include-fixer/SymbolIndex.h
index f3e6ecd..ca04d50 100644
--- a/include-fixer/SymbolIndex.h
+++ b/clang-include-fixer/SymbolIndex.h
@@ -1,9 +1,8 @@
 //===-- SymbolIndex.h - Interface for symbol-header matching ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/SymbolIndexManager.cpp b/clang-include-fixer/SymbolIndexManager.cpp
similarity index 95%
rename from include-fixer/SymbolIndexManager.cpp
rename to clang-include-fixer/SymbolIndexManager.cpp
index e4312bf..7b82753 100644
--- a/include-fixer/SymbolIndexManager.cpp
+++ b/clang-include-fixer/SymbolIndexManager.cpp
@@ -1,9 +1,8 @@
 //===-- SymbolIndexManager.cpp - Managing multiple SymbolIndices-*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,7 +13,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Path.h"
 
-#define DEBUG_TYPE "include-fixer"
+#define DEBUG_TYPE "clang-include-fixer"
 
 namespace clang {
 namespace include_fixer {
diff --git a/include-fixer/SymbolIndexManager.h b/clang-include-fixer/SymbolIndexManager.h
similarity index 90%
rename from include-fixer/SymbolIndexManager.h
rename to clang-include-fixer/SymbolIndexManager.h
index 12963dd..ca2d739 100644
--- a/include-fixer/SymbolIndexManager.h
+++ b/clang-include-fixer/SymbolIndexManager.h
@@ -1,9 +1,8 @@
 //===-- SymbolIndexManager.h - Managing multiple SymbolIndices --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/YamlSymbolIndex.cpp b/clang-include-fixer/YamlSymbolIndex.cpp
similarity index 90%
rename from include-fixer/YamlSymbolIndex.cpp
rename to clang-include-fixer/YamlSymbolIndex.cpp
index f3f2d5a..de72e9a 100644
--- a/include-fixer/YamlSymbolIndex.cpp
+++ b/clang-include-fixer/YamlSymbolIndex.cpp
@@ -1,9 +1,8 @@
 //===-- YamlSymbolIndex.cpp -----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/YamlSymbolIndex.h b/clang-include-fixer/YamlSymbolIndex.h
similarity index 86%
rename from include-fixer/YamlSymbolIndex.h
rename to clang-include-fixer/YamlSymbolIndex.h
index d5d699a..3c4f514 100644
--- a/include-fixer/YamlSymbolIndex.h
+++ b/clang-include-fixer/YamlSymbolIndex.h
@@ -1,9 +1,8 @@
 //===-- YamlSymbolIndex.h ---------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/CMakeLists.txt b/clang-include-fixer/find-all-symbols/CMakeLists.txt
similarity index 100%
rename from include-fixer/find-all-symbols/CMakeLists.txt
rename to clang-include-fixer/find-all-symbols/CMakeLists.txt
diff --git a/include-fixer/find-all-symbols/FindAllMacros.cpp b/clang-include-fixer/find-all-symbols/FindAllMacros.cpp
similarity index 91%
rename from include-fixer/find-all-symbols/FindAllMacros.cpp
rename to clang-include-fixer/find-all-symbols/FindAllMacros.cpp
index 3dc2b96..ed1bc2f 100644
--- a/include-fixer/find-all-symbols/FindAllMacros.cpp
+++ b/clang-include-fixer/find-all-symbols/FindAllMacros.cpp
@@ -1,9 +1,8 @@
 //===-- FindAllMacros.cpp - find all macros ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/FindAllMacros.h b/clang-include-fixer/find-all-symbols/FindAllMacros.h
similarity index 90%
rename from include-fixer/find-all-symbols/FindAllMacros.h
rename to clang-include-fixer/find-all-symbols/FindAllMacros.h
index 10b4a69..5aaf388 100644
--- a/include-fixer/find-all-symbols/FindAllMacros.h
+++ b/clang-include-fixer/find-all-symbols/FindAllMacros.h
@@ -1,10 +1,9 @@
 //===-- FindAllMacros.h - find all macros -----------------------*- C++ -*-===//
 //
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
similarity index 97%
rename from include-fixer/find-all-symbols/FindAllSymbols.cpp
rename to clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bd5032d..bb6a3fa 100644
--- a/include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -1,9 +1,8 @@
 //===-- FindAllSymbols.cpp - find all symbols--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/FindAllSymbols.h b/clang-include-fixer/find-all-symbols/FindAllSymbols.h
similarity index 90%
rename from include-fixer/find-all-symbols/FindAllSymbols.h
rename to clang-include-fixer/find-all-symbols/FindAllSymbols.h
index fca849f..d78da66 100644
--- a/include-fixer/find-all-symbols/FindAllSymbols.h
+++ b/clang-include-fixer/find-all-symbols/FindAllSymbols.h
@@ -1,9 +1,8 @@
 //===-- FindAllSymbols.h - find all symbols----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp b/clang-include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
similarity index 84%
rename from include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
rename to clang-include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
index bc00547..9f1d31d 100644
--- a/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
+++ b/clang-include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
@@ -1,9 +1,8 @@
 //===-- FindAllSymbolsAction.cpp - find all symbols action --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/FindAllSymbolsAction.h b/clang-include-fixer/find-all-symbols/FindAllSymbolsAction.h
similarity index 90%
rename from include-fixer/find-all-symbols/FindAllSymbolsAction.h
rename to clang-include-fixer/find-all-symbols/FindAllSymbolsAction.h
index 7be9fe2..ccffa4b 100644
--- a/include-fixer/find-all-symbols/FindAllSymbolsAction.h
+++ b/clang-include-fixer/find-all-symbols/FindAllSymbolsAction.h
@@ -1,9 +1,8 @@
 //===-- FindAllSymbolsAction.h - find all symbols action --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/HeaderMapCollector.cpp b/clang-include-fixer/find-all-symbols/HeaderMapCollector.cpp
similarity index 86%
rename from include-fixer/find-all-symbols/HeaderMapCollector.cpp
rename to clang-include-fixer/find-all-symbols/HeaderMapCollector.cpp
index 379df81..6ec49ca 100644
--- a/include-fixer/find-all-symbols/HeaderMapCollector.cpp
+++ b/clang-include-fixer/find-all-symbols/HeaderMapCollector.cpp
@@ -1,9 +1,8 @@
 //===-- HeaderMapCoolector.h - find all symbols------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/HeaderMapCollector.h b/clang-include-fixer/find-all-symbols/HeaderMapCollector.h
similarity index 90%
rename from include-fixer/find-all-symbols/HeaderMapCollector.h
rename to clang-include-fixer/find-all-symbols/HeaderMapCollector.h
index 65edd75..2135827 100644
--- a/include-fixer/find-all-symbols/HeaderMapCollector.h
+++ b/clang-include-fixer/find-all-symbols/HeaderMapCollector.h
@@ -1,9 +1,8 @@
 //===-- HeaderMapCoolector.h - find all symbols------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/PathConfig.cpp b/clang-include-fixer/find-all-symbols/PathConfig.cpp
similarity index 83%
rename from include-fixer/find-all-symbols/PathConfig.cpp
rename to clang-include-fixer/find-all-symbols/PathConfig.cpp
index de799b9..4f1ebc7 100644
--- a/include-fixer/find-all-symbols/PathConfig.cpp
+++ b/clang-include-fixer/find-all-symbols/PathConfig.cpp
@@ -1,10 +1,9 @@
 //===-- PathConfig.cpp - Process paths of symbols ---------------*- C++ -*-===//
 //
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/PathConfig.h b/clang-include-fixer/find-all-symbols/PathConfig.h
similarity index 85%
rename from include-fixer/find-all-symbols/PathConfig.h
rename to clang-include-fixer/find-all-symbols/PathConfig.h
index 50de548..9c430f2 100644
--- a/include-fixer/find-all-symbols/PathConfig.h
+++ b/clang-include-fixer/find-all-symbols/PathConfig.h
@@ -1,10 +1,9 @@
 //===-- PathConfig.h - Process paths of symbols -----------------*- C++ -*-===//
 //
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/PragmaCommentHandler.cpp b/clang-include-fixer/find-all-symbols/PragmaCommentHandler.cpp
similarity index 83%
rename from include-fixer/find-all-symbols/PragmaCommentHandler.cpp
rename to clang-include-fixer/find-all-symbols/PragmaCommentHandler.cpp
index 0242d38..4948975 100644
--- a/include-fixer/find-all-symbols/PragmaCommentHandler.cpp
+++ b/clang-include-fixer/find-all-symbols/PragmaCommentHandler.cpp
@@ -1,9 +1,8 @@
 //===-- PragmaCommentHandler.cpp - find all symbols -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/PragmaCommentHandler.h b/clang-include-fixer/find-all-symbols/PragmaCommentHandler.h
similarity index 85%
rename from include-fixer/find-all-symbols/PragmaCommentHandler.h
rename to clang-include-fixer/find-all-symbols/PragmaCommentHandler.h
index 9eb4972..752c82f 100644
--- a/include-fixer/find-all-symbols/PragmaCommentHandler.h
+++ b/clang-include-fixer/find-all-symbols/PragmaCommentHandler.h
@@ -1,9 +1,8 @@
 //===-- PragmaCommentHandler.h - find all symbols----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp b/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
similarity index 98%
rename from include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
rename to clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
index 4a49479..0d0bbd9 100644
--- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
+++ b/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
@@ -1,9 +1,8 @@
 //===-- STLPostfixHeaderMap.h - hardcoded STL header map --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/STLPostfixHeaderMap.h b/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.h
similarity index 75%
rename from include-fixer/find-all-symbols/STLPostfixHeaderMap.h
rename to clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.h
index 162580d..49bc5f3 100644
--- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.h
+++ b/clang-include-fixer/find-all-symbols/STLPostfixHeaderMap.h
@@ -1,9 +1,8 @@
 //===-- STLPostfixHeaderMap.h - hardcoded header map for STL ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/SymbolInfo.cpp b/clang-include-fixer/find-all-symbols/SymbolInfo.cpp
similarity index 95%
rename from include-fixer/find-all-symbols/SymbolInfo.cpp
rename to clang-include-fixer/find-all-symbols/SymbolInfo.cpp
index 00bfbe5..e5b4dba 100644
--- a/include-fixer/find-all-symbols/SymbolInfo.cpp
+++ b/clang-include-fixer/find-all-symbols/SymbolInfo.cpp
@@ -1,9 +1,8 @@
 //===-- SymbolInfo.cpp - Symbol Info ----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/SymbolInfo.h b/clang-include-fixer/find-all-symbols/SymbolInfo.h
similarity index 95%
rename from include-fixer/find-all-symbols/SymbolInfo.h
rename to clang-include-fixer/find-all-symbols/SymbolInfo.h
index 92d360d..6def1c7 100644
--- a/include-fixer/find-all-symbols/SymbolInfo.h
+++ b/clang-include-fixer/find-all-symbols/SymbolInfo.h
@@ -1,9 +1,8 @@
 //===-- SymbolInfo.h - Symbol Info ------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/SymbolReporter.h b/clang-include-fixer/find-all-symbols/SymbolReporter.h
similarity index 78%
rename from include-fixer/find-all-symbols/SymbolReporter.h
rename to clang-include-fixer/find-all-symbols/SymbolReporter.h
index 2398234..25e8621 100644
--- a/include-fixer/find-all-symbols/SymbolReporter.h
+++ b/clang-include-fixer/find-all-symbols/SymbolReporter.h
@@ -1,9 +1,8 @@
 //===--- SymbolReporter.h - Symbol Reporter ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/tool/CMakeLists.txt b/clang-include-fixer/find-all-symbols/tool/CMakeLists.txt
similarity index 100%
rename from include-fixer/find-all-symbols/tool/CMakeLists.txt
rename to clang-include-fixer/find-all-symbols/tool/CMakeLists.txt
diff --git a/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp b/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
similarity index 95%
rename from include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
rename to clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
index e09a5aa..dbbe073 100644
--- a/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
+++ b/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
@@ -1,9 +1,8 @@
 //===-- FindAllSymbolsMain.cpp - find all symbols tool ----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/find-all-symbols/tool/run-find-all-symbols.py b/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py
similarity index 94%
rename from include-fixer/find-all-symbols/tool/run-find-all-symbols.py
rename to clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py
index 461d959..5e9dde7 100755
--- a/include-fixer/find-all-symbols/tool/run-find-all-symbols.py
+++ b/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py
@@ -2,10 +2,9 @@
 #
 #=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python  -*-=#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 
diff --git a/include-fixer/plugin/CMakeLists.txt b/clang-include-fixer/plugin/CMakeLists.txt
similarity index 100%
rename from include-fixer/plugin/CMakeLists.txt
rename to clang-include-fixer/plugin/CMakeLists.txt
diff --git a/include-fixer/plugin/IncludeFixerPlugin.cpp b/clang-include-fixer/plugin/IncludeFixerPlugin.cpp
similarity index 94%
rename from include-fixer/plugin/IncludeFixerPlugin.cpp
rename to clang-include-fixer/plugin/IncludeFixerPlugin.cpp
index 0d6bdb7..bc9c497 100644
--- a/include-fixer/plugin/IncludeFixerPlugin.cpp
+++ b/clang-include-fixer/plugin/IncludeFixerPlugin.cpp
@@ -1,9 +1,8 @@
 //===- IncludeFixerPlugin.cpp - clang-include-fixer as a clang plugin -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/tool/CMakeLists.txt b/clang-include-fixer/tool/CMakeLists.txt
similarity index 100%
rename from include-fixer/tool/CMakeLists.txt
rename to clang-include-fixer/tool/CMakeLists.txt
diff --git a/include-fixer/tool/ClangIncludeFixer.cpp b/clang-include-fixer/tool/ClangIncludeFixer.cpp
similarity index 96%
rename from include-fixer/tool/ClangIncludeFixer.cpp
rename to clang-include-fixer/tool/ClangIncludeFixer.cpp
index d9d97d2..15f6ed2 100644
--- a/include-fixer/tool/ClangIncludeFixer.cpp
+++ b/clang-include-fixer/tool/ClangIncludeFixer.cpp
@@ -1,9 +1,8 @@
 //===-- ClangIncludeFixer.cpp - Standalone include fixer ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -367,8 +366,8 @@
     }
 
     // We leave an empty symbol range as we don't know the range of the symbol
-    // being queried in this mode. include-fixer won't add namespace qualifiers
-    // if the symbol range is empty, which also fits this case.
+    // being queried in this mode. clang-include-fixer won't add namespace
+    // qualifiers if the symbol range is empty, which also fits this case.
     IncludeFixerContext::QuerySymbolInfo Symbol;
     Symbol.RawIdentifier = QuerySymbol;
     auto Context =
@@ -384,9 +383,10 @@
 
   if (tool.run(&Factory) != 0) {
     // We suppress all Clang diagnostics (because they would be wrong,
-    // include-fixer does custom recovery) but still want to give some feedback
-    // in case there was a compiler error we couldn't recover from. The most
-    // common case for this is a #include in the file that couldn't be found.
+    // clang-include-fixer does custom recovery) but still want to give some
+    // feedback in case there was a compiler error we couldn't recover from.
+    // The most common case for this is a #include in the file that couldn't be
+    // found.
     llvm::errs() << "Fatal compiler error occurred while parsing file!"
                     " (incorrect include paths?)\n";
     return 1;
diff --git a/include-fixer/tool/clang-include-fixer-test.el b/clang-include-fixer/tool/clang-include-fixer-test.el
similarity index 100%
rename from include-fixer/tool/clang-include-fixer-test.el
rename to clang-include-fixer/tool/clang-include-fixer-test.el
diff --git a/include-fixer/tool/clang-include-fixer.el b/clang-include-fixer/tool/clang-include-fixer.el
similarity index 98%
rename from include-fixer/tool/clang-include-fixer.el
rename to clang-include-fixer/tool/clang-include-fixer.el
index 1512402..84fff62 100644
--- a/include-fixer/tool/clang-include-fixer.el
+++ b/clang-include-fixer/tool/clang-include-fixer.el
@@ -8,7 +8,7 @@
 ;; This package allows Emacs users to invoke the 'clang-include-fixer' within
 ;; Emacs.  'clang-include-fixer' provides an automated way of adding #include
 ;; directives for missing symbols in one translation unit, see
-;; <http://clang.llvm.org/extra/include-fixer.html>.
+;; <http://clang.llvm.org/extra/clang-include-fixer.html>.
 
 ;;; Code:
 
@@ -243,7 +243,7 @@
                         t))))))))))))
 
 (defun clang-include-fixer--add-header (stdout)
-  "Analyse the result of include-fixer stored in STDOUT.
+  "Analyse the result of clang-include-fixer stored in STDOUT.
 Add a missing header if there is any.  If there are multiple
 possible headers the user can select one of them to be included.
 Temporarily highlight the affected symbols.  Asynchronously call
@@ -317,7 +317,7 @@
             (when overlays
               (goto-char (clang-include-fixer--closest-overlay overlays)))
             (cl-flet ((header (info) (let-alist info .Header)))
-              ;; The header-infos is already sorted by include-fixer.
+              ;; The header-infos is already sorted by clang-include-fixer.
               (let* ((headers (mapcar #'header .HeaderInfos))
                      (header (completing-read
                               (clang-include-fixer--format-message
diff --git a/include-fixer/tool/clang-include-fixer.py b/clang-include-fixer/tool/clang-include-fixer.py
similarity index 94%
rename from include-fixer/tool/clang-include-fixer.py
rename to clang-include-fixer/tool/clang-include-fixer.py
index 0e9306d..4c38f71 100644
--- a/include-fixer/tool/clang-include-fixer.py
+++ b/clang-include-fixer/tool/clang-include-fixer.py
@@ -2,12 +2,14 @@
 # - Change 'binary' if clang-include-fixer is not on the path (see below).
 # - Add to your .vimrc:
 #
-#   noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/clang-include-fixer.py<cr>
+#   noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/clang-include-fixer/tool/clang-include-fixer.py<cr>
 #
-# This enables clang-include-fixer for NORMAL and VISUAL mode. Change "<leader>cf"
-# to another binding if you need clang-include-fixer on a different key.
+# This enables clang-include-fixer for NORMAL and VISUAL mode. Change
+# "<leader>cf" to another binding if you need clang-include-fixer on a
+# different key.
 #
-# To set up clang-include-fixer, see http://clang.llvm.org/extra/include-fixer.html
+# To set up clang-include-fixer, see
+# http://clang.llvm.org/extra/clang-include-fixer.html
 #
 # With this integration you can press the bound key and clang-include-fixer will
 # be run on the current buffer.
@@ -76,7 +78,7 @@
         raise Exception()
     except Exception:
       # Show a new prompt on invalid option instead of aborting so that users
-      # don't need to wait for another include-fixer run.
+      # don't need to wait for another clang-include-fixer run.
       print >> sys.stderr, "Invalid option:", res
       return GetUserSelection(message, headers, maximum_suggested_headers)
   return headers[idx - 1]
@@ -170,7 +172,7 @@
     print "The file is fine, no need to add a header."
     return
   symbol = query_symbol_infos[0]["RawIdentifier"]
-  # The header_infos is already sorted by include-fixer.
+  # The header_infos is already sorted by clang-include-fixer.
   header_infos = include_fixer_context["HeaderInfos"]
   # Deduplicate headers while keeping the order, so that the same header would
   # not be suggested twice.
diff --git a/clang-move/CMakeLists.txt b/clang-move/CMakeLists.txt
index 37a305d..c63127e 100644
--- a/clang-move/CMakeLists.txt
+++ b/clang-move/CMakeLists.txt
@@ -3,7 +3,7 @@
   )
 
 add_clang_library(clangMove
-  ClangMove.cpp
+  Move.cpp
   HelperDeclRefGraph.cpp
 
   LINK_LIBS
diff --git a/clang-move/HelperDeclRefGraph.cpp b/clang-move/HelperDeclRefGraph.cpp
index 28200e0..b47e7f4 100644
--- a/clang-move/HelperDeclRefGraph.cpp
+++ b/clang-move/HelperDeclRefGraph.cpp
@@ -1,14 +1,13 @@
-//===-- UsedHelperDeclFinder.cpp - AST-based call graph for helper decls --===//
+//===-- HelperDeclRefGraph.cpp - AST-based call graph for helper decls ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "HelperDeclRefGraph.h"
-#include "ClangMove.h"
+#include "Move.h"
 #include "clang/AST/Decl.h"
 #include "llvm/Support/Debug.h"
 #include <vector>
diff --git a/clang-move/HelperDeclRefGraph.h b/clang-move/HelperDeclRefGraph.h
index 11b3c9c..a9cc22d 100644
--- a/clang-move/HelperDeclRefGraph.h
+++ b/clang-move/HelperDeclRefGraph.h
@@ -1,9 +1,8 @@
 //===-- UsedHelperDeclFinder.h - AST-based call graph for helper decls ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-move/ClangMove.cpp b/clang-move/Move.cpp
similarity index 98%
rename from clang-move/ClangMove.cpp
rename to clang-move/Move.cpp
index 3ab3d4e..efb67c6 100644
--- a/clang-move/ClangMove.cpp
+++ b/clang-move/Move.cpp
@@ -1,13 +1,12 @@
-//===-- ClangMove.cpp - Implement ClangMove functationalities ---*- C++ -*-===//
+//===-- Move.cpp - Implement ClangMove functationalities --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "ClangMove.h"
+#include "Move.h"
 #include "HelperDeclRefGraph.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Basic/SourceManager.h"
@@ -88,8 +87,7 @@
 std::string MakeAbsolutePath(const SourceManager &SM, StringRef Path) {
   llvm::SmallString<128> AbsolutePath(Path);
   if (std::error_code EC =
-          SM.getFileManager().getVirtualFileSystem()->makeAbsolute(
-              AbsolutePath))
+          SM.getFileManager().getVirtualFileSystem().makeAbsolute(AbsolutePath))
     llvm::errs() << "Warning: could not make absolute file: '" << EC.message()
                  << '\n';
   // Handle symbolic link path cases.
@@ -766,7 +764,7 @@
     if (Context->Spec.OldDependOnNew &&
         MakeAbsolutePath(SM, FilePath) ==
             makeAbsolutePath(Context->Spec.OldHeader)) {
-      // FIXME: Minimize the include path like include-fixer.
+      // FIXME: Minimize the include path like clang-include-fixer.
       std::string IncludeNewH =
           "#include \"" + Context->Spec.NewHeader + "\"\n";
       // This replacment for inserting header will be cleaned up at the end.
diff --git a/clang-move/ClangMove.h b/clang-move/Move.h
similarity index 97%
rename from clang-move/ClangMove.h
rename to clang-move/Move.h
index 9417218..da4bc44 100644
--- a/clang-move/ClangMove.h
+++ b/clang-move/Move.h
@@ -1,9 +1,8 @@
-//===-- ClangMove.h - Clang move  -----------------------------------------===//
+//===-- Move.h - Clang move  ----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-move/tool/CMakeLists.txt b/clang-move/tool/CMakeLists.txt
index 6202e15..7bc4f30 100644
--- a/clang-move/tool/CMakeLists.txt
+++ b/clang-move/tool/CMakeLists.txt
@@ -1,7 +1,7 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
 
 add_clang_executable(clang-move
-  ClangMoveMain.cpp
+  ClangMove.cpp
   )
 
 target_link_libraries(clang-move
diff --git a/clang-move/tool/ClangMoveMain.cpp b/clang-move/tool/ClangMove.cpp
similarity index 95%
rename from clang-move/tool/ClangMoveMain.cpp
rename to clang-move/tool/ClangMove.cpp
index f50e973..807425b 100644
--- a/clang-move/tool/ClangMoveMain.cpp
+++ b/clang-move/tool/ClangMove.cpp
@@ -1,13 +1,12 @@
-//===-- ClangMoveMain.cpp - move defintion to new file ----------*- C++ -*-===//
+//===-- ClangMove.cpp - move defintion to new file --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "ClangMove.h"
+#include "Move.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
diff --git a/clang-query/Query.cpp b/clang-query/Query.cpp
index ffa3b45..eea0e77 100644
--- a/clang-query/Query.cpp
+++ b/clang-query/Query.cpp
@@ -1,9 +1,8 @@
 //===---- Query.cpp - clang-query query -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-query/Query.h b/clang-query/Query.h
index b4ff1d0..56af486 100644
--- a/clang-query/Query.h
+++ b/clang-query/Query.h
@@ -1,9 +1,8 @@
 //===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-query/QueryParser.cpp b/clang-query/QueryParser.cpp
index 54eb5a0..4da2f5d 100644
--- a/clang-query/QueryParser.cpp
+++ b/clang-query/QueryParser.cpp
@@ -1,9 +1,8 @@
 //===---- QueryParser.cpp - clang-query command parser --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-query/QueryParser.h b/clang-query/QueryParser.h
index 56eb5a9..f5d4393 100644
--- a/clang-query/QueryParser.h
+++ b/clang-query/QueryParser.h
@@ -1,9 +1,8 @@
 //===--- QueryParser.h - clang-query ----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-query/QuerySession.h b/clang-query/QuerySession.h
index 70a4ede..0f3bc1a 100644
--- a/clang-query/QuerySession.h
+++ b/clang-query/QuerySession.h
@@ -1,9 +1,8 @@
 //===--- QuerySession.h - clang-query ---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-query/tool/CMakeLists.txt b/clang-query/tool/CMakeLists.txt
index e5c8a77..d6ac0ae 100644
--- a/clang-query/tool/CMakeLists.txt
+++ b/clang-query/tool/CMakeLists.txt
@@ -1,6 +1,8 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
 
-add_clang_executable(clang-query ClangQuery.cpp)
+add_clang_executable(clang-query
+  ClangQuery.cpp
+  )
 target_link_libraries(clang-query
   PRIVATE
   clangAST
diff --git a/clang-query/tool/ClangQuery.cpp b/clang-query/tool/ClangQuery.cpp
index 59c49ba..80e1c60 100644
--- a/clang-query/tool/ClangQuery.cpp
+++ b/clang-query/tool/ClangQuery.cpp
@@ -1,9 +1,8 @@
 //===---- ClangQuery.cpp - clang-query tool -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-reorder-fields/ReorderFieldsAction.cpp
index 7cb8abe..c11234a 100644
--- a/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -1,9 +1,8 @@
 //===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.cpp -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-reorder-fields/ReorderFieldsAction.h b/clang-reorder-fields/ReorderFieldsAction.h
index f08c632..cc450ed 100644
--- a/clang-reorder-fields/ReorderFieldsAction.h
+++ b/clang-reorder-fields/ReorderFieldsAction.h
@@ -1,9 +1,8 @@
 //===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.h -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-reorder-fields/tool/CMakeLists.txt b/clang-reorder-fields/tool/CMakeLists.txt
index 97b41db..718ee96 100644
--- a/clang-reorder-fields/tool/CMakeLists.txt
+++ b/clang-reorder-fields/tool/CMakeLists.txt
@@ -1,4 +1,6 @@
-add_clang_tool(clang-reorder-fields ClangReorderFields.cpp)
+add_clang_tool(clang-reorder-fields
+  ClangReorderFields.cpp
+  )
 
 target_link_libraries(clang-reorder-fields
   PRIVATE
diff --git a/clang-reorder-fields/tool/ClangReorderFields.cpp b/clang-reorder-fields/tool/ClangReorderFields.cpp
index 077e55e..bae3f4c 100644
--- a/clang-reorder-fields/tool/ClangReorderFields.cpp
+++ b/clang-reorder-fields/tool/ClangReorderFields.cpp
@@ -1,9 +1,8 @@
 //===-- tools/extra/clang-reorder-fields/tool/ClangReorderFields.cpp -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
index 9a0c9b6..fb8a151 100644
--- a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
+++ b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
@@ -1,56 +1,55 @@
-//===-- ClangTidyPackages.cs - VSPackage for clang-tidy ----------*- C# -*-===//

-//

-//                     The LLVM Compiler Infrastructure

-//

-// This file is distributed under the University of Illinois Open Source

-// License. See LICENSE.TXT for details.

-//

-//===----------------------------------------------------------------------===//

-//

-// This class contains a VS extension package that runs clang-tidy over a

-// file in a VS text editor.

-//

-//===----------------------------------------------------------------------===//

-

-using Microsoft.VisualStudio.Editor;

-using Microsoft.VisualStudio.Shell;

-using Microsoft.VisualStudio.Shell.Interop;

-using Microsoft.VisualStudio.TextManager.Interop;

-using System;

-using System.Collections;

-using System.ComponentModel;

-using System.ComponentModel.Design;

-using System.IO;

-using System.Runtime.InteropServices;

-using System.Windows.Forms;

-using System.Xml.Linq;

-

-namespace LLVM.ClangTidy

-{

-    [PackageRegistration(UseManagedResourcesOnly = true)]

-    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]

-    [ProvideMenuResource("Menus.ctmenu", 1)]

-    [Guid(GuidList.guidClangTidyPkgString)]

-    [ProvideOptionPage(typeof(ClangTidyConfigurationPage), "LLVM/Clang", "ClangTidy", 0, 0, true)]

-    public sealed class ClangTidyPackage : Package

-    {

-        #region Package Members

-        protected override void Initialize()

-        {

-            base.Initialize();

-

-            var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;

-            if (commandService != null)

-            {

-                var menuCommandID = new CommandID(GuidList.guidClangTidyCmdSet, (int)PkgCmdIDList.cmdidClangTidy);

-                var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

-                commandService.AddCommand(menuItem);

-            }

-        }

-        #endregion

-

-        private void MenuItemCallback(object sender, EventArgs args)

-        {

-        }

-    }

-}

+//===-- ClangTidyPackages.cs - VSPackage for clang-tidy ----------*- C# -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains a VS extension package that runs clang-tidy over a
+// file in a VS text editor.
+//
+//===----------------------------------------------------------------------===//
+
+using Microsoft.VisualStudio.Editor;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.TextManager.Interop;
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+using System.Xml.Linq;
+
+namespace LLVM.ClangTidy
+{
+    [PackageRegistration(UseManagedResourcesOnly = true)]
+    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
+    [ProvideMenuResource("Menus.ctmenu", 1)]
+    [Guid(GuidList.guidClangTidyPkgString)]
+    [ProvideOptionPage(typeof(ClangTidyConfigurationPage), "LLVM/Clang", "ClangTidy", 0, 0, true)]
+    public sealed class ClangTidyPackage : Package
+    {
+        #region Package Members
+        protected override void Initialize()
+        {
+            base.Initialize();
+
+            var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
+            if (commandService != null)
+            {
+                var menuCommandID = new CommandID(GuidList.guidClangTidyCmdSet, (int)PkgCmdIDList.cmdidClangTidy);
+                var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+                commandService.AddCommand(menuItem);
+            }
+        }
+        #endregion
+
+        private void MenuItemCallback(object sender, EventArgs args)
+        {
+        }
+    }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
index 20c8a8f..c9945b2 100644
--- a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
+++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
@@ -1,208 +1,207 @@
-//===-- ClangTidyPropertyGrid.cs - UI for configuring clang-tidy -*- C# -*-===//

-//

-//                     The LLVM Compiler Infrastructure

-//

-// This file is distributed under the University of Illinois Open Source

-// License. See LICENSE.TXT for details.

-//

-//===----------------------------------------------------------------------===//

-//

-// This class contains a UserControl consisting of a .NET PropertyGrid control

-// allowing configuration of checks and check options for ClangTidy.

-//

-//===----------------------------------------------------------------------===//

-using System;

-using System.Collections.Generic;

-using System.ComponentModel;

-using System.Drawing;

-using System.Data;

-using System.Linq;

-using System.Text;

-using System.Threading.Tasks;

-using System.Windows.Forms;

-using System.IO;

-using Microsoft.VisualStudio.Shell;

-

-namespace LLVM.ClangTidy

-{

-    /// <summary>

-    ///  A UserControl displaying a PropertyGrid allowing configuration of clang-tidy

-    ///  checks and check options, as well as serialization and deserialization of

-    ///  clang-tidy configuration files.  When a configuration file is loaded, the

-    ///  entire chain of configuration files is analyzed based on the file path,

-    ///  and quick access is provided to edit or view any of the files in the

-    ///  configuration chain, allowing easy visualization of where values come from

-    ///  (similar in spirit to the -explain-config option of clang-tidy).

-    /// </summary>

-    public partial class ClangTidyPropertyGrid : UserControl

-    {

-        /// <summary>

-        /// The sequence of .clang-tidy configuration files, starting from the root

-        /// of the filesystem, down to the selected file.

-        /// </summary>

-        List<KeyValuePair<string, ClangTidyProperties>> PropertyChain_ = null;

-

-        public ClangTidyPropertyGrid()

-        {

-            InitializeComponent();

-            InitializeSettings();

-        }

-

-        private enum ShouldCancel

-        {

-            Yes,

-            No,

-        }

-

-        public void SaveSettingsToStorage()

-        {

-            PersistUnsavedChanges(false);

-        }

-

-        private ShouldCancel PersistUnsavedChanges(bool PromptFirst)

-        {

-            var UnsavedResults = PropertyChain_.Where(x => x.Key != null && x.Value.GetHasUnsavedChanges());

-            if (UnsavedResults.Count() == 0)

-                return ShouldCancel.No;

-

-            bool ShouldSave = false;

-            if (PromptFirst)

-            {

-                var Response = MessageBox.Show(

-                    "You have unsaved changes!  Do you want to save before loading a new file?",

-                    "clang-tidy",

-                    MessageBoxButtons.YesNoCancel);

-

-                ShouldSave = (Response == DialogResult.Yes);

-                if (Response == DialogResult.Cancel)

-                    return ShouldCancel.Yes;

-            }

-            else

-                ShouldSave = true;

-

-            if (ShouldSave)

-            {

-                foreach (var Result in UnsavedResults)

-                {

-                    ClangTidyConfigParser.SerializeClangTidyFile(Result.Value, Result.Key);

-                    Result.Value.SetHasUnsavedChanges(false);

-                }

-            }

-            return ShouldCancel.No;

-        }

-

-        public void InitializeSettings()

-        {

-            PropertyChain_ = new List<KeyValuePair<string, ClangTidyProperties>>();

-            PropertyChain_.Add(new KeyValuePair<string, ClangTidyProperties>(null, ClangTidyProperties.RootProperties));

-            reloadPropertyChain();

-        }

-

-        private void button1_Click(object sender, EventArgs e)

-        {

-            ShouldCancel Cancel = PersistUnsavedChanges(true);

-            if (Cancel == ShouldCancel.Yes)

-                return;

-

-            using (OpenFileDialog D = new OpenFileDialog())

-            {

-                D.Filter = "Clang Tidy files|.clang-tidy";

-                D.CheckPathExists = true;

-                D.CheckFileExists = true;

-

-                if (D.ShowDialog() == DialogResult.OK)

-                {

-                    PropertyChain_.Clear();

-                    PropertyChain_ = ClangTidyConfigParser.ParseConfigurationChain(D.FileName);

-                    textBox1.Text = D.FileName;

-                    reloadPropertyChain();

-                }

-            }

-        }

-

-        private static readonly string DefaultText = "(Default)";

-        private static readonly string BrowseText = "Browse for a file to edit its properties";

-

-        /// <summary>

-        /// After a new configuration file is chosen, analyzes the directory hierarchy

-        /// and finds all .clang-tidy files in the path, parses them and updates the

-        /// PropertyGrid and quick-access LinkLabel control to reflect the new property

-        /// chain.

-        /// </summary>

-        private void reloadPropertyChain()

-        {

-            StringBuilder LinkBuilder = new StringBuilder();

-            LinkBuilder.Append(DefaultText);

-            LinkBuilder.Append(" > ");

-            int PrefixLength = LinkBuilder.Length;

-

-            if (PropertyChain_.Count == 1)

-                LinkBuilder.Append(BrowseText);

-            else

-                LinkBuilder.Append(PropertyChain_[PropertyChain_.Count - 1].Key);

-

-            linkLabelPath.Text = LinkBuilder.ToString();

-

-            // Given a path like D:\Foo\Bar\Baz, construct a LinkLabel where individual

-            // components of the path are clickable iff they contain a .clang-tidy file.

-            // Clicking one of the links then updates the PropertyGrid to display the

-            // selected .clang-tidy file.

-            ClangTidyProperties LastProps = ClangTidyProperties.RootProperties;

-            linkLabelPath.Links.Clear();

-            linkLabelPath.Links.Add(0, DefaultText.Length, LastProps);

-            foreach (var Prop in PropertyChain_.Skip(1))

-            {

-                LastProps = Prop.Value;

-                string ClangTidyFolder = Path.GetFileName(Prop.Key);

-                int ClangTidyFolderOffset = Prop.Key.Length - ClangTidyFolder.Length;

-                linkLabelPath.Links.Add(PrefixLength + ClangTidyFolderOffset, ClangTidyFolder.Length, LastProps);

-            }

-            propertyGrid1.SelectedObject = LastProps;

-        }

-

-        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)

-        {

-            ClangTidyProperties Props = (ClangTidyProperties)propertyGrid1.SelectedObject;

-            Props.SetHasUnsavedChanges(true);

-

-            // When a CategoryVerb is selected, perform the corresponding action.

-            PropertyDescriptor Property = e.ChangedItem.PropertyDescriptor;

-            if (!(e.ChangedItem.Value is CategoryVerb))

-                return;

-

-            CategoryVerb Action = (CategoryVerb)e.ChangedItem.Value;

-            if (Action == CategoryVerb.None)

-                return;

-

-            var Category = Property.Attributes.OfType<CategoryAttribute>().FirstOrDefault();

-            if (Category == null)

-                return;

-            var SameCategoryProps = Props.GetProperties(new Attribute[] { Category });

-            foreach (PropertyDescriptor P in SameCategoryProps)

-            {

-                if (P == Property)

-                    continue;

-                switch (Action)

-                {

-                    case CategoryVerb.Disable:

-                        P.SetValue(propertyGrid1.SelectedObject, false);

-                        break;

-                    case CategoryVerb.Enable:

-                        P.SetValue(propertyGrid1.SelectedObject, true);

-                        break;

-                    case CategoryVerb.Inherit:

-                        P.ResetValue(propertyGrid1.SelectedObject);

-                        break;

-                }

-            }

-            Property.ResetValue(propertyGrid1.SelectedObject);

-            propertyGrid1.Invalidate();

-        }

-

-        private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)

-        {

-            ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData;

-            propertyGrid1.SelectedObject = Props;

-        }

-    }

-}

+//===-- ClangTidyPropertyGrid.cs - UI for configuring clang-tidy -*- C# -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains a UserControl consisting of a .NET PropertyGrid control
+// allowing configuration of checks and check options for ClangTidy.
+//
+//===----------------------------------------------------------------------===//
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.IO;
+using Microsoft.VisualStudio.Shell;
+
+namespace LLVM.ClangTidy
+{
+    /// <summary>
+    ///  A UserControl displaying a PropertyGrid allowing configuration of clang-tidy
+    ///  checks and check options, as well as serialization and deserialization of
+    ///  clang-tidy configuration files.  When a configuration file is loaded, the
+    ///  entire chain of configuration files is analyzed based on the file path,
+    ///  and quick access is provided to edit or view any of the files in the
+    ///  configuration chain, allowing easy visualization of where values come from
+    ///  (similar in spirit to the -explain-config option of clang-tidy).
+    /// </summary>
+    public partial class ClangTidyPropertyGrid : UserControl
+    {
+        /// <summary>
+        /// The sequence of .clang-tidy configuration files, starting from the root
+        /// of the filesystem, down to the selected file.
+        /// </summary>
+        List<KeyValuePair<string, ClangTidyProperties>> PropertyChain_ = null;
+
+        public ClangTidyPropertyGrid()
+        {
+            InitializeComponent();
+            InitializeSettings();
+        }
+
+        private enum ShouldCancel
+        {
+            Yes,
+            No,
+        }
+
+        public void SaveSettingsToStorage()
+        {
+            PersistUnsavedChanges(false);
+        }
+
+        private ShouldCancel PersistUnsavedChanges(bool PromptFirst)
+        {
+            var UnsavedResults = PropertyChain_.Where(x => x.Key != null && x.Value.GetHasUnsavedChanges());
+            if (UnsavedResults.Count() == 0)
+                return ShouldCancel.No;
+
+            bool ShouldSave = false;
+            if (PromptFirst)
+            {
+                var Response = MessageBox.Show(
+                    "You have unsaved changes!  Do you want to save before loading a new file?",
+                    "clang-tidy",
+                    MessageBoxButtons.YesNoCancel);
+
+                ShouldSave = (Response == DialogResult.Yes);
+                if (Response == DialogResult.Cancel)
+                    return ShouldCancel.Yes;
+            }
+            else
+                ShouldSave = true;
+
+            if (ShouldSave)
+            {
+                foreach (var Result in UnsavedResults)
+                {
+                    ClangTidyConfigParser.SerializeClangTidyFile(Result.Value, Result.Key);
+                    Result.Value.SetHasUnsavedChanges(false);
+                }
+            }
+            return ShouldCancel.No;
+        }
+
+        public void InitializeSettings()
+        {
+            PropertyChain_ = new List<KeyValuePair<string, ClangTidyProperties>>();
+            PropertyChain_.Add(new KeyValuePair<string, ClangTidyProperties>(null, ClangTidyProperties.RootProperties));
+            reloadPropertyChain();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            ShouldCancel Cancel = PersistUnsavedChanges(true);
+            if (Cancel == ShouldCancel.Yes)
+                return;
+
+            using (OpenFileDialog D = new OpenFileDialog())
+            {
+                D.Filter = "Clang Tidy files|.clang-tidy";
+                D.CheckPathExists = true;
+                D.CheckFileExists = true;
+
+                if (D.ShowDialog() == DialogResult.OK)
+                {
+                    PropertyChain_.Clear();
+                    PropertyChain_ = ClangTidyConfigParser.ParseConfigurationChain(D.FileName);
+                    textBox1.Text = D.FileName;
+                    reloadPropertyChain();
+                }
+            }
+        }
+
+        private static readonly string DefaultText = "(Default)";
+        private static readonly string BrowseText = "Browse for a file to edit its properties";
+
+        /// <summary>
+        /// After a new configuration file is chosen, analyzes the directory hierarchy
+        /// and finds all .clang-tidy files in the path, parses them and updates the
+        /// PropertyGrid and quick-access LinkLabel control to reflect the new property
+        /// chain.
+        /// </summary>
+        private void reloadPropertyChain()
+        {
+            StringBuilder LinkBuilder = new StringBuilder();
+            LinkBuilder.Append(DefaultText);
+            LinkBuilder.Append(" > ");
+            int PrefixLength = LinkBuilder.Length;
+
+            if (PropertyChain_.Count == 1)
+                LinkBuilder.Append(BrowseText);
+            else
+                LinkBuilder.Append(PropertyChain_[PropertyChain_.Count - 1].Key);
+
+            linkLabelPath.Text = LinkBuilder.ToString();
+
+            // Given a path like D:\Foo\Bar\Baz, construct a LinkLabel where individual
+            // components of the path are clickable iff they contain a .clang-tidy file.
+            // Clicking one of the links then updates the PropertyGrid to display the
+            // selected .clang-tidy file.
+            ClangTidyProperties LastProps = ClangTidyProperties.RootProperties;
+            linkLabelPath.Links.Clear();
+            linkLabelPath.Links.Add(0, DefaultText.Length, LastProps);
+            foreach (var Prop in PropertyChain_.Skip(1))
+            {
+                LastProps = Prop.Value;
+                string ClangTidyFolder = Path.GetFileName(Prop.Key);
+                int ClangTidyFolderOffset = Prop.Key.Length - ClangTidyFolder.Length;
+                linkLabelPath.Links.Add(PrefixLength + ClangTidyFolderOffset, ClangTidyFolder.Length, LastProps);
+            }
+            propertyGrid1.SelectedObject = LastProps;
+        }
+
+        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
+        {
+            ClangTidyProperties Props = (ClangTidyProperties)propertyGrid1.SelectedObject;
+            Props.SetHasUnsavedChanges(true);
+
+            // When a CategoryVerb is selected, perform the corresponding action.
+            PropertyDescriptor Property = e.ChangedItem.PropertyDescriptor;
+            if (!(e.ChangedItem.Value is CategoryVerb))
+                return;
+
+            CategoryVerb Action = (CategoryVerb)e.ChangedItem.Value;
+            if (Action == CategoryVerb.None)
+                return;
+
+            var Category = Property.Attributes.OfType<CategoryAttribute>().FirstOrDefault();
+            if (Category == null)
+                return;
+            var SameCategoryProps = Props.GetProperties(new Attribute[] { Category });
+            foreach (PropertyDescriptor P in SameCategoryProps)
+            {
+                if (P == Property)
+                    continue;
+                switch (Action)
+                {
+                    case CategoryVerb.Disable:
+                        P.SetValue(propertyGrid1.SelectedObject, false);
+                        break;
+                    case CategoryVerb.Enable:
+                        P.SetValue(propertyGrid1.SelectedObject, true);
+                        break;
+                    case CategoryVerb.Inherit:
+                        P.ResetValue(propertyGrid1.SelectedObject);
+                        break;
+                }
+            }
+            Property.ResetValue(propertyGrid1.SelectedObject);
+            propertyGrid1.Invalidate();
+        }
+
+        private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+        {
+            ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData;
+            propertyGrid1.SelectedObject = Props;
+        }
+    }
+}
diff --git a/clang-tidy-vs/ClangTidy/PkgCmdID.cs b/clang-tidy-vs/ClangTidy/PkgCmdID.cs
index 3faf403..beabbce 100644
--- a/clang-tidy-vs/ClangTidy/PkgCmdID.cs
+++ b/clang-tidy-vs/ClangTidy/PkgCmdID.cs
@@ -4,4 +4,4 @@
     {

         public const uint cmdidClangTidy = 0x100;

     };

-}
\ No newline at end of file
+}

diff --git a/clang-tidy-vs/ClangTidy/license.txt b/clang-tidy-vs/ClangTidy/license.txt
index 547f6a4..d3d7ed3 100644
--- a/clang-tidy-vs/ClangTidy/license.txt
+++ b/clang-tidy-vs/ClangTidy/license.txt
@@ -1,5 +1,240 @@
 ==============================================================================
-LLVM Release License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+    1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+    2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+    3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+    4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+    5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+    6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+    7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+    8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+    9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+    END OF TERMS AND CONDITIONS
+
+    APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+    Copyright [yyyy] [name of copyright owner]
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+   `LICENSE` file at the top containing the specific license and restrictions
+   which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+   file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
 ==============================================================================
 University of Illinois/NCSA
 Open Source License
@@ -41,23 +276,3 @@
 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 WITH THE
 SOFTWARE.
-
-==============================================================================
-The LLVM software contains code written by third parties.  Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the LLVM Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program             Directory
--------             ---------
-<none yet>
-
diff --git a/clang-tidy/CMakeLists.txt b/clang-tidy/CMakeLists.txt
index 196548f..84328ba 100644
--- a/clang-tidy/CMakeLists.txt
+++ b/clang-tidy/CMakeLists.txt
@@ -4,10 +4,12 @@
 
 add_clang_library(clangTidy
   ClangTidy.cpp
+  ClangTidyCheck.cpp
   ClangTidyModule.cpp
   ClangTidyDiagnosticConsumer.cpp
   ClangTidyOptions.cpp
   ClangTidyProfiling.cpp
+  ExpandModularHeadersPPCallbacks.cpp
 
   DEPENDS
   ClangSACheckers
@@ -49,6 +51,7 @@
   add_subdirectory(mpi)
 endif()
 add_subdirectory(objc)
+add_subdirectory(openmp)
 add_subdirectory(performance)
 add_subdirectory(plugin)
 add_subdirectory(portability)
diff --git a/clang-tidy/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp
index 0feda60..1d813d6 100644
--- a/clang-tidy/ClangTidy.cpp
+++ b/clang-tidy/ClangTidy.cpp
@@ -1,9 +1,8 @@
 //===--- tools/extra/clang-tidy/ClangTidy.cpp - Clang tidy tool -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -19,6 +18,7 @@
 #include "ClangTidyDiagnosticConsumer.h"
 #include "ClangTidyModuleRegistry.h"
 #include "ClangTidyProfiling.h"
+#include "ExpandModularHeadersPPCallbacks.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -35,6 +35,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Frontend/FixItRewriter.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/Tooling/Core/Diagnostic.h"
 #if CLANG_ENABLE_STATIC_ANALYZER
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
@@ -125,61 +126,51 @@
       }
       auto Diag = Diags.Report(Loc, Diags.getCustomDiagID(Level, "%0 [%1]"))
                   << Message.Message << Name;
-      for (const auto &FileAndReplacements : Error.Fix) {
-        for (const auto &Repl : FileAndReplacements.second) {
-          SourceLocation FixLoc;
-          ++TotalFixes;
-          bool CanBeApplied = false;
-          if (Repl.isApplicable()) {
+      // FIXME: explore options to support interactive fix selection.
+      const llvm::StringMap<Replacements> *ChosenFix = selectFirstFix(Error);
+      if (ApplyFixes && ChosenFix) {
+        for (const auto &FileAndReplacements : *ChosenFix) {
+          for (const auto &Repl : FileAndReplacements.second) {
+            ++TotalFixes;
+            bool CanBeApplied = false;
+            if (!Repl.isApplicable())
+              continue;
+            SourceLocation FixLoc;
             SmallString<128> FixAbsoluteFilePath = Repl.getFilePath();
             Files.makeAbsolutePath(FixAbsoluteFilePath);
-            if (ApplyFixes) {
-              tooling::Replacement R(FixAbsoluteFilePath, Repl.getOffset(),
-                                     Repl.getLength(),
-                                     Repl.getReplacementText());
-              Replacements &Replacements = FileReplacements[R.getFilePath()];
-              llvm::Error Err = Replacements.add(R);
-              if (Err) {
-                // FIXME: Implement better conflict handling.
-                llvm::errs() << "Trying to resolve conflict: "
-                             << llvm::toString(std::move(Err)) << "\n";
-                unsigned NewOffset =
-                    Replacements.getShiftedCodePosition(R.getOffset());
-                unsigned NewLength = Replacements.getShiftedCodePosition(
-                                         R.getOffset() + R.getLength()) -
-                                     NewOffset;
-                if (NewLength == R.getLength()) {
-                  R = Replacement(R.getFilePath(), NewOffset, NewLength,
-                                  R.getReplacementText());
-                  Replacements = Replacements.merge(tooling::Replacements(R));
-                  CanBeApplied = true;
-                  ++AppliedFixes;
-                } else {
-                  llvm::errs()
-                      << "Can't resolve conflict, skipping the replacement.\n";
-                }
-
-              } else {
+            tooling::Replacement R(FixAbsoluteFilePath, Repl.getOffset(),
+                                   Repl.getLength(), Repl.getReplacementText());
+            Replacements &Replacements = FileReplacements[R.getFilePath()];
+            llvm::Error Err = Replacements.add(R);
+            if (Err) {
+              // FIXME: Implement better conflict handling.
+              llvm::errs() << "Trying to resolve conflict: "
+                           << llvm::toString(std::move(Err)) << "\n";
+              unsigned NewOffset =
+                  Replacements.getShiftedCodePosition(R.getOffset());
+              unsigned NewLength = Replacements.getShiftedCodePosition(
+                                       R.getOffset() + R.getLength()) -
+                                   NewOffset;
+              if (NewLength == R.getLength()) {
+                R = Replacement(R.getFilePath(), NewOffset, NewLength,
+                                R.getReplacementText());
+                Replacements = Replacements.merge(tooling::Replacements(R));
                 CanBeApplied = true;
                 ++AppliedFixes;
+              } else {
+                llvm::errs()
+                    << "Can't resolve conflict, skipping the replacement.\n";
               }
+            } else {
+              CanBeApplied = true;
+              ++AppliedFixes;
             }
             FixLoc = getLocation(FixAbsoluteFilePath, Repl.getOffset());
-            SourceLocation FixEndLoc =
-                FixLoc.getLocWithOffset(Repl.getLength());
-            // Retrieve the source range for applicable fixes. Macro definitions
-            // on the command line have locations in a virtual buffer and don't
-            // have valid file paths and are therefore not applicable.
-            CharSourceRange Range =
-                CharSourceRange::getCharRange(SourceRange(FixLoc, FixEndLoc));
-            Diag << FixItHint::CreateReplacement(Range,
-                                                 Repl.getReplacementText());
-          }
-
-          if (ApplyFixes)
             FixLocations.push_back(std::make_pair(FixLoc, CanBeApplied));
+          }
         }
       }
+      reportFix(Diag, Error.Message.Fix);
     }
     for (auto Fix : FixLocations) {
       Diags.Report(Fix.first, Fix.second ? diag::note_fixit_applied
@@ -250,10 +241,33 @@
     return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
   }
 
+  void reportFix(const DiagnosticBuilder &Diag,
+                 const llvm::StringMap<Replacements> &Fix) {
+    for (const auto &FileAndReplacements : Fix) {
+      for (const auto &Repl : FileAndReplacements.second) {
+        if (!Repl.isApplicable())
+          continue;
+        SmallString<128> FixAbsoluteFilePath = Repl.getFilePath();
+        Files.makeAbsolutePath(FixAbsoluteFilePath);
+        SourceLocation FixLoc =
+            getLocation(FixAbsoluteFilePath, Repl.getOffset());
+        SourceLocation FixEndLoc = FixLoc.getLocWithOffset(Repl.getLength());
+        // Retrieve the source range for applicable fixes. Macro definitions
+        // on the command line have locations in a virtual buffer and don't
+        // have valid file paths and are therefore not applicable.
+        CharSourceRange Range =
+            CharSourceRange::getCharRange(SourceRange(FixLoc, FixEndLoc));
+        Diag << FixItHint::CreateReplacement(Range, Repl.getReplacementText());
+      }
+    }
+  }
+
   void reportNote(const tooling::DiagnosticMessage &Message) {
     SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
-    Diags.Report(Loc, Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
+    auto Diag =
+        Diags.Report(Loc, Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
         << Message.Message;
+    reportFix(Diag, Message.Fix);
   }
 
   FileManager Files;
@@ -291,8 +305,10 @@
 } // namespace
 
 ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
-    ClangTidyContext &Context)
-    : Context(Context), CheckFactories(new ClangTidyCheckFactories) {
+    ClangTidyContext &Context,
+    IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS)
+    : Context(Context), OverlayFS(OverlayFS),
+      CheckFactories(new ClangTidyCheckFactories) {
   for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
                                          E = ClangTidyModuleRegistry::end();
        I != E; ++I) {
@@ -352,14 +368,15 @@
     clang::CompilerInstance &Compiler, StringRef File) {
   // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
   // modify Compiler.
-  Context.setSourceManager(&Compiler.getSourceManager());
+  SourceManager *SM = &Compiler.getSourceManager();
+  Context.setSourceManager(SM);
   Context.setCurrentFile(File);
   Context.setASTContext(&Compiler.getASTContext());
 
   auto WorkingDir = Compiler.getSourceManager()
                         .getFileManager()
                         .getVirtualFileSystem()
-                        ->getCurrentWorkingDirectory();
+                        .getCurrentWorkingDirectory();
   if (WorkingDir)
     Context.setCurrentBuildDirectory(WorkingDir.get());
 
@@ -378,9 +395,19 @@
   std::unique_ptr<ast_matchers::MatchFinder> Finder(
       new ast_matchers::MatchFinder(std::move(FinderOptions)));
 
+  Preprocessor *PP = &Compiler.getPreprocessor();
+  Preprocessor *ModuleExpanderPP = PP;
+
+  if (Context.getLangOpts().Modules && OverlayFS != nullptr) {
+    auto ModuleExpander = llvm::make_unique<ExpandModularHeadersPPCallbacks>(
+        &Compiler, OverlayFS);
+    ModuleExpanderPP = ModuleExpander->getPreprocessor();
+    PP->addPPCallbacks(std::move(ModuleExpander));
+  }
+
   for (auto &Check : Checks) {
     Check->registerMatchers(&*Finder);
-    Check->registerPPCallbacks(Compiler);
+    Check->registerPPCallbacks(*SM, PP, ModuleExpanderPP);
   }
 
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
@@ -435,51 +462,6 @@
   return Options;
 }
 
-DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message,
-                                       DiagnosticIDs::Level Level) {
-  return Context->diag(CheckName, Loc, Message, Level);
-}
-
-void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
-  // For historical reasons, checks don't implement the MatchFinder run()
-  // callback directly. We keep the run()/check() distinction to avoid interface
-  // churn, and to allow us to add cross-cutting logic in the future.
-  check(Result);
-}
-
-OptionsView::OptionsView(StringRef CheckName,
-                         const ClangTidyOptions::OptionMap &CheckOptions)
-    : NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
-
-std::string OptionsView::get(StringRef LocalName, StringRef Default) const {
-  const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
-  if (Iter != CheckOptions.end())
-    return Iter->second;
-  return Default;
-}
-
-std::string OptionsView::getLocalOrGlobal(StringRef LocalName,
-                                          StringRef Default) const {
-  auto Iter = CheckOptions.find(NamePrefix + LocalName.str());
-  if (Iter != CheckOptions.end())
-    return Iter->second;
-  // Fallback to global setting, if present.
-  Iter = CheckOptions.find(LocalName.str());
-  if (Iter != CheckOptions.end())
-    return Iter->second;
-  return Default;
-}
-
-void OptionsView::store(ClangTidyOptions::OptionMap &Options,
-                        StringRef LocalName, StringRef Value) const {
-  Options[NamePrefix + LocalName.str()] = Value;
-}
-
-void OptionsView::store(ClangTidyOptions::OptionMap &Options,
-                        StringRef LocalName, int64_t Value) const {
-  store(Options, LocalName, llvm::itostr(Value));
-}
-
 std::vector<std::string>
 getCheckNames(const ClangTidyOptions &Options,
               bool AllowEnablingAnalyzerAlphaCheckers) {
@@ -506,7 +488,7 @@
 runClangTidy(clang::tidy::ClangTidyContext &Context,
              const CompilationDatabase &Compilations,
              ArrayRef<std::string> InputFiles,
-             llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
+             llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> BaseFS,
              bool EnableCheckProfile, llvm::StringRef StoreCheckProfile) {
   ClangTool Tool(Compilations, InputFiles,
                  std::make_shared<PCHContainerOperations>(), BaseFS);
@@ -529,24 +511,8 @@
         return AdjustedArgs;
       };
 
-  // Remove plugins arguments.
-  ArgumentsAdjuster PluginArgumentsRemover =
-      [](const CommandLineArguments &Args, StringRef Filename) {
-        CommandLineArguments AdjustedArgs;
-        for (size_t I = 0, E = Args.size(); I < E; ++I) {
-          if (I + 4 < Args.size() && Args[I] == "-Xclang" &&
-              (Args[I + 1] == "-load" || Args[I + 1] == "-add-plugin" ||
-               StringRef(Args[I + 1]).startswith("-plugin-arg-")) &&
-              Args[I + 2] == "-Xclang") {
-            I += 3;
-          } else
-            AdjustedArgs.push_back(Args[I]);
-        }
-        return AdjustedArgs;
-      };
-
   Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
-  Tool.appendArgumentsAdjuster(PluginArgumentsRemover);
+  Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
   Context.setEnableProfiling(EnableCheckProfile);
   Context.setProfileStoragePrefix(StoreCheckProfile);
 
@@ -558,7 +524,9 @@
 
   class ActionFactory : public FrontendActionFactory {
   public:
-    ActionFactory(ClangTidyContext &Context) : ConsumerFactory(Context) {}
+    ActionFactory(ClangTidyContext &Context,
+                  IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> BaseFS)
+        : ConsumerFactory(Context, BaseFS) {}
     FrontendAction *create() override { return new Action(&ConsumerFactory); }
 
     bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
@@ -589,7 +557,7 @@
     ClangTidyASTConsumerFactory ConsumerFactory;
   };
 
-  ActionFactory Factory(Context);
+  ActionFactory Factory(Context, BaseFS);
   Tool.run(&Factory);
   return DiagConsumer.take();
 }
@@ -600,7 +568,7 @@
                   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
   ErrorReporter Reporter(Context, Fix, BaseFS);
   llvm::vfs::FileSystem &FileSystem =
-      *Reporter.getSourceManager().getFileManager().getVirtualFileSystem();
+      Reporter.getSourceManager().getFileManager().getVirtualFileSystem();
   auto InitialWorkingDir = FileSystem.getCurrentWorkingDirectory();
   if (!InitialWorkingDir)
     llvm::report_fatal_error("Cannot get current working path.");
diff --git a/clang-tidy/ClangTidy.h b/clang-tidy/ClangTidy.h
index dc11200..a9433f6 100644
--- a/clang-tidy/ClangTidy.h
+++ b/clang-tidy/ClangTidy.h
@@ -1,25 +1,19 @@
 //===--- ClangTidy.h - clang-tidy -------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H
 
+#include "ClangTidyCheck.h"
 #include "ClangTidyDiagnosticConsumer.h"
 #include "ClangTidyOptions.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Tooling/Refactoring.h"
-#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include <memory>
-#include <type_traits>
 #include <vector>
 
 namespace clang {
@@ -31,167 +25,13 @@
 
 namespace tidy {
 
-/// \brief Provides access to the ``ClangTidyCheck`` options via check-local
-/// names.
-///
-/// Methods of this class prepend ``CheckName + "."`` to translate check-local
-/// option names to global option names.
-class OptionsView {
-public:
-  /// \brief Initializes the instance using \p CheckName + "." as a prefix.
-  OptionsView(StringRef CheckName,
-              const ClangTidyOptions::OptionMap &CheckOptions);
-
-  /// \brief Read a named option from the ``Context``.
-  ///
-  /// Reads the option with the check-local name \p LocalName from the
-  /// ``CheckOptions``. If the corresponding key is not present, returns
-  /// \p Default.
-  std::string get(StringRef LocalName, StringRef Default) const;
-
-  /// \brief Read a named option from the ``Context``.
-  ///
-  /// Reads the option with the check-local name \p LocalName from local or
-  /// global ``CheckOptions``. Gets local option first. If local is not present,
-  /// falls back to get global option. If global option is not present either,
-  /// returns Default.
-  std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
-
-  /// \brief Read a named option from the ``Context`` and parse it as an
-  /// integral type ``T``.
-  ///
-  /// Reads the option with the check-local name \p LocalName from the
-  /// ``CheckOptions``. If the corresponding key is not present, returns
-  /// \p Default.
-  template <typename T>
-  typename std::enable_if<std::is_integral<T>::value, T>::type
-  get(StringRef LocalName, T Default) const {
-    std::string Value = get(LocalName, "");
-    T Result = Default;
-    if (!Value.empty())
-      StringRef(Value).getAsInteger(10, Result);
-    return Result;
-  }
-
-  /// \brief Read a named option from the ``Context`` and parse it as an
-  /// integral type ``T``.
-  ///
-  /// Reads the option with the check-local name \p LocalName from local or
-  /// global ``CheckOptions``. Gets local option first. If local is not present,
-  /// falls back to get global option. If global option is not present either,
-  /// returns Default.
-  template <typename T>
-  typename std::enable_if<std::is_integral<T>::value, T>::type
-  getLocalOrGlobal(StringRef LocalName, T Default) const {
-    std::string Value = getLocalOrGlobal(LocalName, "");
-    T Result = Default;
-    if (!Value.empty())
-      StringRef(Value).getAsInteger(10, Result);
-    return Result;
-  }
-
-  /// \brief Stores an option with the check-local name \p LocalName with string
-  /// value \p Value to \p Options.
-  void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
-             StringRef Value) const;
-
-  /// \brief Stores an option with the check-local name \p LocalName with
-  /// ``int64_t`` value \p Value to \p Options.
-  void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
-             int64_t Value) const;
-
-private:
-  std::string NamePrefix;
-  const ClangTidyOptions::OptionMap &CheckOptions;
-};
-
-/// \brief Base class for all clang-tidy checks.
-///
-/// To implement a ``ClangTidyCheck``, write a subclass and override some of the
-/// base class's methods. E.g. to implement a check that validates namespace
-/// declarations, override ``registerMatchers``:
-///
-/// ~~~{.cpp}
-/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
-///   Finder->addMatcher(namespaceDecl().bind("namespace"), this);
-/// }
-/// ~~~
-///
-/// and then override ``check(const MatchResult &Result)`` to do the actual
-/// check for each match.
-///
-/// A new ``ClangTidyCheck`` instance is created per translation unit.
-///
-/// FIXME: Figure out whether carrying information from one TU to another is
-/// useful/necessary.
-class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
-public:
-  /// \brief Initializes the check with \p CheckName and \p Context.
-  ///
-  /// Derived classes must implement the constructor with this signature or
-  /// delegate it. If a check needs to read options, it can do this in the
-  /// constructor using the Options.get() methods below.
-  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
-      : CheckName(CheckName), Context(Context),
-        Options(CheckName, Context->getOptions().CheckOptions) {
-    assert(Context != nullptr);
-    assert(!CheckName.empty());
-  }
-
-  /// \brief Override this to register ``PPCallbacks`` with ``Compiler``.
-  ///
-  /// This should be used for clang-tidy checks that analyze preprocessor-
-  /// dependent properties, e.g. the order of include directives.
-  virtual void registerPPCallbacks(CompilerInstance &Compiler) {}
-
-  /// \brief Override this to register AST matchers with \p Finder.
-  ///
-  /// This should be used by clang-tidy checks that analyze code properties that
-  /// dependent on AST knowledge.
-  ///
-  /// You can register as many matchers as necessary with \p Finder. Usually,
-  /// "this" will be used as callback, but you can also specify other callback
-  /// classes. Thereby, different matchers can trigger different callbacks.
-  ///
-  /// If you need to merge information between the different matchers, you can
-  /// store these as members of the derived class. However, note that all
-  /// matches occur in the order of the AST traversal.
-  virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {}
-
-  /// \brief ``ClangTidyChecks`` that register ASTMatchers should do the actual
-  /// work in here.
-  virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
-
-  /// \brief Add a diagnostic with the check's name.
-  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
-                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
-
-  /// \brief Should store all options supported by this check with their
-  /// current values or default values for options that haven't been overridden.
-  ///
-  /// The check should use ``Options.store()`` to store each option it supports
-  /// whether it has the default value or it has been overridden.
-  virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
-
-private:
-  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  StringRef getID() const override { return CheckName; }
-  std::string CheckName;
-  ClangTidyContext *Context;
-
-protected:
-  OptionsView Options;
-  /// \brief Returns the main file name of the current translation unit.
-  StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
-  /// \brief Returns the language options from the context.
-  LangOptions getLangOpts() const { return Context->getLangOpts(); }
-};
-
 class ClangTidyCheckFactories;
 
 class ClangTidyASTConsumerFactory {
 public:
-  ClangTidyASTConsumerFactory(ClangTidyContext &Context);
+  ClangTidyASTConsumerFactory(
+      ClangTidyContext &Context,
+      IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS = nullptr);
 
   /// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
   std::unique_ptr<clang::ASTConsumer>
@@ -205,6 +45,7 @@
 
 private:
   ClangTidyContext &Context;
+  IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
   std::unique_ptr<ClangTidyCheckFactories> CheckFactories;
 };
 
@@ -234,7 +75,7 @@
 runClangTidy(clang::tidy::ClangTidyContext &Context,
              const tooling::CompilationDatabase &Compilations,
              ArrayRef<std::string> InputFiles,
-             llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
+             llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> BaseFS,
              bool EnableCheckProfile = false,
              llvm::StringRef StoreCheckProfile = StringRef());
 
diff --git a/clang-tidy/ClangTidyCheck.cpp b/clang-tidy/ClangTidyCheck.cpp
new file mode 100644
index 0000000..fbf1176
--- /dev/null
+++ b/clang-tidy/ClangTidyCheck.cpp
@@ -0,0 +1,71 @@
+//===--- ClangTidyCheck.cpp - clang-tidy ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+
+ClangTidyCheck::ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
+    : CheckName(CheckName), Context(Context),
+      Options(CheckName, Context->getOptions().CheckOptions) {
+  assert(Context != nullptr);
+  assert(!CheckName.empty());
+}
+
+DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message,
+                                       DiagnosticIDs::Level Level) {
+  return Context->diag(CheckName, Loc, Message, Level);
+}
+
+void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
+  // For historical reasons, checks don't implement the MatchFinder run()
+  // callback directly. We keep the run()/check() distinction to avoid interface
+  // churn, and to allow us to add cross-cutting logic in the future.
+  check(Result);
+}
+
+ClangTidyCheck::OptionsView::OptionsView(StringRef CheckName,
+                         const ClangTidyOptions::OptionMap &CheckOptions)
+    : NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
+
+std::string ClangTidyCheck::OptionsView::get(StringRef LocalName,
+                                             StringRef Default) const {
+  const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
+  if (Iter != CheckOptions.end())
+    return Iter->second;
+  return Default;
+}
+
+std::string
+ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName,
+                                              StringRef Default) const {
+  auto Iter = CheckOptions.find(NamePrefix + LocalName.str());
+  if (Iter != CheckOptions.end())
+    return Iter->second;
+  // Fallback to global setting, if present.
+  Iter = CheckOptions.find(LocalName.str());
+  if (Iter != CheckOptions.end())
+    return Iter->second;
+  return Default;
+}
+
+void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
+                                        StringRef LocalName,
+                                        StringRef Value) const {
+  Options[NamePrefix + LocalName.str()] = Value;
+}
+
+void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
+                                        StringRef LocalName,
+                                        int64_t Value) const {
+  store(Options, LocalName, llvm::itostr(Value));
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/ClangTidyCheck.h b/clang-tidy/ClangTidyCheck.h
new file mode 100644
index 0000000..fcfea90
--- /dev/null
+++ b/clang-tidy/ClangTidyCheck.h
@@ -0,0 +1,194 @@
+//===--- ClangTidyCheck.h - clang-tidy --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
+
+#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyOptions.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringExtras.h"
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+namespace clang {
+
+class CompilerInstance;
+
+namespace tidy {
+
+/// \brief Base class for all clang-tidy checks.
+///
+/// To implement a ``ClangTidyCheck``, write a subclass and override some of the
+/// base class's methods. E.g. to implement a check that validates namespace
+/// declarations, override ``registerMatchers``:
+///
+/// ~~~{.cpp}
+/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
+///   Finder->addMatcher(namespaceDecl().bind("namespace"), this);
+/// }
+/// ~~~
+///
+/// and then override ``check(const MatchResult &Result)`` to do the actual
+/// check for each match.
+///
+/// A new ``ClangTidyCheck`` instance is created per translation unit.
+///
+/// FIXME: Figure out whether carrying information from one TU to another is
+/// useful/necessary.
+class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
+public:
+  /// \brief Initializes the check with \p CheckName and \p Context.
+  ///
+  /// Derived classes must implement the constructor with this signature or
+  /// delegate it. If a check needs to read options, it can do this in the
+  /// constructor using the Options.get() methods below.
+  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
+
+  /// \brief Override this to register ``PPCallbacks`` in the preprocessor.
+  ///
+  /// This should be used for clang-tidy checks that analyze preprocessor-
+  /// dependent properties, e.g. include directives and macro definitions.
+  ///
+  /// There are two Preprocessors to choose from that differ in how they handle
+  /// modular #includes:
+  ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
+  ///    thus doesn't generate PPCallbacks for their contents.
+  ///  - ModuleExpanderPP preprocesses the whole translation unit in the
+  ///    non-modular mode, which allows it to generate PPCallbacks not only for
+  ///    the main file and textual headers, but also for all transitively
+  ///    included modular headers when the analysis runs with modules enabled.
+  ///    When modules are not enabled ModuleExpanderPP just points to the real
+  ///    preprocessor.
+  virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                                   Preprocessor *ModuleExpanderPP) {}
+
+  /// \brief Override this to register AST matchers with \p Finder.
+  ///
+  /// This should be used by clang-tidy checks that analyze code properties that
+  /// dependent on AST knowledge.
+  ///
+  /// You can register as many matchers as necessary with \p Finder. Usually,
+  /// "this" will be used as callback, but you can also specify other callback
+  /// classes. Thereby, different matchers can trigger different callbacks.
+  ///
+  /// If you need to merge information between the different matchers, you can
+  /// store these as members of the derived class. However, note that all
+  /// matches occur in the order of the AST traversal.
+  virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {}
+
+  /// \brief ``ClangTidyChecks`` that register ASTMatchers should do the actual
+  /// work in here.
+  virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
+
+  /// \brief Add a diagnostic with the check's name.
+  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
+                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
+
+  /// \brief Should store all options supported by this check with their
+  /// current values or default values for options that haven't been overridden.
+  ///
+  /// The check should use ``Options.store()`` to store each option it supports
+  /// whether it has the default value or it has been overridden.
+  virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
+
+private:
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  StringRef getID() const override { return CheckName; }
+  std::string CheckName;
+  ClangTidyContext *Context;
+
+protected:
+  /// \brief Provides access to the ``ClangTidyCheck`` options via check-local
+  /// names.
+  ///
+  /// Methods of this class prepend ``CheckName + "."`` to translate check-local
+  /// option names to global option names.
+  class OptionsView {
+  public:
+    /// \brief Initializes the instance using \p CheckName + "." as a prefix.
+    OptionsView(StringRef CheckName,
+                const ClangTidyOptions::OptionMap &CheckOptions);
+
+    /// \brief Read a named option from the ``Context``.
+    ///
+    /// Reads the option with the check-local name \p LocalName from the
+    /// ``CheckOptions``. If the corresponding key is not present, returns
+    /// \p Default.
+    std::string get(StringRef LocalName, StringRef Default) const;
+
+    /// \brief Read a named option from the ``Context``.
+    ///
+    /// Reads the option with the check-local name \p LocalName from local or
+    /// global ``CheckOptions``. Gets local option first. If local is not
+    /// present, falls back to get global option. If global option is not
+    /// present either, returns Default.
+    std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;
+
+    /// \brief Read a named option from the ``Context`` and parse it as an
+    /// integral type ``T``.
+    ///
+    /// Reads the option with the check-local name \p LocalName from the
+    /// ``CheckOptions``. If the corresponding key is not present, returns
+    /// \p Default.
+    template <typename T>
+    typename std::enable_if<std::is_integral<T>::value, T>::type
+    get(StringRef LocalName, T Default) const {
+      std::string Value = get(LocalName, "");
+      T Result = Default;
+      if (!Value.empty())
+        StringRef(Value).getAsInteger(10, Result);
+      return Result;
+    }
+
+    /// \brief Read a named option from the ``Context`` and parse it as an
+    /// integral type ``T``.
+    ///
+    /// Reads the option with the check-local name \p LocalName from local or
+    /// global ``CheckOptions``. Gets local option first. If local is not
+    /// present, falls back to get global option. If global option is not
+    /// present either, returns Default.
+    template <typename T>
+    typename std::enable_if<std::is_integral<T>::value, T>::type
+    getLocalOrGlobal(StringRef LocalName, T Default) const {
+      std::string Value = getLocalOrGlobal(LocalName, "");
+      T Result = Default;
+      if (!Value.empty())
+        StringRef(Value).getAsInteger(10, Result);
+      return Result;
+    }
+
+    /// \brief Stores an option with the check-local name \p LocalName with
+    /// string value \p Value to \p Options.
+    void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
+               StringRef Value) const;
+
+    /// \brief Stores an option with the check-local name \p LocalName with
+    /// ``int64_t`` value \p Value to \p Options.
+    void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
+               int64_t Value) const;
+
+  private:
+    std::string NamePrefix;
+    const ClangTidyOptions::OptionMap &CheckOptions;
+  };
+
+  OptionsView Options;
+  /// \brief Returns the main file name of the current translation unit.
+  StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
+  /// \brief Returns the language options from the context.
+  const LangOptions &getLangOpts() const { return Context->getLangOpts(); }
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index 7e04d71..0abd63e 100644
--- a/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -1,9 +1,8 @@
 //===--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp ----------=== //
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -19,8 +18,10 @@
 #include "ClangTidyDiagnosticConsumer.h"
 #include "ClangTidyOptions.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
+#include "clang/Tooling/Core/Diagnostic.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include <tuple>
@@ -69,6 +70,9 @@
                        SmallVectorImpl<CharSourceRange> &Ranges,
                        ArrayRef<FixItHint> Hints) override {
     assert(Loc.isValid());
+    tooling::DiagnosticMessage *DiagWithFix =
+        Level == DiagnosticsEngine::Note ? &Error.Notes.back() : &Error.Message;
+
     for (const auto &FixIt : Hints) {
       CharSourceRange Range = FixIt.RemoveRange;
       assert(Range.getBegin().isValid() && Range.getEnd().isValid() &&
@@ -78,7 +82,8 @@
 
       tooling::Replacement Replacement(Loc.getManager(), Range,
                                        FixIt.CodeToInsert);
-      llvm::Error Err = Error.Fix[Replacement.getFilePath()].add(Replacement);
+      llvm::Error Err =
+          DiagWithFix->Fix[Replacement.getFilePath()].add(Replacement);
       // FIXME: better error handling (at least, don't let other replacements be
       // applied).
       if (Err) {
@@ -255,7 +260,11 @@
   return WarningAsErrorFilter->contains(CheckName);
 }
 
-StringRef ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
+std::string ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
+  std::string ClangWarningOption =
+      DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(DiagnosticID);
+  if (!ClangWarningOption.empty())
+    return "clang-diagnostic-" + ClangWarningOption;
   llvm::DenseMap<unsigned, std::string>::const_iterator I =
       CheckNamesByDiagnosticID.find(DiagnosticID);
   if (I != CheckNamesByDiagnosticID.end())
@@ -306,7 +315,7 @@
           Line.substr(BracketIndex, BracketEndIndex - BracketIndex);
       // Allow disabling all the checks with "*".
       if (ChecksStr != "*") {
-        StringRef CheckName = Context.getCheckName(DiagID);
+        std::string CheckName = Context.getCheckName(DiagID);
         // Allow specifying a few check names, delimited with comma.
         SmallVector<StringRef, 1> Checks;
         ChecksStr.split(Checks, ',', -1, false);
@@ -403,13 +412,7 @@
            "A diagnostic note can only be appended to a message.");
   } else {
     finalizeLastError();
-    StringRef WarningOption =
-        Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(
-            Info.getID());
-    std::string CheckName = !WarningOption.empty()
-                                ? ("clang-diagnostic-" + WarningOption).str()
-                                : Context.getCheckName(Info.getID()).str();
-
+    std::string CheckName = Context.getCheckName(Info.getID());
     if (CheckName.empty()) {
       // This is a compiler diagnostic without a warning option. Assign check
       // name based on its level.
@@ -584,9 +587,17 @@
 
   // Compute error sizes.
   std::vector<int> Sizes;
-  for (const auto &Error : Errors) {
+  std::vector<
+      std::pair<ClangTidyError *, llvm::StringMap<tooling::Replacements> *>>
+      ErrorFixes;
+  for (auto &Error : Errors) {
+    if (const auto *Fix = tooling::selectFirstFix(Error))
+      ErrorFixes.emplace_back(
+          &Error, const_cast<llvm::StringMap<tooling::Replacements> *>(Fix));
+  }
+  for (const auto &ErrorAndFix : ErrorFixes) {
     int Size = 0;
-    for (const auto &FileAndReplaces : Error.Fix) {
+    for (const auto &FileAndReplaces : *ErrorAndFix.second) {
       for (const auto &Replace : FileAndReplaces.second)
         Size += Replace.getLength();
     }
@@ -595,8 +606,8 @@
 
   // Build events from error intervals.
   std::map<std::string, std::vector<Event>> FileEvents;
-  for (unsigned I = 0; I < Errors.size(); ++I) {
-    for (const auto &FileAndReplace : Errors[I].Fix) {
+  for (unsigned I = 0; I < ErrorFixes.size(); ++I) {
+    for (const auto &FileAndReplace : *ErrorFixes[I].second) {
       for (const auto &Replace : FileAndReplace.second) {
         unsigned Begin = Replace.getOffset();
         unsigned End = Begin + Replace.getLength();
@@ -611,7 +622,7 @@
     }
   }
 
-  std::vector<bool> Apply(Errors.size(), true);
+  std::vector<bool> Apply(ErrorFixes.size(), true);
   for (auto &FileAndEvents : FileEvents) {
     std::vector<Event> &Events = FileAndEvents.second;
     // Sweep.
@@ -630,10 +641,10 @@
     assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
   }
 
-  for (unsigned I = 0; I < Errors.size(); ++I) {
+  for (unsigned I = 0; I < ErrorFixes.size(); ++I) {
     if (!Apply[I]) {
-      Errors[I].Fix.clear();
-      Errors[I].Notes.emplace_back(
+      ErrorFixes[I].second->clear();
+      ErrorFixes[I].first->Notes.emplace_back(
           "this fix will not be applied because it overlaps with another fix");
     }
   }
diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tidy/ClangTidyDiagnosticConsumer.h
index a868203..400f0dc 100644
--- a/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -139,7 +138,7 @@
 
   /// \brief Returns the name of the clang-tidy check which produced this
   /// diagnostic ID.
-  StringRef getCheckName(unsigned DiagnosticID) const;
+  std::string getCheckName(unsigned DiagnosticID) const;
 
   /// \brief Returns \c true if the check is enabled for the \c CurrentFile.
   ///
diff --git a/clang-tidy/ClangTidyForceLinker.h b/clang-tidy/ClangTidyForceLinker.h
index 2e8e8a8..6100cf6 100644
--- a/clang-tidy/ClangTidyForceLinker.h
+++ b/clang-tidy/ClangTidyForceLinker.h
@@ -1,9 +1,8 @@
 //===- ClangTidyForceLinker.h - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -78,6 +77,11 @@
     MPIModuleAnchorSource;
 #endif
 
+// This anchor is used to force the linker to link the OpenMPModule.
+extern volatile int OpenMPModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED OpenMPModuleAnchorDestination =
+    OpenMPModuleAnchorSource;
+
 // This anchor is used to force the linker to link the PerformanceModule.
 extern volatile int PerformanceModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED PerformanceModuleAnchorDestination =
diff --git a/clang-tidy/ClangTidyModule.cpp b/clang-tidy/ClangTidyModule.cpp
index 9dbf016..7d6de87 100644
--- a/clang-tidy/ClangTidyModule.cpp
+++ b/clang-tidy/ClangTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- tools/extra/clang-tidy/ClangTidyModule.cpp - Clang tidy tool -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-tidy/ClangTidyModule.h b/clang-tidy/ClangTidyModule.h
index 4721636..378f109 100644
--- a/clang-tidy/ClangTidyModule.h
+++ b/clang-tidy/ClangTidyModule.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyModule.h - clang-tidy -------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyModuleRegistry.h b/clang-tidy/ClangTidyModuleRegistry.h
index dc44d14..891671a 100644
--- a/clang-tidy/ClangTidyModuleRegistry.h
+++ b/clang-tidy/ClangTidyModuleRegistry.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyModuleRegistry.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyOptions.cpp b/clang-tidy/ClangTidyOptions.cpp
index c40e97c..e6a60ee 100644
--- a/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tidy/ClangTidyOptions.cpp
@@ -1,9 +1,8 @@
 //===--- ClangTidyOptions.cpp - clang-tidy ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyOptions.h b/clang-tidy/ClangTidyOptions.h
index 1a75354..87c7cf5 100644
--- a/clang-tidy/ClangTidyOptions.h
+++ b/clang-tidy/ClangTidyOptions.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyOptions.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyProfiling.cpp b/clang-tidy/ClangTidyProfiling.cpp
index fc0a969..63eed22 100644
--- a/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tidy/ClangTidyProfiling.cpp
@@ -1,9 +1,8 @@
 //===--- ClangTidyProfiling.cpp - clang-tidy --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyProfiling.h b/clang-tidy/ClangTidyProfiling.h
index 9d86b8e..a266e38 100644
--- a/clang-tidy/ClangTidyProfiling.h
+++ b/clang-tidy/ClangTidyProfiling.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyProfiling.h - clang-tidy ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
new file mode 100644
index 0000000..08037c7
--- /dev/null
+++ b/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
@@ -0,0 +1,294 @@
+//===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExpandModularHeadersPPCallbacks.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Serialization/ASTReader.h"
+
+namespace clang {
+namespace tooling {
+
+class ExpandModularHeadersPPCallbacks::FileRecorder {
+public:
+  /// Records that a given file entry is needed for replaying callbacks.
+  void addNecessaryFile(const FileEntry *File) { FilesToRecord.insert(File); }
+
+  /// Records content for a file and adds it to the FileSystem.
+  void recordFileContent(const FileEntry *File,
+                         const SrcMgr::ContentCache &ContentCache,
+                         llvm::vfs::InMemoryFileSystem &InMemoryFs) {
+    // Return if we are not interested in the contents of this file.
+    if (!FilesToRecord.count(File))
+      return;
+
+    // FIXME: Why is this happening? We might be losing contents here.
+    if (!ContentCache.getRawBuffer())
+      return;
+
+    InMemoryFs.addFile(File->getName(), /*ModificationTime=*/0,
+                       llvm::MemoryBuffer::getMemBufferCopy(
+                           ContentCache.getRawBuffer()->getBuffer()));
+    // Remove the file from the set of necessary files.
+    FilesToRecord.erase(File);
+  }
+
+  /// Makes sure we have contents for all the files we were interested in. Ideally
+  /// `FilesToRecord` should be empty.
+  void checkAllFilesRecorded() {
+    for (auto FileEntry : FilesToRecord)
+      llvm::errs() << "Did not record contents for input file: "
+                   << FileEntry->getName() << "\n";
+  }
+
+private:
+  /// A set of files whose contents are to be recorded.
+  llvm::DenseSet<const FileEntry *> FilesToRecord;
+};
+
+ExpandModularHeadersPPCallbacks::ExpandModularHeadersPPCallbacks(
+    CompilerInstance *CI,
+    IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS)
+    : Recorder(llvm::make_unique<FileRecorder>()), Compiler(*CI),
+      InMemoryFs(new llvm::vfs::InMemoryFileSystem),
+      Sources(Compiler.getSourceManager()),
+      // Forward the new diagnostics to the original DiagnosticConsumer.
+      Diags(new DiagnosticIDs, new DiagnosticOptions,
+            new ForwardingDiagnosticConsumer(Compiler.getDiagnosticClient())),
+      LangOpts(Compiler.getLangOpts()) {
+  // Add a FileSystem containing the extra files needed in place of modular
+  // headers.
+  OverlayFS->pushOverlay(InMemoryFs);
+
+  Diags.setSourceManager(&Sources);
+
+  LangOpts.Modules = false;
+
+  auto HSO = std::make_shared<HeaderSearchOptions>();
+  *HSO = Compiler.getHeaderSearchOpts();
+
+  HeaderInfo = llvm::make_unique<HeaderSearch>(HSO, Sources, Diags, LangOpts,
+                                               &Compiler.getTarget());
+
+  auto PO = std::make_shared<PreprocessorOptions>();
+  *PO = Compiler.getPreprocessorOpts();
+
+  PP = llvm::make_unique<clang::Preprocessor>(PO, Diags, LangOpts, Sources,
+                                              *HeaderInfo, ModuleLoader,
+                                              /*IILookup=*/nullptr,
+                                              /*OwnsHeaderSearch=*/false);
+  PP->Initialize(Compiler.getTarget(), Compiler.getAuxTarget());
+  InitializePreprocessor(*PP, *PO, Compiler.getPCHContainerReader(),
+                         Compiler.getFrontendOpts());
+  ApplyHeaderSearchOptions(*HeaderInfo, *HSO, LangOpts,
+                           Compiler.getTarget().getTriple());
+}
+
+ExpandModularHeadersPPCallbacks::~ExpandModularHeadersPPCallbacks() = default;
+
+Preprocessor *ExpandModularHeadersPPCallbacks::getPreprocessor() const {
+  return PP.get();
+}
+
+void ExpandModularHeadersPPCallbacks::handleModuleFile(
+    serialization::ModuleFile *MF) {
+  if (!MF)
+    return;
+  // Avoid processing a ModuleFile more than once.
+  if (VisitedModules.count(MF))
+    return;
+  VisitedModules.insert(MF);
+
+  // Visit all the input files of this module and mark them to record their
+  // contents later.
+  Compiler.getModuleManager()->visitInputFiles(
+      *MF, true, false,
+      [this](const serialization::InputFile &IF, bool /*IsSystem*/) {
+        Recorder->addNecessaryFile(IF.getFile());
+      });
+  // Recursively handle all transitively imported modules.
+  for (auto Import : MF->Imports)
+    handleModuleFile(Import);
+}
+
+void ExpandModularHeadersPPCallbacks::parseToLocation(SourceLocation Loc) {
+  // Load all source locations present in the external sources.
+  for (unsigned I = 0, N = Sources.loaded_sloc_entry_size(); I != N; ++I) {
+    Sources.getLoadedSLocEntry(I, nullptr);
+  }
+  // Record contents of files we are interested in and add to the FileSystem.
+  for (auto It = Sources.fileinfo_begin(); It != Sources.fileinfo_end(); ++It) {
+    Recorder->recordFileContent(It->getFirst(), *It->getSecond(), *InMemoryFs);
+  }
+  Recorder->checkAllFilesRecorded();
+
+  if (!StartedLexing) {
+    StartedLexing = true;
+    PP->Lex(CurrentToken);
+  }
+  while (!CurrentToken.is(tok::eof) &&
+         Sources.isBeforeInTranslationUnit(CurrentToken.getLocation(), Loc)) {
+    PP->Lex(CurrentToken);
+  }
+}
+
+void ExpandModularHeadersPPCallbacks::FileChanged(
+    SourceLocation Loc, FileChangeReason Reason,
+    SrcMgr::CharacteristicKind FileType, FileID PrevFID = FileID()) {
+  if (!EnteredMainFile) {
+    EnteredMainFile = true;
+    PP->EnterMainSourceFile();
+  }
+}
+
+void ExpandModularHeadersPPCallbacks::InclusionDirective(
+    SourceLocation DirectiveLoc, const Token &IncludeToken,
+    StringRef IncludedFilename, bool IsAngled, CharSourceRange FilenameRange,
+    const FileEntry *IncludedFile, StringRef SearchPath, StringRef RelativePath,
+    const Module *Imported, SrcMgr::CharacteristicKind FileType) {
+  if (Imported) {
+    serialization::ModuleFile *MF =
+        Compiler.getModuleManager()->getModuleManager().lookup(
+            Imported->getASTFile());
+    handleModuleFile(MF);
+  }
+  parseToLocation(DirectiveLoc);
+}
+
+void ExpandModularHeadersPPCallbacks::EndOfMainFile() {
+  while (!CurrentToken.is(tok::eof))
+    PP->Lex(CurrentToken);
+}
+
+// Handle all other callbacks.
+// Just parse to the corresponding location to generate the same callback for
+// the PPCallbacks registered in our custom preprocessor.
+void ExpandModularHeadersPPCallbacks::Ident(SourceLocation Loc, StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDirective(SourceLocation Loc,
+                                                      PragmaIntroducerKind) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaComment(SourceLocation Loc,
+                                                    const IdentifierInfo *,
+                                                    StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDetectMismatch(SourceLocation Loc,
+                                                           StringRef,
+                                                           StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDebug(SourceLocation Loc,
+                                                  StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaMessage(SourceLocation Loc,
+                                                    StringRef,
+                                                    PragmaMessageKind,
+                                                    StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDiagnosticPush(SourceLocation Loc,
+                                                           StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDiagnosticPop(SourceLocation Loc,
+                                                          StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
+                                                       StringRef,
+                                                       diag::Severity,
+                                                       StringRef) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::HasInclude(SourceLocation Loc, StringRef,
+                                                 bool, const FileEntry *,
+                                                 SrcMgr::CharacteristicKind) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaOpenCLExtension(
+    SourceLocation NameLoc, const IdentifierInfo *, SourceLocation StateLoc,
+    unsigned) {
+  // FIME: Figure out whether it's the right location to parse to.
+  parseToLocation(NameLoc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaWarning(SourceLocation Loc,
+                                                    StringRef, ArrayRef<int>) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaWarningPush(SourceLocation Loc,
+                                                        int) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaAssumeNonNullBegin(
+    SourceLocation Loc) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::PragmaAssumeNonNullEnd(
+    SourceLocation Loc) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::MacroExpands(const Token &MacroNameTok,
+                                                   const MacroDefinition &,
+                                                   SourceRange Range,
+                                                   const MacroArgs *) {
+  // FIME: Figure out whether it's the right location to parse to.
+  parseToLocation(Range.getBegin());
+}
+void ExpandModularHeadersPPCallbacks::MacroDefined(const Token &MacroNameTok,
+                                                   const MacroDirective *MD) {
+  parseToLocation(MD->getLocation());
+}
+void ExpandModularHeadersPPCallbacks::MacroUndefined(
+    const Token &, const MacroDefinition &, const MacroDirective *Undef) {
+  if (Undef)
+    parseToLocation(Undef->getLocation());
+}
+void ExpandModularHeadersPPCallbacks::Defined(const Token &MacroNameTok,
+                                              const MacroDefinition &,
+                                              SourceRange Range) {
+  // FIME: Figure out whether it's the right location to parse to.
+  parseToLocation(Range.getBegin());
+}
+void ExpandModularHeadersPPCallbacks::SourceRangeSkipped(
+    SourceRange Range, SourceLocation EndifLoc) {
+  // FIME: Figure out whether it's the right location to parse to.
+  parseToLocation(EndifLoc);
+}
+void ExpandModularHeadersPPCallbacks::If(SourceLocation Loc, SourceRange,
+                                         ConditionValueKind) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::Elif(SourceLocation Loc, SourceRange,
+                                           ConditionValueKind, SourceLocation) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::Ifdef(SourceLocation Loc, const Token &,
+                                            const MacroDefinition &) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::Ifndef(SourceLocation Loc, const Token &,
+                                             const MacroDefinition &) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::Else(SourceLocation Loc, SourceLocation) {
+  parseToLocation(Loc);
+}
+void ExpandModularHeadersPPCallbacks::Endif(SourceLocation Loc,
+                                            SourceLocation) {
+  parseToLocation(Loc);
+}
+
+} // namespace tooling
+} // namespace clang
diff --git a/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tidy/ExpandModularHeadersPPCallbacks.h
new file mode 100644
index 0000000..4b43104
--- /dev/null
+++ b/clang-tidy/ExpandModularHeadersPPCallbacks.h
@@ -0,0 +1,137 @@
+//===- ExpandModularHeadersPPCallbacks.h - clang-tidy -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
+#define LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
+
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace clang {
+class CompilerInstance;
+
+namespace serialization {
+class ModuleFile;
+} // namespace serialization
+
+namespace tooling {
+
+/// \brief Handles PPCallbacks and re-runs preprocessing of the whole
+/// translation unit with modules disabled.
+///
+/// This way it's possible to get PPCallbacks for the whole translation unit
+/// including the contents of the modular headers and all their transitive
+/// includes.
+///
+/// This allows existing tools based on PPCallbacks to retain their functionality
+/// when running with C++ modules enabled. This only works in the backwards
+/// compatible modules mode, i.e. when code can still be parsed in non-modular
+/// way.
+class ExpandModularHeadersPPCallbacks : public PPCallbacks {
+public:
+  ExpandModularHeadersPPCallbacks(
+      CompilerInstance *Compiler,
+      IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
+  ~ExpandModularHeadersPPCallbacks();
+
+  /// \brief Returns the preprocessor that provides callbacks for the whole
+  /// translation unit, including the main file, textual headers, and modular
+  /// headers.
+  ///
+  /// This preprocessor is separate from the one used by the rest of the
+  /// compiler.
+  Preprocessor *getPreprocessor() const;
+
+private:
+  class FileRecorder;
+
+  void handleModuleFile(serialization::ModuleFile *MF);
+  void parseToLocation(SourceLocation Loc);
+
+  // Handle PPCallbacks.
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
+
+  void InclusionDirective(SourceLocation DirectiveLoc,
+                          const Token &IncludeToken, StringRef IncludedFilename,
+                          bool IsAngled, CharSourceRange FilenameRange,
+                          const FileEntry *IncludedFile, StringRef SearchPath,
+                          StringRef RelativePath, const Module *Imported,
+                          SrcMgr::CharacteristicKind FileType) override;
+
+  void EndOfMainFile() override;
+
+  // Handle all other callbacks.
+  // Just parse to the corresponding location to generate PPCallbacks for the
+  // corresponding range
+  void Ident(SourceLocation Loc, StringRef) override;
+  void PragmaDirective(SourceLocation Loc, PragmaIntroducerKind) override;
+  void PragmaComment(SourceLocation Loc, const IdentifierInfo *,
+                     StringRef) override;
+  void PragmaDetectMismatch(SourceLocation Loc, StringRef, StringRef) override;
+  void PragmaDebug(SourceLocation Loc, StringRef) override;
+  void PragmaMessage(SourceLocation Loc, StringRef, PragmaMessageKind,
+                     StringRef) override;
+  void PragmaDiagnosticPush(SourceLocation Loc, StringRef) override;
+  void PragmaDiagnosticPop(SourceLocation Loc, StringRef) override;
+  void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity,
+                        StringRef) override;
+  void HasInclude(SourceLocation Loc, StringRef, bool, const FileEntry *,
+                  SrcMgr::CharacteristicKind) override;
+  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *,
+                             SourceLocation StateLoc, unsigned) override;
+  void PragmaWarning(SourceLocation Loc, StringRef, ArrayRef<int>) override;
+  void PragmaWarningPush(SourceLocation Loc, int) override;
+  void PragmaWarningPop(SourceLocation Loc) override;
+  void PragmaAssumeNonNullBegin(SourceLocation Loc) override;
+  void PragmaAssumeNonNullEnd(SourceLocation Loc) override;
+  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &,
+                    SourceRange Range, const MacroArgs *) override;
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override;
+  void MacroUndefined(const Token &, const MacroDefinition &,
+                      const MacroDirective *Undef) override;
+  void Defined(const Token &MacroNameTok, const MacroDefinition &,
+               SourceRange Range) override;
+  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;
+  void If(SourceLocation Loc, SourceRange, ConditionValueKind) override;
+  void Elif(SourceLocation Loc, SourceRange, ConditionValueKind,
+            SourceLocation) override;
+  void Ifdef(SourceLocation Loc, const Token &,
+             const MacroDefinition &) override;
+  void Ifndef(SourceLocation Loc, const Token &,
+              const MacroDefinition &) override;
+  void Else(SourceLocation Loc, SourceLocation) override;
+  void Endif(SourceLocation Loc, SourceLocation) override;
+
+  std::unique_ptr<FileRecorder> Recorder;
+  // Set of all the modules visited. Avoids processing a module more than once.
+  llvm::DenseSet<serialization::ModuleFile *> VisitedModules;
+
+  CompilerInstance &Compiler;
+  // Additional filesystem for replay. Provides all input files from modules.
+  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFs;
+
+  SourceManager &Sources;
+  DiagnosticsEngine Diags;
+  LangOptions LangOpts;
+  TrivialModuleLoader ModuleLoader;
+
+  std::unique_ptr<HeaderSearch> HeaderInfo;
+  std::unique_ptr<Preprocessor> PP;
+  bool EnteredMainFile = false;
+  bool StartedLexing = false;
+  Token CurrentToken;
+};
+
+} // namespace tooling
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_EXPANDMODULARHEADERSPPCALLBACKS_H_
diff --git a/clang-tidy/abseil/AbseilMatcher.h b/clang-tidy/abseil/AbseilMatcher.h
index 116aa95..3f7529d 100644
--- a/clang-tidy/abseil/AbseilMatcher.h
+++ b/clang-tidy/abseil/AbseilMatcher.h
@@ -1,9 +1,8 @@
 //===- AbseilMatcher.h - clang-tidy ---------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp
index 1814001..c70ef90 100644
--- a/clang-tidy/abseil/AbseilTidyModule.cpp
+++ b/clang-tidy/abseil/AbseilTidyModule.cpp
@@ -1,26 +1,30 @@
 //===------- AbseilTidyModule.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "DurationAdditionCheck.h"
 #include "DurationComparisonCheck.h"
+#include "DurationConversionCastCheck.h"
 #include "DurationDivisionCheck.h"
 #include "DurationFactoryFloatCheck.h"
 #include "DurationFactoryScaleCheck.h"
 #include "DurationSubtractionCheck.h"
+#include "DurationUnnecessaryConversionCheck.h"
 #include "FasterStrsplitDelimiterCheck.h"
 #include "NoInternalDependenciesCheck.h"
 #include "NoNamespaceCheck.h"
 #include "RedundantStrcatCallsCheck.h"
 #include "StringFindStartswithCheck.h"
 #include "StrCatAppendCheck.h"
+#include "TimeComparisonCheck.h"
+#include "TimeSubtractionCheck.h"
 #include "UpgradeDurationConversionsCheck.h"
 
 namespace clang {
@@ -30,8 +34,12 @@
 class AbseilModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<DurationAdditionCheck>(
+        "abseil-duration-addition");
     CheckFactories.registerCheck<DurationComparisonCheck>(
         "abseil-duration-comparison");
+    CheckFactories.registerCheck<DurationConversionCastCheck>(
+        "abseil-duration-conversion-cast");
     CheckFactories.registerCheck<DurationDivisionCheck>(
         "abseil-duration-division");
     CheckFactories.registerCheck<DurationFactoryFloatCheck>(
@@ -40,6 +48,8 @@
         "abseil-duration-factory-scale");
     CheckFactories.registerCheck<DurationSubtractionCheck>(
         "abseil-duration-subtraction");
+    CheckFactories.registerCheck<DurationUnnecessaryConversionCheck>(
+        "abseil-duration-unnecessary-conversion");
     CheckFactories.registerCheck<FasterStrsplitDelimiterCheck>(
         "abseil-faster-strsplit-delimiter");
     CheckFactories.registerCheck<NoInternalDependenciesCheck>(
@@ -51,6 +61,10 @@
         "abseil-str-cat-append");
     CheckFactories.registerCheck<StringFindStartswithCheck>(
         "abseil-string-find-startswith");
+    CheckFactories.registerCheck<TimeComparisonCheck>(
+        "abseil-time-comparison");
+    CheckFactories.registerCheck<TimeSubtractionCheck>(
+        "abseil-time-subtraction");
     CheckFactories.registerCheck<UpgradeDurationConversionsCheck>(
         "abseil-upgrade-duration-conversions");
   }
diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt
index bf9d9e8..3f88da6 100644
--- a/clang-tidy/abseil/CMakeLists.txt
+++ b/clang-tidy/abseil/CMakeLists.txt
@@ -2,18 +2,23 @@
 
 add_clang_library(clangTidyAbseilModule
   AbseilTidyModule.cpp
+  DurationAdditionCheck.cpp
   DurationComparisonCheck.cpp
+  DurationConversionCastCheck.cpp
   DurationDivisionCheck.cpp
   DurationFactoryFloatCheck.cpp
   DurationFactoryScaleCheck.cpp
   DurationRewriter.cpp
   DurationSubtractionCheck.cpp
+  DurationUnnecessaryConversionCheck.cpp
   FasterStrsplitDelimiterCheck.cpp
   NoInternalDependenciesCheck.cpp
   NoNamespaceCheck.cpp
   RedundantStrcatCallsCheck.cpp
   StrCatAppendCheck.cpp
   StringFindStartswithCheck.cpp
+  TimeComparisonCheck.cpp
+  TimeSubtractionCheck.cpp
   UpgradeDurationConversionsCheck.cpp
 
   LINK_LIBS
diff --git a/clang-tidy/abseil/DurationAdditionCheck.cpp b/clang-tidy/abseil/DurationAdditionCheck.cpp
new file mode 100644
index 0000000..6004709
--- /dev/null
+++ b/clang-tidy/abseil/DurationAdditionCheck.cpp
@@ -0,0 +1,73 @@
+//===--- DurationAdditionCheck.cpp - clang-tidy----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DurationAdditionCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      binaryOperator(hasOperatorName("+"),
+                     hasEitherOperand(expr(ignoringParenImpCasts(
+                         callExpr(callee(functionDecl(TimeConversionFunction())
+                                             .bind("function_decl")))
+                             .bind("call")))))
+          .bind("binop"),
+      this);
+}
+
+void DurationAdditionCheck::check(const MatchFinder::MatchResult &Result) {
+  const BinaryOperator *Binop =
+      Result.Nodes.getNodeAs<clang::BinaryOperator>("binop");
+  const CallExpr *Call = Result.Nodes.getNodeAs<clang::CallExpr>("call");
+
+  // Don't try to replace things inside of macro definitions.
+  if (Binop->getExprLoc().isMacroID() || Binop->getExprLoc().isInvalid())
+    return;
+
+  llvm::Optional<DurationScale> Scale = getScaleForTimeInverse(
+      Result.Nodes.getNodeAs<clang::FunctionDecl>("function_decl")->getName());
+  if (!Scale)
+    return;
+
+  llvm::StringRef TimeFactory = getTimeInverseForScale(*Scale);
+
+  FixItHint Hint;
+  if (Call == Binop->getLHS()->IgnoreParenImpCasts()) {
+    Hint = FixItHint::CreateReplacement(
+        Binop->getSourceRange(),
+        (llvm::Twine(TimeFactory) + "(" +
+         tooling::fixit::getText(*Call->getArg(0), *Result.Context) + " + " +
+         rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS()) + ")")
+            .str());
+  } else {
+    assert(Call == Binop->getRHS()->IgnoreParenImpCasts() &&
+           "Call should be found on the RHS");
+    Hint = FixItHint::CreateReplacement(
+        Binop->getSourceRange(),
+        (llvm::Twine(TimeFactory) + "(" +
+         rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS()) +
+         " + " + tooling::fixit::getText(*Call->getArg(0), *Result.Context) +
+         ")")
+            .str());
+  }
+
+  diag(Binop->getBeginLoc(), "perform addition in the duration domain") << Hint;
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/abseil/DurationAdditionCheck.h b/clang-tidy/abseil/DurationAdditionCheck.h
new file mode 100644
index 0000000..64b4d89
--- /dev/null
+++ b/clang-tidy/abseil/DurationAdditionCheck.h
@@ -0,0 +1,35 @@
+//===--- DurationAdditionCheck.h - clang-tidy -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Checks for cases where addition should be performed in the
+/// ``absl::Time`` domain.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-addition.html
+class DurationAdditionCheck : public ClangTidyCheck {
+public:
+  DurationAdditionCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H
diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp
index 963da3f..a6e12dd 100644
--- a/clang-tidy/abseil/DurationComparisonCheck.cpp
+++ b/clang-tidy/abseil/DurationComparisonCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DurationComparisonCheck.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,35 +18,11 @@
 namespace tidy {
 namespace abseil {
 
-/// Return `true` if `E` is a either: not a macro at all; or an argument to
-/// one. In the latter case, we should still transform it.
-static bool IsValidMacro(const MatchFinder::MatchResult &Result,
-                         const Expr *E) {
-  if (!E->getBeginLoc().isMacroID())
-    return true;
-
-  SourceLocation Loc = E->getBeginLoc();
-  // We want to get closer towards the initial macro typed into the source only
-  // if the location is being expanded as a macro argument.
-  while (Result.SourceManager->isMacroArgExpansion(Loc)) {
-    // We are calling getImmediateMacroCallerLoc, but note it is essentially
-    // equivalent to calling getImmediateSpellingLoc in this context according
-    // to Clang implementation. We are not calling getImmediateSpellingLoc
-    // because Clang comment says it "should not generally be used by clients."
-    Loc = Result.SourceManager->getImmediateMacroCallerLoc(Loc);
-  }
-  return !Loc.isMacroID();
-}
-
 void DurationComparisonCheck::registerMatchers(MatchFinder *Finder) {
-  auto Matcher =
-      binaryOperator(anyOf(hasOperatorName(">"), hasOperatorName(">="),
-                           hasOperatorName("=="), hasOperatorName("<="),
-                           hasOperatorName("<")),
-                     hasEitherOperand(ignoringImpCasts(callExpr(
-                         callee(functionDecl(DurationConversionFunction())
-                                    .bind("function_decl"))))))
-          .bind("binop");
+  auto Matcher = expr(comparisonOperatorWithCallee(functionDecl(
+                          functionDecl(DurationConversionFunction())
+                              .bind("function_decl"))))
+                     .bind("binop");
 
   Finder->addMatcher(Matcher, this);
 }
@@ -55,7 +30,7 @@
 void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Binop = Result.Nodes.getNodeAs<BinaryOperator>("binop");
 
-  llvm::Optional<DurationScale> Scale = getScaleForInverse(
+  llvm::Optional<DurationScale> Scale = getScaleForDurationInverse(
       Result.Nodes.getNodeAs<FunctionDecl>("function_decl")->getName());
   if (!Scale)
     return;
@@ -64,8 +39,7 @@
   // want to handle the case of rewriting both sides. This is much simpler if
   // we unconditionally try and rewrite both, and let the rewriter determine
   // if nothing needs to be done.
-  if (!IsValidMacro(Result, Binop->getLHS()) ||
-      !IsValidMacro(Result, Binop->getRHS()))
+  if (isInMacro(Result, Binop->getLHS()) || isInMacro(Result, Binop->getRHS()))
     return;
   std::string LhsReplacement =
       rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS());
diff --git a/clang-tidy/abseil/DurationComparisonCheck.h b/clang-tidy/abseil/DurationComparisonCheck.h
index 2d82f8e..4c7085f 100644
--- a/clang-tidy/abseil/DurationComparisonCheck.h
+++ b/clang-tidy/abseil/DurationComparisonCheck.h
@@ -1,9 +1,8 @@
 //===--- DurationComparisonCheck.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tidy/abseil/DurationConversionCastCheck.cpp
new file mode 100644
index 0000000..d9e9155
--- /dev/null
+++ b/clang-tidy/abseil/DurationConversionCastCheck.cpp
@@ -0,0 +1,85 @@
+//===--- DurationConversionCastCheck.cpp - clang-tidy ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DurationConversionCastCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void DurationConversionCastCheck::registerMatchers(MatchFinder *Finder) {
+  auto CallMatcher = ignoringImpCasts(callExpr(
+      callee(functionDecl(DurationConversionFunction()).bind("func_decl")),
+      hasArgument(0, expr().bind("arg"))));
+
+  Finder->addMatcher(
+      expr(anyOf(
+          cxxStaticCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"),
+          cStyleCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"),
+          cxxFunctionalCastExpr(hasSourceExpression(CallMatcher))
+              .bind("cast_expr"))),
+      this);
+}
+
+void DurationConversionCastCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *MatchedCast =
+      Result.Nodes.getNodeAs<ExplicitCastExpr>("cast_expr");
+
+  if (isInMacro(Result, MatchedCast))
+    return;
+
+  const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("func_decl");
+  const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg");
+  StringRef ConversionFuncName = FuncDecl->getName();
+
+  llvm::Optional<DurationScale> Scale =
+      getScaleForDurationInverse(ConversionFuncName);
+  if (!Scale)
+    return;
+
+  // Casting a double to an integer.
+  if (MatchedCast->getTypeAsWritten()->isIntegerType() &&
+      ConversionFuncName.contains("Double")) {
+    llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).second;
+
+    diag(MatchedCast->getBeginLoc(),
+         "duration should be converted directly to an integer rather than "
+         "through a type cast")
+        << FixItHint::CreateReplacement(
+               MatchedCast->getSourceRange(),
+               (llvm::Twine(NewFuncName.substr(2)) + "(" +
+                tooling::fixit::getText(*Arg, *Result.Context) + ")")
+                   .str());
+  }
+
+  // Casting an integer to a double.
+  if (MatchedCast->getTypeAsWritten()->isRealFloatingType() &&
+      ConversionFuncName.contains("Int64")) {
+    llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).first;
+
+    diag(MatchedCast->getBeginLoc(), "duration should be converted directly to "
+                                     "a floating-piont number rather than "
+                                     "through a type cast")
+        << FixItHint::CreateReplacement(
+               MatchedCast->getSourceRange(),
+               (llvm::Twine(NewFuncName.substr(2)) + "(" +
+                tooling::fixit::getText(*Arg, *Result.Context) + ")")
+                   .str());
+  }
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/abseil/DurationConversionCastCheck.h b/clang-tidy/abseil/DurationConversionCastCheck.h
new file mode 100644
index 0000000..bc1d620
--- /dev/null
+++ b/clang-tidy/abseil/DurationConversionCastCheck.h
@@ -0,0 +1,35 @@
+//===--- DurationConversionCastCheck.h - clang-tidy -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Checks for casts of ``absl::Duration`` conversion functions, and recommends
+/// the right conversion function instead.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-conversion-cast.html
+class DurationConversionCastCheck : public ClangTidyCheck {
+public:
+  DurationConversionCastCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H
diff --git a/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tidy/abseil/DurationDivisionCheck.cpp
index 5edc158..82c405f 100644
--- a/clang-tidy/abseil/DurationDivisionCheck.cpp
+++ b/clang-tidy/abseil/DurationDivisionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DurationDivisionCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationDivisionCheck.h b/clang-tidy/abseil/DurationDivisionCheck.h
index 932d029..ac81e05 100644
--- a/clang-tidy/abseil/DurationDivisionCheck.h
+++ b/clang-tidy/abseil/DurationDivisionCheck.h
@@ -1,9 +1,8 @@
 //===--- DurationDivisionCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tidy/abseil/DurationFactoryFloatCheck.cpp
index 0676514..d46265d 100644
--- a/clang-tidy/abseil/DurationFactoryFloatCheck.cpp
+++ b/clang-tidy/abseil/DurationFactoryFloatCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DurationFactoryFloatCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationFactoryFloatCheck.h b/clang-tidy/abseil/DurationFactoryFloatCheck.h
index 8d215e4..cc77315 100644
--- a/clang-tidy/abseil/DurationFactoryFloatCheck.h
+++ b/clang-tidy/abseil/DurationFactoryFloatCheck.h
@@ -1,9 +1,8 @@
 //===--- DurationFactoryFloatCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp
index e56ed81..c3b4191 100644
--- a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp
+++ b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DurationFactoryScaleCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -210,7 +209,7 @@
       diag(Call->getBeginLoc(), "internal duration scaling can be removed")
           << FixItHint::CreateReplacement(
                  Call->getSourceRange(),
-                 (llvm::Twine(getFactoryForScale(*NewScale)) + "(" +
+                 (llvm::Twine(getDurationFactoryForScale(*NewScale)) + "(" +
                   tooling::fixit::getText(*Remainder, *Result.Context) + ")")
                      .str());
     }
@@ -223,7 +222,7 @@
     diag(Call->getBeginLoc(), "internal duration scaling can be removed")
         << FixItHint::CreateReplacement(
                Call->getSourceRange(),
-               (llvm::Twine(getFactoryForScale(*NewScale)) + "(" +
+               (llvm::Twine(getDurationFactoryForScale(*NewScale)) + "(" +
                 tooling::fixit::getText(*Remainder, *Result.Context) + ")")
                    .str());
   }
diff --git a/clang-tidy/abseil/DurationFactoryScaleCheck.h b/clang-tidy/abseil/DurationFactoryScaleCheck.h
index 606724e..3b79b91 100644
--- a/clang-tidy/abseil/DurationFactoryScaleCheck.h
+++ b/clang-tidy/abseil/DurationFactoryScaleCheck.h
@@ -1,9 +1,8 @@
 //===--- DurationFactoryScaleCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp
index ed64889..3466cdb 100644
--- a/clang-tidy/abseil/DurationRewriter.cpp
+++ b/clang-tidy/abseil/DurationRewriter.cpp
@@ -1,9 +1,8 @@
 //===--- DurationRewriter.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,7 +37,7 @@
 }
 
 const std::pair<llvm::StringRef, llvm::StringRef> &
-getInverseForScale(DurationScale Scale) {
+getDurationInverseForScale(DurationScale Scale) {
   static const llvm::IndexedMap<std::pair<llvm::StringRef, llvm::StringRef>,
                                 DurationScale2IndexFunctor>
       InverseMap = []() {
@@ -72,7 +71,7 @@
 rewriteInverseDurationCall(const MatchFinder::MatchResult &Result,
                            DurationScale Scale, const Expr &Node) {
   const std::pair<llvm::StringRef, llvm::StringRef> &InverseFunctions =
-      getInverseForScale(Scale);
+      getDurationInverseForScale(Scale);
   if (const auto *MaybeCallArg = selectFirst<const Expr>(
           "e",
           match(callExpr(callee(functionDecl(hasAnyName(
@@ -85,8 +84,24 @@
   return llvm::None;
 }
 
+/// If `Node` is a call to the inverse of `Scale`, return that inverse's
+/// argument, otherwise None.
+static llvm::Optional<std::string>
+rewriteInverseTimeCall(const MatchFinder::MatchResult &Result,
+                       DurationScale Scale, const Expr &Node) {
+  llvm::StringRef InverseFunction = getTimeInverseForScale(Scale);
+  if (const auto *MaybeCallArg = selectFirst<const Expr>(
+          "e", match(callExpr(callee(functionDecl(hasName(InverseFunction))),
+                              hasArgument(0, expr().bind("e"))),
+                     Node, *Result.Context))) {
+    return tooling::fixit::getText(*MaybeCallArg, *Result.Context).str();
+  }
+
+  return llvm::None;
+}
+
 /// Returns the factory function name for a given `Scale`.
-llvm::StringRef getFactoryForScale(DurationScale Scale) {
+llvm::StringRef getDurationFactoryForScale(DurationScale Scale) {
   switch (Scale) {
   case DurationScale::Hours:
     return "absl::Hours";
@@ -104,6 +119,43 @@
   llvm_unreachable("unknown scaling factor");
 }
 
+llvm::StringRef getTimeFactoryForScale(DurationScale Scale) {
+  switch (Scale) {
+  case DurationScale::Hours:
+    return "absl::FromUnixHours";
+  case DurationScale::Minutes:
+    return "absl::FromUnixMinutes";
+  case DurationScale::Seconds:
+    return "absl::FromUnixSeconds";
+  case DurationScale::Milliseconds:
+    return "absl::FromUnixMillis";
+  case DurationScale::Microseconds:
+    return "absl::FromUnixMicros";
+  case DurationScale::Nanoseconds:
+    return "absl::FromUnixNanos";
+  }
+  llvm_unreachable("unknown scaling factor");
+}
+
+/// Returns the Time factory function name for a given `Scale`.
+llvm::StringRef getTimeInverseForScale(DurationScale scale) {
+  switch (scale) {
+  case DurationScale::Hours:
+    return "absl::ToUnixHours";
+  case DurationScale::Minutes:
+    return "absl::ToUnixMinutes";
+  case DurationScale::Seconds:
+    return "absl::ToUnixSeconds";
+  case DurationScale::Milliseconds:
+    return "absl::ToUnixMillis";
+  case DurationScale::Microseconds:
+    return "absl::ToUnixMicros";
+  case DurationScale::Nanoseconds:
+    return "absl::ToUnixNanos";
+  }
+  llvm_unreachable("unknown scaling factor");
+}
+
 /// Returns `true` if `Node` is a value which evaluates to a literal `0`.
 bool IsLiteralZero(const MatchFinder::MatchResult &Result, const Expr &Node) {
   auto ZeroMatcher =
@@ -176,7 +228,7 @@
   return tooling::fixit::getText(Node, *Result.Context).str();
 }
 
-llvm::Optional<DurationScale> getScaleForInverse(llvm::StringRef Name) {
+llvm::Optional<DurationScale> getScaleForDurationInverse(llvm::StringRef Name) {
   static const llvm::StringMap<DurationScale> ScaleMap(
       {{"ToDoubleHours", DurationScale::Hours},
        {"ToInt64Hours", DurationScale::Hours},
@@ -198,6 +250,22 @@
   return ScaleIter->second;
 }
 
+llvm::Optional<DurationScale> getScaleForTimeInverse(llvm::StringRef Name) {
+  static const llvm::StringMap<DurationScale> ScaleMap(
+      {{"ToUnixHours", DurationScale::Hours},
+       {"ToUnixMinutes", DurationScale::Minutes},
+       {"ToUnixSeconds", DurationScale::Seconds},
+       {"ToUnixMillis", DurationScale::Milliseconds},
+       {"ToUnixMicros", DurationScale::Microseconds},
+       {"ToUnixNanos", DurationScale::Nanoseconds}});
+
+  auto ScaleIter = ScaleMap.find(std::string(Name));
+  if (ScaleIter == ScaleMap.end())
+    return llvm::None;
+
+  return ScaleIter->second;
+}
+
 std::string rewriteExprFromNumberToDuration(
     const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
     const Expr *Node) {
@@ -211,11 +279,46 @@
   if (IsLiteralZero(Result, RootNode))
     return std::string("absl::ZeroDuration()");
 
-  return (llvm::Twine(getFactoryForScale(Scale)) + "(" +
+  return (llvm::Twine(getDurationFactoryForScale(Scale)) + "(" +
           simplifyDurationFactoryArg(Result, RootNode) + ")")
       .str();
 }
 
+std::string rewriteExprFromNumberToTime(
+    const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
+    const Expr *Node) {
+  const Expr &RootNode = *Node->IgnoreParenImpCasts();
+
+  // First check to see if we can undo a complimentary function call.
+  if (llvm::Optional<std::string> MaybeRewrite =
+          rewriteInverseTimeCall(Result, Scale, RootNode))
+    return *MaybeRewrite;
+
+  if (IsLiteralZero(Result, RootNode))
+    return std::string("absl::UnixEpoch()");
+
+  return (llvm::Twine(getTimeFactoryForScale(Scale)) + "(" +
+          tooling::fixit::getText(RootNode, *Result.Context) + ")")
+      .str();
+}
+
+bool isInMacro(const MatchFinder::MatchResult &Result, const Expr *E) {
+  if (!E->getBeginLoc().isMacroID())
+    return false;
+
+  SourceLocation Loc = E->getBeginLoc();
+  // We want to get closer towards the initial macro typed into the source only
+  // if the location is being expanded as a macro argument.
+  while (Result.SourceManager->isMacroArgExpansion(Loc)) {
+    // We are calling getImmediateMacroCallerLoc, but note it is essentially
+    // equivalent to calling getImmediateSpellingLoc in this context according
+    // to Clang implementation. We are not calling getImmediateSpellingLoc
+    // because Clang comment says it "should not generally be used by clients."
+    Loc = Result.SourceManager->getImmediateMacroCallerLoc(Loc);
+  }
+  return Loc.isMacroID();
+}
+
 } // namespace abseil
 } // namespace tidy
 } // namespace clang
diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h
index d0004d1..1ae312c 100644
--- a/clang-tidy/abseil/DurationRewriter.h
+++ b/clang-tidy/abseil/DurationRewriter.h
@@ -1,9 +1,8 @@
 //===--- DurationRewriter.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -30,7 +29,11 @@
 
 /// Given a `Scale`, return the appropriate factory function call for
 /// constructing a `Duration` for that scale.
-llvm::StringRef getFactoryForScale(DurationScale Scale);
+llvm::StringRef getDurationFactoryForScale(DurationScale Scale);
+
+/// Given a 'Scale', return the appropriate factory function call for
+/// constructing a `Time` for that scale.
+llvm::StringRef getTimeFactoryForScale(DurationScale scale);
 
 // Determine if `Node` represents a literal floating point or integral zero.
 bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result,
@@ -61,13 +64,20 @@
 
 /// Given the name of an inverse Duration function (e.g., `ToDoubleSeconds`),
 /// return its `DurationScale`, or `None` if a match is not found.
-llvm::Optional<DurationScale> getScaleForInverse(llvm::StringRef Name);
+llvm::Optional<DurationScale> getScaleForDurationInverse(llvm::StringRef Name);
+
+/// Given the name of an inverse Time function (e.g., `ToUnixSeconds`),
+/// return its `DurationScale`, or `None` if a match is not found.
+llvm::Optional<DurationScale> getScaleForTimeInverse(llvm::StringRef Name);
 
 /// Given a `Scale` return the fully qualified inverse functions for it.
 /// The first returned value is the inverse for `double`, and the second
 /// returned value is the inverse for `int64`.
 const std::pair<llvm::StringRef, llvm::StringRef> &
-getInverseForScale(DurationScale Scale);
+getDurationInverseForScale(DurationScale Scale);
+
+/// Returns the Time inverse function name for a given `Scale`.
+llvm::StringRef getTimeInverseForScale(DurationScale scale);
 
 /// Assuming `Node` has type `double` or `int` representing a time interval of
 /// `Scale`, return the expression to make it a suitable `Duration`.
@@ -75,6 +85,17 @@
     const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
     const Expr *Node);
 
+/// Assuming `Node` has a type `int` representing a time instant of `Scale`
+/// since The Epoch, return the expression to make it a suitable `Time`.
+std::string rewriteExprFromNumberToTime(
+    const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
+    const Expr *Node);
+
+/// Return `false` if `E` is a either: not a macro at all; or an argument to
+/// one.  In the both cases, we often want to do the transformation.
+bool isInMacro(const ast_matchers::MatchFinder::MatchResult &Result,
+               const Expr *E);
+
 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
                      DurationConversionFunction) {
   using namespace clang::ast_matchers;
@@ -95,6 +116,24 @@
                                  "::absl::Minutes", "::absl::Hours"));
 }
 
+AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
+                     TimeConversionFunction) {
+  using namespace clang::ast_matchers;
+  return functionDecl(hasAnyName(
+      "::absl::ToUnixHours", "::absl::ToUnixMinutes", "::absl::ToUnixSeconds",
+      "::absl::ToUnixMillis", "::absl::ToUnixMicros", "::absl::ToUnixNanos"));
+}
+
+AST_MATCHER_FUNCTION_P(ast_matchers::internal::Matcher<Stmt>,
+                       comparisonOperatorWithCallee,
+                       ast_matchers::internal::Matcher<Decl>, funcDecl) {
+  using namespace clang::ast_matchers;
+  return binaryOperator(
+      anyOf(hasOperatorName(">"), hasOperatorName(">="), hasOperatorName("=="),
+            hasOperatorName("<="), hasOperatorName("<")),
+      hasEitherOperand(ignoringImpCasts(callExpr(callee(funcDecl)))));
+}
+
 } // namespace abseil
 } // namespace tidy
 } // namespace clang
diff --git a/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tidy/abseil/DurationSubtractionCheck.cpp
index db9d407..3221714 100644
--- a/clang-tidy/abseil/DurationSubtractionCheck.cpp
+++ b/clang-tidy/abseil/DurationSubtractionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DurationSubtractionCheck.cpp - clang-tidy ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,7 +37,8 @@
   if (Binop->getExprLoc().isMacroID() || Binop->getExprLoc().isInvalid())
     return;
 
-  llvm::Optional<DurationScale> Scale = getScaleForInverse(FuncDecl->getName());
+  llvm::Optional<DurationScale> Scale =
+      getScaleForDurationInverse(FuncDecl->getName());
   if (!Scale)
     return;
 
diff --git a/clang-tidy/abseil/DurationSubtractionCheck.h b/clang-tidy/abseil/DurationSubtractionCheck.h
index 227dcdb..89deb37 100644
--- a/clang-tidy/abseil/DurationSubtractionCheck.h
+++ b/clang-tidy/abseil/DurationSubtractionCheck.h
@@ -1,9 +1,8 @@
 //===--- DurationSubtractionCheck.h - clang-tidy ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
new file mode 100644
index 0000000..2ba90ee
--- /dev/null
+++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
@@ -0,0 +1,82 @@
+//===--- DurationUnnecessaryConversionCheck.cpp - clang-tidy
+//-----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DurationUnnecessaryConversionCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) {
+  for (const auto &Scale : {"Hours", "Minutes", "Seconds", "Milliseconds",
+                            "Microseconds", "Nanoseconds"}) {
+    std::string DurationFactory = (llvm::Twine("::absl::") + Scale).str();
+    std::string FloatConversion =
+        (llvm::Twine("::absl::ToDouble") + Scale).str();
+    std::string IntegerConversion =
+        (llvm::Twine("::absl::ToInt64") + Scale).str();
+
+    // Matcher which matches the current scale's factory with a `1` argument,
+    // e.g. `absl::Seconds(1)`.
+    auto factory_matcher = cxxConstructExpr(hasArgument(
+        0,
+        callExpr(callee(functionDecl(hasName(DurationFactory))),
+                 hasArgument(0, ignoringImpCasts(integerLiteral(equals(1)))))));
+
+    // Matcher which matches either inverse function and binds its argument,
+    // e.g. `absl::ToDoubleSeconds(dur)`.
+    auto inverse_function_matcher = callExpr(
+        callee(functionDecl(hasAnyName(FloatConversion, IntegerConversion))),
+        hasArgument(0, expr().bind("arg")));
+
+    // Matcher which matches a duration divided by the factory_matcher above,
+    // e.g. `dur / absl::Seconds(1)`.
+    auto division_operator_matcher = cxxOperatorCallExpr(
+        hasOverloadedOperatorName("/"), hasArgument(0, expr().bind("arg")),
+        hasArgument(1, factory_matcher));
+
+    // Matcher which matches a duration argument to `FDivDuration`,
+    // e.g. `absl::FDivDuration(dur, absl::Seconds(1))`
+    auto fdiv_matcher = callExpr(
+        callee(functionDecl(hasName("::absl::FDivDuration"))),
+        hasArgument(0, expr().bind("arg")), hasArgument(1, factory_matcher));
+
+    Finder->addMatcher(
+        callExpr(callee(functionDecl(hasName(DurationFactory))),
+                 hasArgument(0, anyOf(inverse_function_matcher,
+                                      division_operator_matcher, fdiv_matcher)))
+            .bind("call"),
+        this);
+  }
+}
+
+void DurationUnnecessaryConversionCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *OuterCall = Result.Nodes.getNodeAs<Expr>("call");
+  const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg");
+
+  if (isInMacro(Result, OuterCall))
+    return;
+
+  diag(OuterCall->getBeginLoc(),
+       "remove unnecessary absl::Duration conversions")
+      << FixItHint::CreateReplacement(
+             OuterCall->getSourceRange(),
+             tooling::fixit::getText(*Arg, *Result.Context));
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h
new file mode 100644
index 0000000..1806133
--- /dev/null
+++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h
@@ -0,0 +1,35 @@
+//===--- DurationUnnecessaryConversionCheck.h - clang-tidy ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Finds and fixes cases where ``absl::Duration`` values are being converted
+/// to numeric types and back again.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-unnecessary-conversion.html
+class DurationUnnecessaryConversionCheck : public ClangTidyCheck {
+public:
+  DurationUnnecessaryConversionCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H
diff --git a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
index 35d99ac..57f822e 100644
--- a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
+++ b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp
@@ -1,9 +1,8 @@
 //===--- FasterStrsplitDelimiterCheck.cpp - clang-tidy---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h
index 17e231c..7dc77e7 100644
--- a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h
+++ b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h
@@ -1,9 +1,8 @@
 //===--- FasterStrsplitDelimiterCheck.h - clang-tidy-------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/NoInternalDependenciesCheck.cpp b/clang-tidy/abseil/NoInternalDependenciesCheck.cpp
index cb77e95..dcb8585 100644
--- a/clang-tidy/abseil/NoInternalDependenciesCheck.cpp
+++ b/clang-tidy/abseil/NoInternalDependenciesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NoInternalDependenciesCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/NoInternalDependenciesCheck.h b/clang-tidy/abseil/NoInternalDependenciesCheck.h
index 7e659df..301c89d 100644
--- a/clang-tidy/abseil/NoInternalDependenciesCheck.h
+++ b/clang-tidy/abseil/NoInternalDependenciesCheck.h
@@ -1,9 +1,8 @@
 //===--- NoInternalDependenciesCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/NoNamespaceCheck.cpp b/clang-tidy/abseil/NoNamespaceCheck.cpp
index fc9e698..5db50de 100644
--- a/clang-tidy/abseil/NoNamespaceCheck.cpp
+++ b/clang-tidy/abseil/NoNamespaceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NoNamespaceCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/NoNamespaceCheck.h b/clang-tidy/abseil/NoNamespaceCheck.h
index 00686d1..058d110 100644
--- a/clang-tidy/abseil/NoNamespaceCheck.h
+++ b/clang-tidy/abseil/NoNamespaceCheck.h
@@ -1,9 +1,8 @@
 //===--- NoNamespaceCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp b/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
index 1980668..f8e6e7a 100644
--- a/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
+++ b/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantStrcatCallsCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/RedundantStrcatCallsCheck.h b/clang-tidy/abseil/RedundantStrcatCallsCheck.h
index ede0354..71f3ff6 100644
--- a/clang-tidy/abseil/RedundantStrcatCallsCheck.h
+++ b/clang-tidy/abseil/RedundantStrcatCallsCheck.h
@@ -1,9 +1,8 @@
 //===--- RedundantStrcatCallsCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/StrCatAppendCheck.cpp b/clang-tidy/abseil/StrCatAppendCheck.cpp
index 4907237..a249b12 100644
--- a/clang-tidy/abseil/StrCatAppendCheck.cpp
+++ b/clang-tidy/abseil/StrCatAppendCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StrCatAppendCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/StrCatAppendCheck.h b/clang-tidy/abseil/StrCatAppendCheck.h
index eaa750d..72203fd 100644
--- a/clang-tidy/abseil/StrCatAppendCheck.h
+++ b/clang-tidy/abseil/StrCatAppendCheck.h
@@ -1,9 +1,8 @@
 //===--- StrCatAppendCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/StringFindStartswithCheck.cpp b/clang-tidy/abseil/StringFindStartswithCheck.cpp
index 2701c24..3fd9fd4 100644
--- a/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ b/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StringFindStartswithCheck.cc - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -115,11 +114,10 @@
 }
 
 void StringFindStartswithCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  IncludeInserter = llvm::make_unique<clang::tidy::utils::IncludeInserter>(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
-  Compiler.getPreprocessor().addPPCallbacks(
-      IncludeInserter->CreatePPCallbacks());
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                              IncludeStyle);
+  PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
 }
 
 void StringFindStartswithCheck::storeOptions(
diff --git a/clang-tidy/abseil/StringFindStartswithCheck.h b/clang-tidy/abseil/StringFindStartswithCheck.h
index 1c04e80..8a702f7 100644
--- a/clang-tidy/abseil/StringFindStartswithCheck.h
+++ b/clang-tidy/abseil/StringFindStartswithCheck.h
@@ -1,9 +1,8 @@
 //===--- StringFindStartswithCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -29,7 +28,8 @@
 public:
   using ClangTidyCheck::ClangTidyCheck;
   StringFindStartswithCheck(StringRef Name, ClangTidyContext *Context);
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
diff --git a/clang-tidy/abseil/TimeComparisonCheck.cpp b/clang-tidy/abseil/TimeComparisonCheck.cpp
new file mode 100644
index 0000000..391f38f
--- /dev/null
+++ b/clang-tidy/abseil/TimeComparisonCheck.cpp
@@ -0,0 +1,61 @@
+//===--- TimeComparisonCheck.cpp - clang-tidy
+//--------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TimeComparisonCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void TimeComparisonCheck::registerMatchers(MatchFinder *Finder) {
+  auto Matcher =
+      expr(comparisonOperatorWithCallee(functionDecl(
+               functionDecl(TimeConversionFunction()).bind("function_decl"))))
+          .bind("binop");
+
+  Finder->addMatcher(Matcher, this);
+}
+
+void TimeComparisonCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Binop = Result.Nodes.getNodeAs<BinaryOperator>("binop");
+
+  llvm::Optional<DurationScale> Scale = getScaleForTimeInverse(
+      Result.Nodes.getNodeAs<FunctionDecl>("function_decl")->getName());
+  if (!Scale)
+    return;
+
+  if (isInMacro(Result, Binop->getLHS()) || isInMacro(Result, Binop->getRHS()))
+    return;
+
+  // In most cases, we'll only need to rewrite one of the sides, but we also
+  // want to handle the case of rewriting both sides. This is much simpler if
+  // we unconditionally try and rewrite both, and let the rewriter determine
+  // if nothing needs to be done.
+  std::string LhsReplacement =
+      rewriteExprFromNumberToTime(Result, *Scale, Binop->getLHS());
+  std::string RhsReplacement =
+      rewriteExprFromNumberToTime(Result, *Scale, Binop->getRHS());
+
+  diag(Binop->getBeginLoc(), "perform comparison in the time domain")
+      << FixItHint::CreateReplacement(Binop->getSourceRange(),
+                                      (llvm::Twine(LhsReplacement) + " " +
+                                       Binop->getOpcodeStr() + " " +
+                                       RhsReplacement)
+                                          .str());
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/abseil/TimeComparisonCheck.h b/clang-tidy/abseil/TimeComparisonCheck.h
new file mode 100644
index 0000000..5598433
--- /dev/null
+++ b/clang-tidy/abseil/TimeComparisonCheck.h
@@ -0,0 +1,35 @@
+//===--- TimeComparisonCheck.h - clang-tidy ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Prefer comparison in the `absl::Time` domain instead of the numeric
+/// domain.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-time-comparison.html
+class TimeComparisonCheck : public ClangTidyCheck {
+public:
+  TimeComparisonCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H
diff --git a/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tidy/abseil/TimeSubtractionCheck.cpp
new file mode 100644
index 0000000..0a7c401
--- /dev/null
+++ b/clang-tidy/abseil/TimeSubtractionCheck.cpp
@@ -0,0 +1,181 @@
+//===--- TimeSubtractionCheck.cpp - clang-tidy ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TimeSubtractionCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+// Returns `true` if `Range` is inside a macro definition.
+static bool InsideMacroDefinition(const MatchFinder::MatchResult &Result,
+                                  SourceRange Range) {
+  return !clang::Lexer::makeFileCharRange(
+              clang::CharSourceRange::getCharRange(Range),
+              *Result.SourceManager, Result.Context->getLangOpts())
+              .isValid();
+}
+
+static bool isConstructorAssignment(const MatchFinder::MatchResult &Result,
+                                    const Expr *Node) {
+  return selectFirst<const Expr>(
+             "e", match(expr(hasParent(materializeTemporaryExpr(hasParent(
+                                 cxxConstructExpr(hasParent(exprWithCleanups(
+                                     hasParent(varDecl()))))))))
+                            .bind("e"),
+                        *Node, *Result.Context)) != nullptr;
+}
+
+static bool isArgument(const MatchFinder::MatchResult &Result,
+                       const Expr *Node) {
+  return selectFirst<const Expr>(
+             "e",
+             match(expr(hasParent(
+                            materializeTemporaryExpr(hasParent(cxxConstructExpr(
+                                hasParent(callExpr()),
+                                unless(hasParent(cxxOperatorCallExpr())))))))
+                       .bind("e"),
+                   *Node, *Result.Context)) != nullptr;
+}
+
+static bool isReturn(const MatchFinder::MatchResult &Result, const Expr *Node) {
+  return selectFirst<const Expr>(
+             "e", match(expr(hasParent(materializeTemporaryExpr(hasParent(
+                                 cxxConstructExpr(hasParent(exprWithCleanups(
+                                     hasParent(returnStmt()))))))))
+                            .bind("e"),
+                        *Node, *Result.Context)) != nullptr;
+}
+
+static bool parensRequired(const MatchFinder::MatchResult &Result,
+                           const Expr *Node) {
+  // TODO: Figure out any more contexts in which we can omit the surrounding
+  // parentheses.
+  return !(isConstructorAssignment(Result, Node) || isArgument(Result, Node) ||
+           isReturn(Result, Node));
+}
+
+void TimeSubtractionCheck::emitDiagnostic(const Expr *Node,
+                                          llvm::StringRef Replacement) {
+  diag(Node->getBeginLoc(), "perform subtraction in the time domain")
+      << FixItHint::CreateReplacement(Node->getSourceRange(), Replacement);
+}
+
+void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) {
+  for (auto ScaleName :
+       {"Hours", "Minutes", "Seconds", "Millis", "Micros", "Nanos"}) {
+    std::string TimeInverse = (llvm::Twine("ToUnix") + ScaleName).str();
+    llvm::Optional<DurationScale> Scale = getScaleForTimeInverse(TimeInverse);
+    assert(Scale && "Unknow scale encountered");
+
+    auto TimeInverseMatcher = callExpr(callee(
+        functionDecl(hasName((llvm::Twine("::absl::") + TimeInverse).str()))
+            .bind("func_decl")));
+
+    // Match the cases where we know that the result is a 'Duration' and the
+    // first argument is a 'Time'. Just knowing the type of the first operand
+    // is not sufficient, since the second operand could be either a 'Time' or
+    // a 'Duration'. If we know the result is a 'Duration', we can then infer
+    // that the second operand must be a 'Time'.
+    auto CallMatcher =
+        callExpr(
+            callee(functionDecl(hasName(getDurationFactoryForScale(*Scale)))),
+            hasArgument(0, binaryOperator(hasOperatorName("-"),
+                                          hasLHS(TimeInverseMatcher))
+                               .bind("binop")))
+            .bind("outer_call");
+    Finder->addMatcher(CallMatcher, this);
+
+    // Match cases where we know the second operand is a 'Time'. Since
+    // subtracting a 'Time' from a 'Duration' is not defined, in these cases,
+    // we always know the first operand is a 'Time' if the second is a 'Time'.
+    auto OperandMatcher =
+        binaryOperator(hasOperatorName("-"), hasRHS(TimeInverseMatcher))
+            .bind("binop");
+    Finder->addMatcher(OperandMatcher, this);
+  }
+}
+
+void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
+  std::string InverseName =
+      Result.Nodes.getNodeAs<FunctionDecl>("func_decl")->getNameAsString();
+  if (InsideMacroDefinition(Result, BinOp->getSourceRange()))
+    return;
+
+  llvm::Optional<DurationScale> Scale = getScaleForTimeInverse(InverseName);
+  if (!Scale)
+    return;
+
+  const auto *OuterCall = Result.Nodes.getNodeAs<CallExpr>("outer_call");
+  if (OuterCall) {
+    if (InsideMacroDefinition(Result, OuterCall->getSourceRange()))
+      return;
+
+    // We're working with the first case of matcher, and need to replace the
+    // entire 'Duration' factory call. (Which also means being careful about
+    // our order-of-operations and optionally putting in some parenthesis.
+    bool NeedParens = parensRequired(Result, OuterCall);
+
+    emitDiagnostic(
+        OuterCall,
+        (llvm::Twine(NeedParens ? "(" : "") +
+         rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) + " - " +
+         rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) +
+         (NeedParens ? ")" : ""))
+            .str());
+  } else {
+    // We're working with the second case of matcher, and either just need to
+    // change the arguments, or perhaps remove an outer function call. In the
+    // latter case (addressed first), we also need to worry about parenthesis.
+    const auto *MaybeCallArg = selectFirst<const CallExpr>(
+        "arg", match(expr(hasAncestor(
+                         callExpr(callee(functionDecl(hasName(
+                                      getDurationFactoryForScale(*Scale)))))
+                             .bind("arg"))),
+                     *BinOp, *Result.Context));
+    if (MaybeCallArg && MaybeCallArg->getArg(0)->IgnoreImpCasts() == BinOp &&
+        !InsideMacroDefinition(Result, MaybeCallArg->getSourceRange())) {
+      // Handle the case where the matched expression is inside a call which
+      // converts it from the inverse to a Duration.  In this case, we replace
+      // the outer with just the subtraction expresison, which gives the right
+      // type and scale, taking care again about parenthesis.
+      bool NeedParens = parensRequired(Result, MaybeCallArg);
+
+      emitDiagnostic(
+          MaybeCallArg,
+          (llvm::Twine(NeedParens ? "(" : "") +
+           rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) +
+           " - " +
+           rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) +
+           (NeedParens ? ")" : ""))
+              .str());
+    } else {
+      // In the last case, just convert the arguments and wrap the result in
+      // the correct inverse function.
+      emitDiagnostic(
+          BinOp,
+          (llvm::Twine(
+               getDurationInverseForScale(*Scale).second.str().substr(2)) +
+           "(" + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) +
+           " - " +
+           rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) + ")")
+              .str());
+    }
+  }
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/abseil/TimeSubtractionCheck.h b/clang-tidy/abseil/TimeSubtractionCheck.h
new file mode 100644
index 0000000..4e3cd3b
--- /dev/null
+++ b/clang-tidy/abseil/TimeSubtractionCheck.h
@@ -0,0 +1,38 @@
+//===--- TimeSubtractionCheck.h - clang-tidy --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Finds and fixes `absl::Time` subtraction expressions to do subtraction
+/// in the time domain instead of the numeric domain.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-time-subtraction.html
+class TimeSubtractionCheck : public ClangTidyCheck {
+public:
+  TimeSubtractionCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  void emitDiagnostic(const Expr* Node, llvm::StringRef Replacement);
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H
diff --git a/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
index 1925f48..9c709d2 100644
--- a/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
+++ b/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UpgradeDurationConversionsCheck.cpp - clang-tidy -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/UpgradeDurationConversionsCheck.h b/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
index 63712e2..b1096a6 100644
--- a/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
+++ b/clang-tidy/abseil/UpgradeDurationConversionsCheck.h
@@ -1,9 +1,8 @@
 //===--- UpgradeDurationConversionsCheck.h - clang-tidy ---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/add_new_check.py b/clang-tidy/add_new_check.py
index f4c518d..8f96cbd 100755
--- a/clang-tidy/add_new_check.py
+++ b/clang-tidy/add_new_check.py
@@ -2,10 +2,9 @@
 #
 #===- add_new_check.py - clang-tidy check generator ----------*- python -*--===#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 
@@ -61,17 +60,16 @@
     f.write('*- C++ -*-===//')
     f.write("""
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef %(header_guard)s
 #define %(header_guard)s
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -112,10 +110,9 @@
     f.write('-===//')
     f.write("""
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -140,7 +137,8 @@
   if (MatchedDecl->getName().startswith("awesome_"))
     return;
   diag(MatchedDecl->getLocation(), "function %%0 is insufficiently awesome")
-      << MatchedDecl
+      << MatchedDecl;
+  diag(MatchedDecl->getLocation(), "insert 'awesome'", DiagnosticIDs::Note)
       << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
 }
 
@@ -201,7 +199,7 @@
     lines = f.readlines()
 
   lineMatcher = re.compile('Improvements to clang-tidy')
-  nextSectionMatcher = re.compile('Improvements to include-fixer')
+  nextSectionMatcher = re.compile('Improvements to clang-include-fixer')
   checkerMatcher = re.compile('- New :doc:`(.*)')
 
   print('Updating %s...' % filename)
diff --git a/clang-tidy/android/AndroidTidyModule.cpp b/clang-tidy/android/AndroidTidyModule.cpp
index bbb4b71..2baa3fb 100644
--- a/clang-tidy/android/AndroidTidyModule.cpp
+++ b/clang-tidy/android/AndroidTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- AndroidTidyModule.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecAccept4Check.cpp b/clang-tidy/android/CloexecAccept4Check.cpp
index 3d172ef..fe1f341 100644
--- a/clang-tidy/android/CloexecAccept4Check.cpp
+++ b/clang-tidy/android/CloexecAccept4Check.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecAccept4Check.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecAccept4Check.h b/clang-tidy/android/CloexecAccept4Check.h
index 0cf3215..21196de 100644
--- a/clang-tidy/android/CloexecAccept4Check.h
+++ b/clang-tidy/android/CloexecAccept4Check.h
@@ -1,9 +1,8 @@
 //===--- CloexecAccept4Check.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecAcceptCheck.cpp b/clang-tidy/android/CloexecAcceptCheck.cpp
index f583bd0..b26ad75 100644
--- a/clang-tidy/android/CloexecAcceptCheck.cpp
+++ b/clang-tidy/android/CloexecAcceptCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecAcceptCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecAcceptCheck.h b/clang-tidy/android/CloexecAcceptCheck.h
index cba1c09..304ac51 100644
--- a/clang-tidy/android/CloexecAcceptCheck.h
+++ b/clang-tidy/android/CloexecAcceptCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecAcceptCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecCheck.cpp b/clang-tidy/android/CloexecCheck.cpp
index 4cc0f61..148839a 100644
--- a/clang-tidy/android/CloexecCheck.cpp
+++ b/clang-tidy/android/CloexecCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecCheck.cpp - clang-tidy-------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecCheck.h b/clang-tidy/android/CloexecCheck.h
index 1c58a31..92cdf78 100644
--- a/clang-tidy/android/CloexecCheck.h
+++ b/clang-tidy/android/CloexecCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecCheck.h - clang-tidy-----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -16,7 +15,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/android/CloexecCreatCheck.cpp b/clang-tidy/android/CloexecCreatCheck.cpp
index 83ca49a..f096884 100644
--- a/clang-tidy/android/CloexecCreatCheck.cpp
+++ b/clang-tidy/android/CloexecCreatCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecCreatCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecCreatCheck.h b/clang-tidy/android/CloexecCreatCheck.h
index 335990c..cb60e25 100644
--- a/clang-tidy/android/CloexecCreatCheck.h
+++ b/clang-tidy/android/CloexecCreatCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecCreatCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecDupCheck.cpp b/clang-tidy/android/CloexecDupCheck.cpp
index ec4ff0a..9a676d1 100644
--- a/clang-tidy/android/CloexecDupCheck.cpp
+++ b/clang-tidy/android/CloexecDupCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecDupCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecDupCheck.h b/clang-tidy/android/CloexecDupCheck.h
index c040b38..e87c0ab 100644
--- a/clang-tidy/android/CloexecDupCheck.h
+++ b/clang-tidy/android/CloexecDupCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecDupCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecEpollCreate1Check.cpp b/clang-tidy/android/CloexecEpollCreate1Check.cpp
index d94b4a0..8fb175e 100644
--- a/clang-tidy/android/CloexecEpollCreate1Check.cpp
+++ b/clang-tidy/android/CloexecEpollCreate1Check.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecEpollCreate1Check.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecEpollCreate1Check.h b/clang-tidy/android/CloexecEpollCreate1Check.h
index 9890d5f..cac2581 100644
--- a/clang-tidy/android/CloexecEpollCreate1Check.h
+++ b/clang-tidy/android/CloexecEpollCreate1Check.h
@@ -1,9 +1,8 @@
 //===--- CloexecEpollCreate1Check.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecEpollCreateCheck.cpp b/clang-tidy/android/CloexecEpollCreateCheck.cpp
index 7165d24..f1d7edf 100644
--- a/clang-tidy/android/CloexecEpollCreateCheck.cpp
+++ b/clang-tidy/android/CloexecEpollCreateCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecEpollCreateCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecEpollCreateCheck.h b/clang-tidy/android/CloexecEpollCreateCheck.h
index 21d2b2a..8db80c8 100644
--- a/clang-tidy/android/CloexecEpollCreateCheck.h
+++ b/clang-tidy/android/CloexecEpollCreateCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecEpollCreateCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecFopenCheck.cpp b/clang-tidy/android/CloexecFopenCheck.cpp
index 33058d6..dc9908b 100644
--- a/clang-tidy/android/CloexecFopenCheck.cpp
+++ b/clang-tidy/android/CloexecFopenCheck.cpp
@@ -1,9 +1,9 @@
 //===--- CloexecFopenCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.  //
 //===----------------------------------------------------------------------===//
 
 #include "CloexecFopenCheck.h"
diff --git a/clang-tidy/android/CloexecFopenCheck.h b/clang-tidy/android/CloexecFopenCheck.h
index 1c82b8b..0b617ff 100644
--- a/clang-tidy/android/CloexecFopenCheck.h
+++ b/clang-tidy/android/CloexecFopenCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecFopenCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source //
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecInotifyInit1Check.cpp b/clang-tidy/android/CloexecInotifyInit1Check.cpp
index ca0aeb8..f0a0b98 100644
--- a/clang-tidy/android/CloexecInotifyInit1Check.cpp
+++ b/clang-tidy/android/CloexecInotifyInit1Check.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecInotifyInit1Check.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecInotifyInit1Check.h b/clang-tidy/android/CloexecInotifyInit1Check.h
index deb04f2..d4a392d 100644
--- a/clang-tidy/android/CloexecInotifyInit1Check.h
+++ b/clang-tidy/android/CloexecInotifyInit1Check.h
@@ -1,9 +1,8 @@
 //===--- CloexecInotifyInit1Check.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecInotifyInitCheck.cpp b/clang-tidy/android/CloexecInotifyInitCheck.cpp
index 0d5a56d..e11cbb8 100644
--- a/clang-tidy/android/CloexecInotifyInitCheck.cpp
+++ b/clang-tidy/android/CloexecInotifyInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecInotifyInitCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecInotifyInitCheck.h b/clang-tidy/android/CloexecInotifyInitCheck.h
index ceeecbe..3b6e057 100644
--- a/clang-tidy/android/CloexecInotifyInitCheck.h
+++ b/clang-tidy/android/CloexecInotifyInitCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecInotifyInitCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecMemfdCreateCheck.cpp b/clang-tidy/android/CloexecMemfdCreateCheck.cpp
index 4820e2b..6fa606b 100644
--- a/clang-tidy/android/CloexecMemfdCreateCheck.cpp
+++ b/clang-tidy/android/CloexecMemfdCreateCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecMemfdCreateCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecMemfdCreateCheck.h b/clang-tidy/android/CloexecMemfdCreateCheck.h
index 0fe96f4..f429ee5 100644
--- a/clang-tidy/android/CloexecMemfdCreateCheck.h
+++ b/clang-tidy/android/CloexecMemfdCreateCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecMemfdCreateCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecOpenCheck.cpp b/clang-tidy/android/CloexecOpenCheck.cpp
index a4d3bc6..d0617a3 100644
--- a/clang-tidy/android/CloexecOpenCheck.cpp
+++ b/clang-tidy/android/CloexecOpenCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecOpenCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecOpenCheck.h b/clang-tidy/android/CloexecOpenCheck.h
index c221087..eb3319c 100644
--- a/clang-tidy/android/CloexecOpenCheck.h
+++ b/clang-tidy/android/CloexecOpenCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecOpenCheck.h - clang-tidy-----------------------------------===//
 //
-//                      The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecSocketCheck.cpp b/clang-tidy/android/CloexecSocketCheck.cpp
index b223918..dd0f624 100644
--- a/clang-tidy/android/CloexecSocketCheck.cpp
+++ b/clang-tidy/android/CloexecSocketCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CloexecSocketCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/CloexecSocketCheck.h b/clang-tidy/android/CloexecSocketCheck.h
index c1fd01f..acbfcea 100644
--- a/clang-tidy/android/CloexecSocketCheck.h
+++ b/clang-tidy/android/CloexecSocketCheck.h
@@ -1,9 +1,8 @@
 //===--- CloexecSocketCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp b/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp
index a98eb8c..f43d949 100644
--- a/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp
+++ b/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ComparisonInTempFailureRetryCheck.cpp - clang-tidy----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/android/ComparisonInTempFailureRetryCheck.h b/clang-tidy/android/ComparisonInTempFailureRetryCheck.h
index de81232..d12c999 100644
--- a/clang-tidy/android/ComparisonInTempFailureRetryCheck.h
+++ b/clang-tidy/android/ComparisonInTempFailureRetryCheck.h
@@ -1,16 +1,15 @@
 //===--- ComparisonInTempFailureRetryCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_COMPARISONINTEMPFAILURERETRYCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_COMPARISONINTEMPFAILURERETRYCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/boost/BoostTidyModule.cpp b/clang-tidy/boost/BoostTidyModule.cpp
index 28eb1d6..4ab22ad 100644
--- a/clang-tidy/boost/BoostTidyModule.cpp
+++ b/clang-tidy/boost/BoostTidyModule.cpp
@@ -1,9 +1,8 @@
 //===------- BoostTidyModule.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/boost/UseToStringCheck.cpp b/clang-tidy/boost/UseToStringCheck.cpp
index 259f3df..29bedcf 100644
--- a/clang-tidy/boost/UseToStringCheck.cpp
+++ b/clang-tidy/boost/UseToStringCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseToStringCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/boost/UseToStringCheck.h b/clang-tidy/boost/UseToStringCheck.h
index 76e7823..058a34c 100644
--- a/clang-tidy/boost/UseToStringCheck.h
+++ b/clang-tidy/boost/UseToStringCheck.h
@@ -1,16 +1,15 @@
 //===--- UseToStringCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BOOST_USE_TO_STRING_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BOOST_USE_TO_STRING_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tidy/bugprone/ArgumentCommentCheck.cpp
index 62f30f7..5d6c7c9 100644
--- a/clang-tidy/bugprone/ArgumentCommentCheck.cpp
+++ b/clang-tidy/bugprone/ArgumentCommentCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ArgumentCommentCheck.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Token.h"
+
 #include "../utils/LexerUtils.h"
 
 using namespace clang::ast_matchers;
@@ -24,17 +24,37 @@
                                            ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0),
+      CommentBoolLiterals(Options.getLocalOrGlobal("CommentBoolLiterals", 0) !=
+                          0),
+      CommentIntegerLiterals(
+          Options.getLocalOrGlobal("CommentIntegerLiterals", 0) != 0),
+      CommentFloatLiterals(
+          Options.getLocalOrGlobal("CommentFloatLiterals", 0) != 0),
+      CommentStringLiterals(
+          Options.getLocalOrGlobal("CommentStringLiterals", 0) != 0),
+      CommentUserDefinedLiterals(
+          Options.getLocalOrGlobal("CommentUserDefinedLiterals", 0) != 0),
+      CommentCharacterLiterals(
+          Options.getLocalOrGlobal("CommentCharacterLiterals", 0) != 0),
+      CommentNullPtrs(Options.getLocalOrGlobal("CommentNullPtrs", 0) != 0),
       IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
 
 void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "StrictMode", StrictMode);
+  Options.store(Opts, "CommentBoolLiterals", CommentBoolLiterals);
+  Options.store(Opts, "CommentIntegerLiterals", CommentIntegerLiterals);
+  Options.store(Opts, "CommentFloatLiterals", CommentFloatLiterals);
+  Options.store(Opts, "CommentStringLiterals", CommentStringLiterals);
+  Options.store(Opts, "CommentUserDefinedLiterals", CommentUserDefinedLiterals);
+  Options.store(Opts, "CommentCharacterLiterals", CommentCharacterLiterals);
+  Options.store(Opts, "CommentNullPtrs", CommentNullPtrs);
 }
 
 void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       callExpr(unless(cxxOperatorCallExpr()),
-               // NewCallback's arguments relate to the pointed function, don't
-               // check them against NewCallback's parameter names.
+               // NewCallback's arguments relate to the pointed function,
+               // don't check them against NewCallback's parameter names.
                // FIXME: Make this configurable.
                unless(hasDeclaration(functionDecl(
                    hasAnyName("NewCallback", "NewPermanentCallback")))))
@@ -127,8 +147,8 @@
 
     const unsigned Threshold = 2;
     // Other parameters must be an edit distance at least Threshold more away
-    // from this parameter. This gives us greater confidence that this is a typo
-    // of this parameter and not one with a similar name.
+    // from this parameter. This gives us greater confidence that this is a
+    // typo of this parameter and not one with a similar name.
     unsigned OtherED = ArgNameLower.edit_distance(II->getName().lower(),
                                                   /*AllowReplacements=*/true,
                                                   ThisED + Threshold);
@@ -181,8 +201,8 @@
     }
     return nullptr;
   }
-  if (const auto *Next = dyn_cast_or_null<CXXMethodDecl>(
-                 Method->getNextDeclInContext())) {
+  if (const auto *Next =
+          dyn_cast_or_null<CXXMethodDecl>(Method->getNextDeclInContext())) {
     if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next))
       return Method;
   }
@@ -207,6 +227,21 @@
   return Func;
 }
 
+// Given the argument type and the options determine if we should
+// be adding an argument comment.
+bool ArgumentCommentCheck::shouldAddComment(const Expr *Arg) const {
+  if (Arg->getExprLoc().isMacroID())
+    return false;
+  Arg = Arg->IgnoreImpCasts();
+  return (CommentBoolLiterals && isa<CXXBoolLiteralExpr>(Arg)) ||
+         (CommentIntegerLiterals && isa<IntegerLiteral>(Arg)) ||
+         (CommentFloatLiterals && isa<FloatingLiteral>(Arg)) ||
+         (CommentUserDefinedLiterals && isa<UserDefinedLiteral>(Arg)) ||
+         (CommentCharacterLiterals && isa<CharacterLiteral>(Arg)) ||
+         (CommentStringLiterals && isa<StringLiteral>(Arg)) ||
+         (CommentNullPtrs && isa<CXXNullPtrLiteralExpr>(Arg));
+}
+
 void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
                                          const FunctionDecl *OriginalCallee,
                                          SourceLocation ArgBeginLoc,
@@ -220,7 +255,7 @@
   if (NumArgs == 0)
     return;
 
-  auto makeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) {
+  auto MakeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) {
     return Lexer::makeFileCharRange(CharSourceRange::getCharRange(Begin, End),
                                     Ctx->getSourceManager(),
                                     Ctx->getLangOpts());
@@ -243,7 +278,7 @@
     }
 
     CharSourceRange BeforeArgument =
-        makeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc());
+        MakeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc());
     ArgBeginLoc = Args[I]->getEndLoc();
 
     std::vector<std::pair<SourceLocation, StringRef>> Comments;
@@ -251,7 +286,7 @@
       Comments = getCommentsInRange(Ctx, BeforeArgument);
     } else {
       // Fall back to parsing back from the start of the argument.
-      CharSourceRange ArgsRange = makeFileCharRange(
+      CharSourceRange ArgsRange = MakeFileCharRange(
           Args[I]->getBeginLoc(), Args[NumArgs - 1]->getEndLoc());
       Comments = getCommentsBeforeLoc(Ctx, ArgsRange.getBegin());
     }
@@ -278,8 +313,19 @@
         }
       }
     }
+
+    // If the argument comments are missing for literals add them.
+    if (Comments.empty() && shouldAddComment(Args[I])) {
+      std::string ArgComment =
+          (llvm::Twine("/*") + II->getName() + "=*/").str();
+      DiagnosticBuilder Diag =
+          diag(Args[I]->getBeginLoc(),
+               "argument comment missing for literal argument %0")
+          << II
+          << FixItHint::CreateInsertion(Args[I]->getBeginLoc(), ArgComment);
+    }
   }
-}
+} // namespace bugprone
 
 void ArgumentCommentCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *E = Result.Nodes.getNodeAs<Expr>("expr");
diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.h b/clang-tidy/bugprone/ArgumentCommentCheck.h
index 2f5a751..216d92c 100644
--- a/clang-tidy/bugprone/ArgumentCommentCheck.h
+++ b/clang-tidy/bugprone/ArgumentCommentCheck.h
@@ -1,16 +1,15 @@
 //===--- ArgumentCommentCheck.h - clang-tidy --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_ARGUMENTCOMMENTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_ARGUMENTCOMMENTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/Support/Regex.h"
 
 namespace clang {
@@ -27,7 +26,8 @@
 ///
 ///   ...
 ///   f(/*bar=*/true);
-///   // warning: argument name 'bar' in comment does not match parameter name 'foo'
+///   // warning: argument name 'bar' in comment does not match parameter name
+///   'foo'
 /// \endcode
 ///
 /// The check tries to detect typos and suggest automated fixes for them.
@@ -40,12 +40,21 @@
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
 
 private:
-  const bool StrictMode;
+  const unsigned StrictMode : 1;
+  const unsigned CommentBoolLiterals : 1;
+  const unsigned CommentIntegerLiterals : 1;
+  const unsigned CommentFloatLiterals : 1;
+  const unsigned CommentStringLiterals : 1;
+  const unsigned CommentUserDefinedLiterals : 1;
+  const unsigned CommentCharacterLiterals : 1;
+  const unsigned CommentNullPtrs : 1;
   llvm::Regex IdentRE;
 
   void checkCallArgs(ASTContext *Ctx, const FunctionDecl *Callee,
                      SourceLocation ArgBeginLoc,
                      llvm::ArrayRef<const Expr *> Args);
+
+  bool shouldAddComment(const Expr *Arg) const;
 };
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tidy/bugprone/AssertSideEffectCheck.cpp
index c747980..a28ef11 100644
--- a/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AssertSideEffectCheck.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/AssertSideEffectCheck.h b/clang-tidy/bugprone/AssertSideEffectCheck.h
index 0f386c9..15d1a69 100644
--- a/clang-tidy/bugprone/AssertSideEffectCheck.h
+++ b/clang-tidy/bugprone/AssertSideEffectCheck.h
@@ -1,16 +1,15 @@
 //===--- AssertSideEffectCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_ASSERTSIDEEFFECTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_ASSERTSIDEEFFECTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
diff --git a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
index 675322d..b7f5b0d 100644
--- a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
+++ b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- BoolPointerImplicitConversionCheck.cpp - clang-tidy --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h
index b3416a9..2eed471 100644
--- a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h
+++ b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h
@@ -1,16 +1,15 @@
 //===--- BoolPointerImplicitConversionCheck.h - clang-tidy ------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BOOLPOINTERIMPLICITCONVERSIONCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BOOLPOINTERIMPLICITCONVERSIONCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tidy/bugprone/BugproneTidyModule.cpp
index beb58f5..01bc0e5 100644
--- a/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- BugproneTidyModule.cpp - clang-tidy ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/CopyConstructorInitCheck.cpp b/clang-tidy/bugprone/CopyConstructorInitCheck.cpp
index f048825..5ae7999 100644
--- a/clang-tidy/bugprone/CopyConstructorInitCheck.cpp
+++ b/clang-tidy/bugprone/CopyConstructorInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- CopyConstructorInitCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/CopyConstructorInitCheck.h b/clang-tidy/bugprone/CopyConstructorInitCheck.h
index 4d13da4..648aa42 100644
--- a/clang-tidy/bugprone/CopyConstructorInitCheck.h
+++ b/clang-tidy/bugprone/CopyConstructorInitCheck.h
@@ -1,16 +1,15 @@
 //===--- CopyConstructorInitCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_COPY_CONSTRUCTOR_INIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_COPY_CONSTRUCTOR_INIT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tidy/bugprone/DanglingHandleCheck.cpp
index 81b799e..74ad2e7 100644
--- a/clang-tidy/bugprone/DanglingHandleCheck.cpp
+++ b/clang-tidy/bugprone/DanglingHandleCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -164,9 +163,8 @@
 
   // Return a temporary.
   Finder->addMatcher(
-      returnStmt(
-          has(ignoringParenImpCasts(exprWithCleanups(has(ignoringParenImpCasts(
-              handleFrom(IsAHandle, handleFromTemporaryValue(IsAHandle))))))))
+      returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom(
+                     IsAHandle, handleFromTemporaryValue(IsAHandle)))))))
           .bind("bad_stmt"),
       this);
 }
diff --git a/clang-tidy/bugprone/DanglingHandleCheck.h b/clang-tidy/bugprone/DanglingHandleCheck.h
index add8d42..650522d 100644
--- a/clang-tidy/bugprone/DanglingHandleCheck.h
+++ b/clang-tidy/bugprone/DanglingHandleCheck.h
@@ -1,16 +1,15 @@
 //===--- DanglingHandleCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DANGLING_HANDLE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DANGLING_HANDLE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp
index 3c8a6c5..951c6f1 100644
--- a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp
+++ b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp
@@ -1,9 +1,8 @@
-//===--- ExceptionEscapeCheck.cpp - clang-tidy-----------------------------===//
+//===--- ExceptionEscapeCheck.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,158 +10,21 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
-
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringSet.h"
 
 using namespace clang::ast_matchers;
 
-namespace {
-typedef llvm::SmallVector<const clang::Type *, 8> TypeVec;
-} // namespace
-
 namespace clang {
-
-static bool isBaseOf(const Type *DerivedType, const Type *BaseType) {
-  const auto *DerivedClass = DerivedType->getAsCXXRecordDecl();
-  const auto *BaseClass = BaseType->getAsCXXRecordDecl();
-  if (!DerivedClass || !BaseClass)
-    return false;
-
-  return !DerivedClass->forallBases(
-      [BaseClass](const CXXRecordDecl *Cur) { return Cur != BaseClass; });
-}
-
-static const TypeVec
-throwsException(const Stmt *St, const TypeVec &Caught,
-                llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
-
-static const TypeVec
-throwsException(const FunctionDecl *Func,
-                llvm::SmallSet<const FunctionDecl *, 32> &CallStack) {
-  if (CallStack.count(Func))
-    return TypeVec();
-
-  if (const Stmt *Body = Func->getBody()) {
-    CallStack.insert(Func);
-    const TypeVec Result = throwsException(Body, TypeVec(), CallStack);
-    CallStack.erase(Func);
-    return Result;
-  }
-
-  TypeVec Result;
-  if (const auto *FPT = Func->getType()->getAs<FunctionProtoType>()) {
-    for (const QualType Ex : FPT->exceptions()) {
-      Result.push_back(Ex.getTypePtr());
-    }
-  }
-  return Result;
-}
-
-static const TypeVec
-throwsException(const Stmt *St, const TypeVec &Caught,
-                llvm::SmallSet<const FunctionDecl *, 32> &CallStack) {
-  TypeVec Results;
-
-  if (!St)
-    return Results;
-
-  if (const auto *Throw = dyn_cast<CXXThrowExpr>(St)) {
-    if (const auto *ThrownExpr = Throw->getSubExpr()) {
-      const auto *ThrownType =
-          ThrownExpr->getType()->getUnqualifiedDesugaredType();
-      if (ThrownType->isReferenceType()) {
-        ThrownType = ThrownType->castAs<ReferenceType>()
-                         ->getPointeeType()
-                         ->getUnqualifiedDesugaredType();
-      }
-      if (const auto *TD = ThrownType->getAsTagDecl()) {
-        if (TD->getDeclName().isIdentifier() && TD->getName() == "bad_alloc"
-            && TD->isInStdNamespace())
-          return Results;
-      }
-      Results.push_back(ThrownExpr->getType()->getUnqualifiedDesugaredType());
-    } else {
-      Results.append(Caught.begin(), Caught.end());
-    }
-  } else if (const auto *Try = dyn_cast<CXXTryStmt>(St)) {
-    TypeVec Uncaught = throwsException(Try->getTryBlock(), Caught, CallStack);
-    for (unsigned i = 0; i < Try->getNumHandlers(); ++i) {
-      const CXXCatchStmt *Catch = Try->getHandler(i);
-      if (!Catch->getExceptionDecl()) {
-        const TypeVec Rethrown =
-            throwsException(Catch->getHandlerBlock(), Uncaught, CallStack);
-        Results.append(Rethrown.begin(), Rethrown.end());
-        Uncaught.clear();
-      } else {
-        const auto *CaughtType =
-            Catch->getCaughtType()->getUnqualifiedDesugaredType();
-        if (CaughtType->isReferenceType()) {
-          CaughtType = CaughtType->castAs<ReferenceType>()
-                           ->getPointeeType()
-                           ->getUnqualifiedDesugaredType();
-        }
-        auto NewEnd =
-            llvm::remove_if(Uncaught, [&CaughtType](const Type *ThrownType) {
-              return ThrownType == CaughtType ||
-                     isBaseOf(ThrownType, CaughtType);
-            });
-        if (NewEnd != Uncaught.end()) {
-          Uncaught.erase(NewEnd, Uncaught.end());
-          const TypeVec Rethrown = throwsException(
-              Catch->getHandlerBlock(), TypeVec(1, CaughtType), CallStack);
-          Results.append(Rethrown.begin(), Rethrown.end());
-        }
-      }
-    }
-    Results.append(Uncaught.begin(), Uncaught.end());
-  } else if (const auto *Call = dyn_cast<CallExpr>(St)) {
-    if (const FunctionDecl *Func = Call->getDirectCallee()) {
-      TypeVec Excs = throwsException(Func, CallStack);
-      Results.append(Excs.begin(), Excs.end());
-    }
-  } else {
-    for (const Stmt *Child : St->children()) {
-      TypeVec Excs = throwsException(Child, Caught, CallStack);
-      Results.append(Excs.begin(), Excs.end());
-    }
-  }
-  return Results;
-}
-
-static const TypeVec throwsException(const FunctionDecl *Func) {
-  llvm::SmallSet<const FunctionDecl *, 32> CallStack;
-  return throwsException(Func, CallStack);
-}
-
-namespace ast_matchers {
-AST_MATCHER_P(FunctionDecl, throws, internal::Matcher<Type>, InnerMatcher) {
-  TypeVec ExceptionList = throwsException(&Node);
-  auto NewEnd = llvm::remove_if(
-      ExceptionList, [this, Finder, Builder](const Type *Exception) {
-        return !InnerMatcher.matches(*Exception, Finder, Builder);
-      });
-  ExceptionList.erase(NewEnd, ExceptionList.end());
-  return ExceptionList.size();
-}
-
-AST_MATCHER_P(Type, isIgnored, llvm::StringSet<>, IgnoredExceptions) {
-  if (const auto *TD = Node.getAsTagDecl()) {
-    if (TD->getDeclName().isIdentifier())
-      return IgnoredExceptions.count(TD->getName()) > 0;
-  }
-  return false;
-}
-
+namespace {
 AST_MATCHER_P(FunctionDecl, isEnabled, llvm::StringSet<>,
               FunctionsThatShouldNotThrow) {
   return FunctionsThatShouldNotThrow.count(Node.getNameAsString()) > 0;
 }
-} // namespace ast_matchers
+} // namespace
 
 namespace tidy {
 namespace bugprone {
-
 ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name,
                                            ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context), RawFunctionsThatShouldNotThrow(Options.get(
@@ -174,9 +36,13 @@
       .split(FunctionsThatShouldNotThrowVec, ",", -1, false);
   FunctionsThatShouldNotThrow.insert(FunctionsThatShouldNotThrowVec.begin(),
                                      FunctionsThatShouldNotThrowVec.end());
+
+  llvm::StringSet<> IgnoredExceptions;
   StringRef(RawIgnoredExceptions).split(IgnoredExceptionsVec, ",", -1, false);
   IgnoredExceptions.insert(IgnoredExceptionsVec.begin(),
                            IgnoredExceptionsVec.end());
+  Tracer.ignoreExceptions(std::move(IgnoredExceptions));
+  Tracer.ignoreBadAlloc(true);
 }
 
 void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
@@ -194,22 +60,26 @@
                          cxxConstructorDecl(isMoveConstructor()),
                          cxxMethodDecl(isMoveAssignmentOperator()),
                          hasName("main"), hasName("swap"),
-                         isEnabled(FunctionsThatShouldNotThrow)),
-                   throws(unless(isIgnored(IgnoredExceptions))))
+                         isEnabled(FunctionsThatShouldNotThrow)))
           .bind("thrower"),
       this);
 }
 
 void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) {
-  const FunctionDecl *MatchedDecl =
-      Result.Nodes.getNodeAs<FunctionDecl>("thrower");
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("thrower");
+
   if (!MatchedDecl)
     return;
 
-  // FIXME: We should provide more information about the exact location where
-  // the exception is thrown, maybe the full path the exception escapes
-  diag(MatchedDecl->getLocation(), "an exception may be thrown in function %0 "
-       "which should not throw exceptions") << MatchedDecl;
+  if (Tracer.analyze(MatchedDecl).getBehaviour() ==
+      utils::ExceptionAnalyzer::State::Throwing)
+    // FIXME: We should provide more information about the exact location where
+    // the exception is thrown, maybe the full path the exception escapes
+    diag(MatchedDecl->getLocation(),
+         "an exception may be thrown in function %0 "
+
+         "which should not throw exceptions")
+        << MatchedDecl;
 }
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.h b/clang-tidy/bugprone/ExceptionEscapeCheck.h
index d690022..85bb713 100644
--- a/clang-tidy/bugprone/ExceptionEscapeCheck.h
+++ b/clang-tidy/bugprone/ExceptionEscapeCheck.h
@@ -1,17 +1,16 @@
-//===--- ExceptionEscapeCheck.h - clang-tidy---------------------*- C++ -*-===//
+//===--- ExceptionEscapeCheck.h - clang-tidy --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_ESCAPE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_ESCAPE_H
 
-#include "../ClangTidy.h"
-
+#include "../ClangTidyCheck.h"
+#include "../utils/ExceptionAnalyzer.h"
 #include "llvm/ADT/StringSet.h"
 
 namespace clang {
@@ -37,7 +36,7 @@
   std::string RawIgnoredExceptions;
 
   llvm::StringSet<> FunctionsThatShouldNotThrow;
-  llvm::StringSet<> IgnoredExceptions;
+  utils::ExceptionAnalyzer Tracer;
 };
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/FoldInitTypeCheck.cpp b/clang-tidy/bugprone/FoldInitTypeCheck.cpp
index 6d7fd28..e77c981 100644
--- a/clang-tidy/bugprone/FoldInitTypeCheck.cpp
+++ b/clang-tidy/bugprone/FoldInitTypeCheck.cpp
@@ -1,9 +1,8 @@
 //===--- FoldInitTypeCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/FoldInitTypeCheck.h b/clang-tidy/bugprone/FoldInitTypeCheck.h
index e6170de..926b9e8 100644
--- a/clang-tidy/bugprone/FoldInitTypeCheck.h
+++ b/clang-tidy/bugprone/FoldInitTypeCheck.h
@@ -1,16 +1,15 @@
 //===--- FoldInitTypeCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FOLD_INIT_TYPE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FOLD_INIT_TYPE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 9ea5b55..a03f860 100644
--- a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ForwardDeclarationNamespaceCheck.cpp - clang-tidy ------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h
index c3d3018..cd07a94 100644
--- a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h
+++ b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h
@@ -1,16 +1,15 @@
 //===--- ForwardDeclarationNamespaceCheck.h - clang-tidy --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FORWARDDECLARATIONNAMESPACECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FORWARDDECLARATIONNAMESPACECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include <set>
 #include <vector>
diff --git a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 17bdc76..57055ff 100644
--- a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ForwardingReferenceOverloadCheck.cpp - clang-tidy-----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h
index 4b00ab2..a27156c 100644
--- a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h
+++ b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h
@@ -1,16 +1,15 @@
 //===--- ForwardingReferenceOverloadCheck.h - clang-tidy---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FORWARDINGREFERENCEOVERLOADCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_FORWARDINGREFERENCEOVERLOADCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tidy/bugprone/InaccurateEraseCheck.cpp
index c1e65b5..95babc7 100644
--- a/clang-tidy/bugprone/InaccurateEraseCheck.cpp
+++ b/clang-tidy/bugprone/InaccurateEraseCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InaccurateEraseCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -18,10 +17,6 @@
 namespace tidy {
 namespace bugprone {
 
-namespace {
-AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
-}
-
 void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
   // Only register the matchers for C++; the functionality currently does not
   // provide any benefit to other languages, despite being benign.
diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.h b/clang-tidy/bugprone/InaccurateEraseCheck.h
index d6b3729..93ea239 100644
--- a/clang-tidy/bugprone/InaccurateEraseCheck.h
+++ b/clang-tidy/bugprone/InaccurateEraseCheck.h
@@ -1,16 +1,15 @@
 //===--- InaccurateEraseCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INACCURATEERASECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INACCURATEERASECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp b/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
index 549799f..bc58e8e 100644
--- a/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
+++ b/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IncorrectRoundingsCheck.cpp - clang-tidy ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/IncorrectRoundingsCheck.h b/clang-tidy/bugprone/IncorrectRoundingsCheck.h
index b1886fd..436472f 100644
--- a/clang-tidy/bugprone/IncorrectRoundingsCheck.h
+++ b/clang-tidy/bugprone/IncorrectRoundingsCheck.h
@@ -1,16 +1,15 @@
 //===--- IncorrectRoundingsCheck.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCORRECTROUNDINGSCHECK_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCORRECTROUNDINGSCHECK_H_
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/IntegerDivisionCheck.cpp b/clang-tidy/bugprone/IntegerDivisionCheck.cpp
index 094d991..670efe2 100644
--- a/clang-tidy/bugprone/IntegerDivisionCheck.cpp
+++ b/clang-tidy/bugprone/IntegerDivisionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IntegerDivisionCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/IntegerDivisionCheck.h b/clang-tidy/bugprone/IntegerDivisionCheck.h
index 307e493..6d2fb79 100644
--- a/clang-tidy/bugprone/IntegerDivisionCheck.h
+++ b/clang-tidy/bugprone/IntegerDivisionCheck.h
@@ -1,16 +1,15 @@
 //===--- IntegerDivisionCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INTEGER_DIVISION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INTEGER_DIVISION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
index bdb769d..cc8cb3b 100644
--- a/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
+++ b/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
@@ -1,9 +1,8 @@
 //===--- LambdaFunctionNameCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -65,10 +64,10 @@
                      this);
 }
 
-void LambdaFunctionNameCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<MacroExpansionsWithFileAndLine>(
-          &SuppressMacroExpansions));
+void LambdaFunctionNameCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(llvm::make_unique<MacroExpansionsWithFileAndLine>(
+      &SuppressMacroExpansions));
 }
 
 void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.h b/clang-tidy/bugprone/LambdaFunctionNameCheck.h
index b7b1b44..d36ed46 100644
--- a/clang-tidy/bugprone/LambdaFunctionNameCheck.h
+++ b/clang-tidy/bugprone/LambdaFunctionNameCheck.h
@@ -1,16 +1,15 @@
 //===--- LambdaFunctionNameCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_LAMBDAFUNCTIONNAMECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_LAMBDAFUNCTIONNAMECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -37,7 +36,8 @@
   LambdaFunctionNameCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.cpp b/clang-tidy/bugprone/MacroParenthesesCheck.cpp
index 6846bc2..874cd47 100644
--- a/clang-tidy/bugprone/MacroParenthesesCheck.cpp
+++ b/clang-tidy/bugprone/MacroParenthesesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MacroParenthesesCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -249,10 +248,9 @@
   }
 }
 
-void MacroParenthesesCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<MacroParenthesesPPCallbacks>(
-          &Compiler.getPreprocessor(), this));
+void MacroParenthesesCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(llvm::make_unique<MacroParenthesesPPCallbacks>(PP, this));
 }
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.h b/clang-tidy/bugprone/MacroParenthesesCheck.h
index 383a6cc..8b6edaa 100644
--- a/clang-tidy/bugprone/MacroParenthesesCheck.h
+++ b/clang-tidy/bugprone/MacroParenthesesCheck.h
@@ -1,16 +1,15 @@
 //===--- MacroParenthesesCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MACROPARENTHESESCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MACROPARENTHESESCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -33,7 +32,8 @@
 public:
   MacroParenthesesCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp
index 30c770e..ee70346 100644
--- a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp
+++ b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MacroRepeatedSideEffectsCheck.cpp - clang-tidy--------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -173,10 +172,8 @@
 }
 
 void MacroRepeatedSideEffectsCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      ::llvm::make_unique<MacroRepeatedPPCallbacks>(
-          *this, Compiler.getPreprocessor()));
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(::llvm::make_unique<MacroRepeatedPPCallbacks>(*this, *PP));
 }
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
index a2a3134..0189c7a 100644
--- a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
+++ b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
@@ -1,16 +1,15 @@
 //===--- MacroRepeatedSideEffectsCheck.h - clang-tidy -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MACROREPEATEDSIDEEFFECTSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MACROREPEATEDSIDEEFFECTSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -21,7 +20,8 @@
 public:
   MacroRepeatedSideEffectsCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
index 83ddbcf..3e6f9fd 100644
--- a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
+++ b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MisplacedOperatorInStrlenInAllocCheck.cpp - clang-tidy------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h
index 99cfcfb..0eb1b43 100644
--- a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h
+++ b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h
@@ -1,16 +1,15 @@
 //===--- MisplacedOperatorInStrlenInAllocCheck.h - clang-tidy----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MISPLACED_OPERATOR_IN_STRLEN_IN_ALLOC_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MISPLACED_OPERATOR_IN_STRLEN_IN_ALLOC_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp b/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
index 46fbd2b..98a1a0c 100644
--- a/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
+++ b/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MisplacedWideningCastCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MisplacedWideningCastCheck.h b/clang-tidy/bugprone/MisplacedWideningCastCheck.h
index b61556f..a1b3737 100644
--- a/clang-tidy/bugprone/MisplacedWideningCastCheck.h
+++ b/clang-tidy/bugprone/MisplacedWideningCastCheck.h
@@ -1,16 +1,15 @@
 //===--- MisplacedWideningCastCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MISPLACEDWIDENINGCASTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MISPLACEDWIDENINGCASTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index f75a194..bf6f2f6 100644
--- a/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MoveForwardingReferenceCheck.cpp - clang-tidy --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MoveForwardingReferenceCheck.h b/clang-tidy/bugprone/MoveForwardingReferenceCheck.h
index c61de75..2ed08cb 100644
--- a/clang-tidy/bugprone/MoveForwardingReferenceCheck.h
+++ b/clang-tidy/bugprone/MoveForwardingReferenceCheck.h
@@ -1,16 +1,15 @@
 //===--- MoveForwardingReferenceCheck.h - clang-tidy ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MOVEFORWARDINGREFERENCECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MOVEFORWARDINGREFERENCECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp b/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp
index 5c49821..5cc7feb 100644
--- a/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp
+++ b/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MultipleStatementMacroCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MultipleStatementMacroCheck.h b/clang-tidy/bugprone/MultipleStatementMacroCheck.h
index efc6599..72823d3 100644
--- a/clang-tidy/bugprone/MultipleStatementMacroCheck.h
+++ b/clang-tidy/bugprone/MultipleStatementMacroCheck.h
@@ -1,16 +1,15 @@
 //===--- MultipleStatementMacroCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MULTIPLE_STATEMENT_MACRO_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_MULTIPLE_STATEMENT_MACRO_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.cpp b/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
index a5293b1..b2f5142 100755
--- a/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
+++ b/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ParentVirtualCallCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.h b/clang-tidy/bugprone/ParentVirtualCallCheck.h
index 08c3aef..ade8017 100755
--- a/clang-tidy/bugprone/ParentVirtualCallCheck.h
+++ b/clang-tidy/bugprone/ParentVirtualCallCheck.h
@@ -1,16 +1,15 @@
 //===--- ParentVirtualCallCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_PARENTVIRTUALCALLCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_PARENTVIRTUALCALLCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SizeofContainerCheck.cpp b/clang-tidy/bugprone/SizeofContainerCheck.cpp
index f7d63b1..411fe8d 100644
--- a/clang-tidy/bugprone/SizeofContainerCheck.cpp
+++ b/clang-tidy/bugprone/SizeofContainerCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SizeofContainerCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SizeofContainerCheck.h b/clang-tidy/bugprone/SizeofContainerCheck.h
index 76b82b0..c74b755 100644
--- a/clang-tidy/bugprone/SizeofContainerCheck.h
+++ b/clang-tidy/bugprone/SizeofContainerCheck.h
@@ -1,16 +1,15 @@
 //===--- SizeofContainerCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIZEOFCONTAINERCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIZEOFCONTAINERCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index d662657..fb16195 100644
--- a/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SizeofExpressionCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -85,8 +84,11 @@
   const auto IntegerCallExpr = expr(ignoringParenImpCasts(
       callExpr(anyOf(hasType(isInteger()), hasType(enumType())),
                unless(isInTemplateInstantiation()))));
-  const auto SizeOfExpr =
-      expr(anyOf(sizeOfExpr(has(type())), sizeOfExpr(has(expr()))));
+  const auto SizeOfExpr = expr(anyOf(
+      sizeOfExpr(
+          has(hasUnqualifiedDesugaredType(type().bind("sizeof-arg-type")))),
+      sizeOfExpr(has(expr(hasType(
+          hasUnqualifiedDesugaredType(type().bind("sizeof-arg-type"))))))));
   const auto SizeOfZero = expr(
       sizeOfExpr(has(ignoringParenImpCasts(expr(integerLiteral(equals(0)))))));
 
@@ -210,6 +212,36 @@
                hasSizeOfDescendant(8, expr(SizeOfExpr, unless(SizeOfZero))))))))
           .bind("sizeof-sizeof-expr"),
       this);
+
+  // Detect sizeof in pointer aritmetic like: N * sizeof(S) == P1 - P2 or
+  // (P1 - P2) / sizeof(S) where P1 and P2 are pointers to type S.
+  const auto PtrDiffExpr = binaryOperator(
+      hasOperatorName("-"),
+      hasLHS(expr(hasType(hasUnqualifiedDesugaredType(pointerType(pointee(
+          hasUnqualifiedDesugaredType(type().bind("left-ptr-type")))))))),
+      hasRHS(expr(hasType(hasUnqualifiedDesugaredType(pointerType(pointee(
+          hasUnqualifiedDesugaredType(type().bind("right-ptr-type")))))))));
+
+  Finder->addMatcher(
+      binaryOperator(
+          anyOf(hasOperatorName("=="), hasOperatorName("!="),
+                hasOperatorName("<"), hasOperatorName("<="),
+                hasOperatorName(">"), hasOperatorName(">="),
+                hasOperatorName("+"), hasOperatorName("-")),
+          hasEitherOperand(expr(anyOf(
+              ignoringParenImpCasts(SizeOfExpr),
+              ignoringParenImpCasts(binaryOperator(
+                  hasOperatorName("*"),
+                  hasEitherOperand(ignoringParenImpCasts(SizeOfExpr))))))),
+          hasEitherOperand(ignoringParenImpCasts(PtrDiffExpr)))
+          .bind("sizeof-in-ptr-arithmetic-mul"),
+      this);
+
+  Finder->addMatcher(binaryOperator(hasOperatorName("/"),
+                                    hasLHS(ignoringParenImpCasts(PtrDiffExpr)),
+                                    hasRHS(ignoringParenImpCasts(SizeOfExpr)))
+                         .bind("sizeof-in-ptr-arithmetic-div"),
+                     this);
 }
 
 void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
@@ -276,6 +308,26 @@
   } else if (const auto *E =
                  Result.Nodes.getNodeAs<Expr>("sizeof-multiply-sizeof")) {
     diag(E->getBeginLoc(), "suspicious 'sizeof' by 'sizeof' multiplication");
+  } else if (const auto *E =
+                 Result.Nodes.getNodeAs<Expr>("sizeof-in-ptr-arithmetic-mul")) {
+    const auto *LPtrTy = Result.Nodes.getNodeAs<Type>("left-ptr-type");
+    const auto *RPtrTy = Result.Nodes.getNodeAs<Type>("right-ptr-type");
+    const auto *SizeofArgTy = Result.Nodes.getNodeAs<Type>("sizeof-arg-type");
+
+    if ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+      diag(E->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
+                              "pointer arithmetic");
+    }
+  } else if (const auto *E =
+                 Result.Nodes.getNodeAs<Expr>("sizeof-in-ptr-arithmetic-div")) {
+    const auto *LPtrTy = Result.Nodes.getNodeAs<Type>("left-ptr-type");
+    const auto *RPtrTy = Result.Nodes.getNodeAs<Type>("right-ptr-type");
+    const auto *SizeofArgTy = Result.Nodes.getNodeAs<Type>("sizeof-arg-type");
+
+    if ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+      diag(E->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
+                              "pointer arithmetic");
+    }
   }
 }
 
diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.h b/clang-tidy/bugprone/SizeofExpressionCheck.h
index 8e14c31..90d8122 100644
--- a/clang-tidy/bugprone/SizeofExpressionCheck.h
+++ b/clang-tidy/bugprone/SizeofExpressionCheck.h
@@ -1,16 +1,15 @@
 //===--- SizeofExpressionCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIZEOFEXPRESSIONCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SIZEOFEXPRESSIONCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tidy/bugprone/StringConstructorCheck.cpp
index cc6e297..a4b83ad 100644
--- a/clang-tidy/bugprone/StringConstructorCheck.cpp
+++ b/clang-tidy/bugprone/StringConstructorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StringConstructorCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -139,7 +138,8 @@
     }
   } else if (const auto *Ptr = Result.Nodes.getNodeAs<Expr>("from-ptr")) {
     Expr::EvalResult ConstPtr;
-    if (Ptr->EvaluateAsRValue(ConstPtr, Ctx) &&
+    if (!Ptr->isInstantiationDependent() &&
+        Ptr->EvaluateAsRValue(ConstPtr, Ctx) &&
         ((ConstPtr.Val.isInt() && ConstPtr.Val.getInt().isNullValue()) ||
          (ConstPtr.Val.isLValue() && ConstPtr.Val.isNullPointer()))) {
       diag(Loc, "constructing string from nullptr is undefined behaviour");
diff --git a/clang-tidy/bugprone/StringConstructorCheck.h b/clang-tidy/bugprone/StringConstructorCheck.h
index 52e9791..e7b4c87 100644
--- a/clang-tidy/bugprone/StringConstructorCheck.h
+++ b/clang-tidy/bugprone/StringConstructorCheck.h
@@ -1,16 +1,15 @@
 //===--- StringConstructorCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRING_CONSTRUCTOR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRING_CONSTRUCTOR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp
index f49a570..c64b5f3 100644
--- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp
+++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StringIntegerAssignmentCheck.cpp - clang-tidy---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,20 +26,121 @@
                 hasOverloadedOperatorName("+=")),
           callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl(
               hasName("::std::basic_string"),
-              hasTemplateArgument(0, refersToType(qualType().bind("type"))))))),
-          hasArgument(1,
-                      ignoringImpCasts(expr(hasType(isInteger()),
-                                            unless(hasType(isAnyCharacter())))
-                                           .bind("expr"))),
+              hasTemplateArgument(0, refersToType(hasCanonicalType(
+                                         qualType().bind("type")))))))),
+          hasArgument(
+              1,
+              ignoringImpCasts(
+                  expr(hasType(isInteger()), unless(hasType(isAnyCharacter())),
+                       // Ignore calls to tolower/toupper (see PR27723).
+                       unless(callExpr(callee(functionDecl(
+                           hasAnyName("tolower", "std::tolower", "toupper",
+                                      "std::toupper"))))),
+                       // Do not warn if assigning e.g. `CodePoint` to
+                       // `basic_string<CodePoint>`
+                       unless(hasType(qualType(
+                           hasCanonicalType(equalsBoundNode("type"))))))
+                      .bind("expr"))),
           unless(isInTemplateInstantiation())),
       this);
 }
 
+class CharExpressionDetector {
+public:
+  CharExpressionDetector(QualType CharType, const ASTContext &Ctx)
+      : CharType(CharType), Ctx(Ctx) {}
+
+  bool isLikelyCharExpression(const Expr *E) const {
+    if (isCharTyped(E))
+      return true;
+
+    if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
+      const auto *LHS = BinOp->getLHS()->IgnoreParenImpCasts();
+      const auto *RHS = BinOp->getRHS()->IgnoreParenImpCasts();
+      // Handle both directions, e.g. `'a' + (i % 26)` and `(i % 26) + 'a'`.
+      if (BinOp->isAdditiveOp() || BinOp->isBitwiseOp())
+        return handleBinaryOp(BinOp->getOpcode(), LHS, RHS) ||
+               handleBinaryOp(BinOp->getOpcode(), RHS, LHS);
+      // Except in the case of '%'.
+      if (BinOp->getOpcode() == BO_Rem)
+        return handleBinaryOp(BinOp->getOpcode(), LHS, RHS);
+      return false;
+    }
+
+    // Ternary where at least one branch is a likely char expression, e.g.
+    //    i < 265 ? i : ' '
+    if (const auto *CondOp = dyn_cast<AbstractConditionalOperator>(E))
+      return isLikelyCharExpression(
+                 CondOp->getFalseExpr()->IgnoreParenImpCasts()) ||
+             isLikelyCharExpression(
+                 CondOp->getTrueExpr()->IgnoreParenImpCasts());
+    return false;
+  }
+
+private:
+  bool handleBinaryOp(clang::BinaryOperatorKind Opcode, const Expr *const LHS,
+                      const Expr *const RHS) const {
+    // <char_expr> <op> <char_expr> (c++ integer promotion rules make this an
+    // int), e.g.
+    //    'a' + c
+    if (isCharTyped(LHS) && isCharTyped(RHS))
+      return true;
+
+    // <expr> & <char_valued_constant> or <expr> % <char_valued_constant>, e.g.
+    //    i & 0xff
+    if ((Opcode == BO_And || Opcode == BO_Rem) && isCharValuedConstant(RHS))
+      return true;
+
+    // <char_expr> | <char_valued_constant>, e.g.
+    //    c | 0x80
+    if (Opcode == BO_Or && isCharTyped(LHS) && isCharValuedConstant(RHS))
+      return true;
+
+    // <char_constant> + <likely_char_expr>, e.g.
+    //    'a' + (i % 26)
+    if (Opcode == BO_Add)
+      return isCharConstant(LHS) && isLikelyCharExpression(RHS);
+
+    return false;
+  }
+
+  // Returns true if `E` is an character constant.
+  bool isCharConstant(const Expr *E) const {
+    return isCharTyped(E) && isCharValuedConstant(E);
+  };
+
+  // Returns true if `E` is an integer constant which fits in `CharType`.
+  bool isCharValuedConstant(const Expr *E) const {
+    if (E->isInstantiationDependent())
+      return false;
+    Expr::EvalResult EvalResult;
+    if (!E->EvaluateAsInt(EvalResult, Ctx, Expr::SE_AllowSideEffects))
+      return false;
+    return EvalResult.Val.getInt().getActiveBits() <= Ctx.getTypeSize(CharType);
+  };
+
+  // Returns true if `E` has the right character type.
+  bool isCharTyped(const Expr *E) const {
+    return E->getType().getCanonicalType().getTypePtr() ==
+           CharType.getTypePtr();
+  };
+
+  const QualType CharType;
+  const ASTContext &Ctx;
+};
+
 void StringIntegerAssignmentCheck::check(
     const MatchFinder::MatchResult &Result) {
   const auto *Argument = Result.Nodes.getNodeAs<Expr>("expr");
+  const auto CharType =
+      Result.Nodes.getNodeAs<QualType>("type")->getCanonicalType();
   SourceLocation Loc = Argument->getBeginLoc();
 
+  // Try to detect a few common expressions to reduce false positives.
+  if (CharExpressionDetector(CharType, *Result.Context)
+          .isLikelyCharExpression(Argument))
+    return;
+
   auto Diag =
       diag(Loc, "an integer is interpreted as a character code when assigning "
                 "it to a string; if this is intended, cast the integer to the "
@@ -50,7 +150,6 @@
   if (Loc.isMacroID())
     return;
 
-  auto CharType = *Result.Nodes.getNodeAs<QualType>("type");
   bool IsWideCharType = CharType->isWideCharType();
   if (!CharType->isCharType() && !IsWideCharType)
     return;
diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
index 42fa53e..733e7be 100644
--- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
+++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
@@ -1,16 +1,15 @@
 //===--- StringIntegerAssignmentCheck.h - clang-tidy-------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGINTEGERASSIGNMENTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGINTEGERASSIGNMENTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
index b440b61..0fbd93e 100644
--- a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
+++ b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StringLiteralWithEmbeddedNulCheck.cpp - clang-tidy----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h
index f5341c3..a163a9f 100644
--- a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h
+++ b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h
@@ -1,16 +1,15 @@
 //===--- StringLiteralWithEmbeddedNulCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGLITERALWITHEMBEDDEDNULCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STRINGLITERALWITHEMBEDDEDNULCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp
index 5353700..42965a6 100644
--- a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp
+++ b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SuspiciousEnumUsageCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h
index 9c1b53d..f05f3e1 100644
--- a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h
+++ b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h
@@ -1,16 +1,15 @@
 //===--- SuspiciousEnumUsageCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSENUMUSAGECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSENUMUSAGECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp
index ca3c126..9f98316 100644
--- a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp
+++ b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SuspiciousMemsetUsageCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h
index 1c0d1bc..4074641 100644
--- a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h
+++ b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h
@@ -1,16 +1,15 @@
 //===--- SuspiciousMemsetUsageCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUS_MEMSET_USAGE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUS_MEMSET_USAGE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
index a66cf43..09409d8 100644
--- a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
+++ b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SuspiciousMissingCommaCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h
index 4ae3ecf..bf90f0a 100644
--- a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h
+++ b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h
@@ -1,16 +1,15 @@
 //===--- SuspiciousMissingCommaCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSMISSINGCOMMACHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSMISSINGCOMMACHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp b/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp
index f92fc37..d94731b 100644
--- a/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp
+++ b/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SuspiciousSemicolonCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -54,7 +53,7 @@
 
   SourceLocation LocEnd = Semicolon->getEndLoc();
   FileID FID = SM.getFileID(LocEnd);
-  llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, LocEnd);
+  const llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, LocEnd);
   Lexer Lexer(SM.getLocForStartOfFile(FID), Ctxt.getLangOpts(),
               Buffer->getBufferStart(), SM.getCharacterData(LocEnd) + 1,
               Buffer->getBufferEnd());
diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
index adfced1..0228f38 100644
--- a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
+++ b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
@@ -1,16 +1,15 @@
 //===--- SuspiciousSemicolonCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSEMICOLONCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSEMICOLONCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp b/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
index a16da4a..8de6460 100644
--- a/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
+++ b/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SuspiciousStringCompareCheck.cpp - clang-tidy---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousStringCompareCheck.h b/clang-tidy/bugprone/SuspiciousStringCompareCheck.h
index 38a9d9c..d0cda51 100644
--- a/clang-tidy/bugprone/SuspiciousStringCompareCheck.h
+++ b/clang-tidy/bugprone/SuspiciousStringCompareCheck.h
@@ -1,16 +1,15 @@
 //===--- SuspiciousStringCompareCheck.h - clang-tidy-------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSTRINGCOMPARECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSSTRINGCOMPARECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/SwappedArgumentsCheck.cpp b/clang-tidy/bugprone/SwappedArgumentsCheck.cpp
index c1550f6..9f05530 100644
--- a/clang-tidy/bugprone/SwappedArgumentsCheck.cpp
+++ b/clang-tidy/bugprone/SwappedArgumentsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SwappedArgumentsCheck.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SwappedArgumentsCheck.h b/clang-tidy/bugprone/SwappedArgumentsCheck.h
index 59ec3ad..484972c 100644
--- a/clang-tidy/bugprone/SwappedArgumentsCheck.h
+++ b/clang-tidy/bugprone/SwappedArgumentsCheck.h
@@ -1,16 +1,15 @@
 //===--- SwappedArgumentsCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SWAPPEDARGUMENTSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SWAPPEDARGUMENTSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/TerminatingContinueCheck.cpp b/clang-tidy/bugprone/TerminatingContinueCheck.cpp
index e41fc1f..beeeb2c 100644
--- a/clang-tidy/bugprone/TerminatingContinueCheck.cpp
+++ b/clang-tidy/bugprone/TerminatingContinueCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TerminatingContinueCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/TerminatingContinueCheck.h b/clang-tidy/bugprone/TerminatingContinueCheck.h
index 5985693..480db5d 100644
--- a/clang-tidy/bugprone/TerminatingContinueCheck.h
+++ b/clang-tidy/bugprone/TerminatingContinueCheck.h
@@ -1,16 +1,15 @@
 //===--- TerminatingContinueCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TERMINATINGCONTINUECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TERMINATINGCONTINUECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp b/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
index 695d9c5..767f9a4 100644
--- a/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
+++ b/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ThrowKeywordMissingCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/ThrowKeywordMissingCheck.h b/clang-tidy/bugprone/ThrowKeywordMissingCheck.h
index cc57083..d5e7d4e 100644
--- a/clang-tidy/bugprone/ThrowKeywordMissingCheck.h
+++ b/clang-tidy/bugprone/ThrowKeywordMissingCheck.h
@@ -1,16 +1,15 @@
 //===--- ThrowKeywordMissingCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWKEYWORDMISSINGCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWKEYWORDMISSINGCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
index 59cc185..1e31fde 100644
--- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
+++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TooSmallLoopVariableCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,6 +27,17 @@
 static constexpr llvm::StringLiteral LoopIncrementName =
     llvm::StringLiteral("loopIncrement");
 
+TooSmallLoopVariableCheck::TooSmallLoopVariableCheck(StringRef Name,
+                                                     ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      MagnitudeBitsUpperLimit(Options.get<unsigned>(
+          "MagnitudeBitsUpperLimit", 16)) {}
+
+void TooSmallLoopVariableCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "MagnitudeBitsUpperLimit", MagnitudeBitsUpperLimit);
+}
+
 /// \brief The matcher for loops with suspicious integer loop variable.
 ///
 /// In this general example, assuming 'j' and 'k' are of integral type:
@@ -85,9 +95,9 @@
       this);
 }
 
-/// Returns the positive part of the integer width for an integer type.
-static unsigned calcPositiveBits(const ASTContext &Context,
-                                 const QualType &IntExprType) {
+/// Returns the magnitude bits of an integer type.
+static unsigned calcMagnitudeBits(const ASTContext &Context,
+                                  const QualType &IntExprType) {
   assert(IntExprType->isIntegerType());
 
   return IntExprType->isUnsignedIntegerType()
@@ -95,13 +105,13 @@
              : Context.getIntWidth(IntExprType) - 1;
 }
 
-/// \brief Calculate the upper bound expression's positive bits, but ignore
+/// \brief Calculate the upper bound expression's magnitude bits, but ignore
 /// constant like values to reduce false positives.
-static unsigned calcUpperBoundPositiveBits(const ASTContext &Context,
-                                           const Expr *UpperBound,
-                                           const QualType &UpperBoundType) {
+static unsigned calcUpperBoundMagnitudeBits(const ASTContext &Context,
+                                            const Expr *UpperBound,
+                                            const QualType &UpperBoundType) {
   // Ignore casting caused by constant values inside a binary operator.
-  // We are interested in variable values' positive bits.
+  // We are interested in variable values' magnitude bits.
   if (const auto *BinOperator = dyn_cast<BinaryOperator>(UpperBound)) {
     const Expr *RHSE = BinOperator->getRHS()->IgnoreParenImpCasts();
     const Expr *LHSE = BinOperator->getLHS()->IgnoreParenImpCasts();
@@ -123,15 +133,15 @@
     if (RHSEIsConstantValue && LHSEIsConstantValue)
       return 0;
     if (RHSEIsConstantValue)
-      return calcPositiveBits(Context, LHSEType);
+      return calcMagnitudeBits(Context, LHSEType);
     if (LHSEIsConstantValue)
-      return calcPositiveBits(Context, RHSEType);
+      return calcMagnitudeBits(Context, RHSEType);
 
-    return std::max(calcPositiveBits(Context, LHSEType),
-                    calcPositiveBits(Context, RHSEType));
+    return std::max(calcMagnitudeBits(Context, LHSEType),
+                    calcMagnitudeBits(Context, RHSEType));
   }
 
-  return calcPositiveBits(Context, UpperBoundType);
+  return calcMagnitudeBits(Context, UpperBoundType);
 }
 
 void TooSmallLoopVariableCheck::check(const MatchFinder::MatchResult &Result) {
@@ -150,14 +160,17 @@
 
   ASTContext &Context = *Result.Context;
 
-  unsigned LoopVarPosBits = calcPositiveBits(Context, LoopVarType);
-  unsigned UpperBoundPosBits =
-      calcUpperBoundPositiveBits(Context, UpperBound, UpperBoundType);
+  unsigned LoopVarMagnitudeBits = calcMagnitudeBits(Context, LoopVarType);
+  unsigned UpperBoundMagnitudeBits =
+      calcUpperBoundMagnitudeBits(Context, UpperBound, UpperBoundType);
 
-  if (UpperBoundPosBits == 0)
+  if (UpperBoundMagnitudeBits == 0)
     return;
 
-  if (LoopVarPosBits < UpperBoundPosBits)
+  if (LoopVarMagnitudeBits > MagnitudeBitsUpperLimit)
+    return;
+
+  if (LoopVarMagnitudeBits < UpperBoundMagnitudeBits)
     diag(LoopVar->getBeginLoc(), "loop variable has narrower type %0 than "
                                  "iteration's upper bound %1")
         << LoopVarType << UpperBoundType;
diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
index 0819fcf..c48b446 100644
--- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
+++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
@@ -1,16 +1,15 @@
 //===--- TooSmallLoopVariableCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TOOSMALLLOOPVARIABLECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TOOSMALLLOOPVARIABLECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -30,10 +29,14 @@
 /// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-too-small-loop-variable.html
 class TooSmallLoopVariableCheck : public ClangTidyCheck {
 public:
-  TooSmallLoopVariableCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  TooSmallLoopVariableCheck(StringRef Name, ClangTidyContext *Context);
+
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  const unsigned MagnitudeBitsUpperLimit;
 };
 
 } // namespace bugprone
diff --git a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
index 0665e08..514ee5a 100644
--- a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
+++ b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UndefinedMemoryManipulationCheck.cpp - clang-tidy-----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
index 64d6c56..25af704 100644
--- a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
+++ b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
@@ -1,16 +1,15 @@
 //===--- UndefinedMemoryManipulationCheck.h - clang-tidy---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNDEFINED_MEMORY_MANIPULATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNDEFINED_MEMORY_MANIPULATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp b/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
index 90c07b9..32a023f 100644
--- a/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
+++ b/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UndelegatedConstructorCheck.cpp - clang-tidy --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UndelegatedConstructorCheck.h b/clang-tidy/bugprone/UndelegatedConstructorCheck.h
index ed881e1..0906052 100644
--- a/clang-tidy/bugprone/UndelegatedConstructorCheck.h
+++ b/clang-tidy/bugprone/UndelegatedConstructorCheck.h
@@ -1,16 +1,15 @@
 //===--- UndelegatedConstructorCheck.h - clang-tidy -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNDELEGATEDCONSTRUCTOR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNDELEGATEDCONSTRUCTOR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tidy/bugprone/UnusedRaiiCheck.cpp
index e9089b7..e89cbe1 100644
--- a/clang-tidy/bugprone/UnusedRaiiCheck.cpp
+++ b/clang-tidy/bugprone/UnusedRaiiCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnusedRaiiCheck.cpp - clang-tidy ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UnusedRaiiCheck.h b/clang-tidy/bugprone/UnusedRaiiCheck.h
index 34190ec..1307a77 100644
--- a/clang-tidy/bugprone/UnusedRaiiCheck.h
+++ b/clang-tidy/bugprone/UnusedRaiiCheck.h
@@ -1,16 +1,15 @@
 //===--- UnusedRaiiCheck.h - clang-tidy -------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDRAIICHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDRAIICHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
index b8de045..c3efb08 100644
--- a/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
+++ b/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnusedReturnValueCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UnusedReturnValueCheck.h b/clang-tidy/bugprone/UnusedReturnValueCheck.h
index 9475f56..7e100cd 100644
--- a/clang-tidy/bugprone/UnusedReturnValueCheck.h
+++ b/clang-tidy/bugprone/UnusedReturnValueCheck.h
@@ -1,16 +1,15 @@
 //===--- UnusedReturnValueCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDRETURNVALUECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNUSEDRETURNVALUECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include <string>
 
 namespace clang {
diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tidy/bugprone/UseAfterMoveCheck.cpp
index 99c847e..8e316eb 100644
--- a/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ b/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseAfterMoveCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.h b/clang-tidy/bugprone/UseAfterMoveCheck.h
index f6dea68..27cb32b 100644
--- a/clang-tidy/bugprone/UseAfterMoveCheck.h
+++ b/clang-tidy/bugprone/UseAfterMoveCheck.h
@@ -1,16 +1,15 @@
 //===--- UseAfterMoveCheck.h - clang-tidy ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_USEAFTERMOVECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_USEAFTERMOVECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tidy/bugprone/VirtualNearMissCheck.cpp
index ede1bf3..32ca1b4 100644
--- a/clang-tidy/bugprone/VirtualNearMissCheck.cpp
+++ b/clang-tidy/bugprone/VirtualNearMissCheck.cpp
@@ -1,9 +1,8 @@
 //===--- VirtualNearMissCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/VirtualNearMissCheck.h b/clang-tidy/bugprone/VirtualNearMissCheck.h
index ea1e256..d5f4a11 100644
--- a/clang-tidy/bugprone/VirtualNearMissCheck.h
+++ b/clang-tidy/bugprone/VirtualNearMissCheck.h
@@ -1,16 +1,15 @@
 //===--- VirtualNearMissCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_VIRTUAL_NEAR_MISS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_VIRTUAL_NEAR_MISS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/DenseMap.h"
 
 namespace clang {
diff --git a/clang-tidy/cert/CERTTidyModule.cpp b/clang-tidy/cert/CERTTidyModule.cpp
index b6a0e7b..cd8da0c 100644
--- a/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tidy/cert/CERTTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- CERTTidyModule.cpp - clang-tidy ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/CommandProcessorCheck.cpp b/clang-tidy/cert/CommandProcessorCheck.cpp
index e2dbeca..72b39d1 100644
--- a/clang-tidy/cert/CommandProcessorCheck.cpp
+++ b/clang-tidy/cert/CommandProcessorCheck.cpp
@@ -1,9 +1,8 @@
-//===--- Env33CCheck.cpp - clang-tidy--------------------------------------===//
+//===-- CommandProcessorCheck.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/CommandProcessorCheck.h b/clang-tidy/cert/CommandProcessorCheck.h
index a85a7ed..14ebd08 100644
--- a/clang-tidy/cert/CommandProcessorCheck.h
+++ b/clang-tidy/cert/CommandProcessorCheck.h
@@ -1,16 +1,15 @@
 //===--- CommandInterpreterCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_COMMAND_PROCESSOR_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_COMMAND_PROCESSOR_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp b/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp
index e5759a5..7b2c759 100644
--- a/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp
+++ b/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DontModifyStdNamespaceCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/DontModifyStdNamespaceCheck.h b/clang-tidy/cert/DontModifyStdNamespaceCheck.h
index 0cc23f7..3e90111 100644
--- a/clang-tidy/cert/DontModifyStdNamespaceCheck.h
+++ b/clang-tidy/cert/DontModifyStdNamespaceCheck.h
@@ -1,16 +1,15 @@
 //===--- DontModifyStdNamespaceCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/FloatLoopCounter.cpp b/clang-tidy/cert/FloatLoopCounter.cpp
index e92552e..b6b3b19 100644
--- a/clang-tidy/cert/FloatLoopCounter.cpp
+++ b/clang-tidy/cert/FloatLoopCounter.cpp
@@ -1,9 +1,8 @@
 //===--- FloatLoopCounter.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/FloatLoopCounter.h b/clang-tidy/cert/FloatLoopCounter.h
index c66e44a..be993c4 100644
--- a/clang-tidy/cert/FloatLoopCounter.h
+++ b/clang-tidy/cert/FloatLoopCounter.h
@@ -1,16 +1,15 @@
 //===--- FloatLoopCounter.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_FLOAT_LOOP_COUNTER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_FLOAT_LOOP_COUNTER_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/LICENSE.TXT b/clang-tidy/cert/LICENSE.TXT
index d8395cc..769cc46 100644
--- a/clang-tidy/cert/LICENSE.TXT
+++ b/clang-tidy/cert/LICENSE.TXT
@@ -1,8 +1,8 @@
 ------------------------------------------------------------------------------
 clang-tidy CERT Files
 ------------------------------------------------------------------------------
-All clang-tidy files are licensed under the LLVM license with the following
-additions:
+All clang-tidy files are licensed under the same terms as the rest of the LLVM
+project with the following additions:
 
 Any file referencing a CERT Secure Coding guideline:
 Please allow this letter to serve as confirmation that open source projects on
diff --git a/clang-tidy/cert/LimitedRandomnessCheck.cpp b/clang-tidy/cert/LimitedRandomnessCheck.cpp
index 3f6f948..847f05e 100644
--- a/clang-tidy/cert/LimitedRandomnessCheck.cpp
+++ b/clang-tidy/cert/LimitedRandomnessCheck.cpp
@@ -1,9 +1,8 @@
 //===--- LimitedRandomnessCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/LimitedRandomnessCheck.h b/clang-tidy/cert/LimitedRandomnessCheck.h
index 59d511c..7ef75e3 100644
--- a/clang-tidy/cert/LimitedRandomnessCheck.h
+++ b/clang-tidy/cert/LimitedRandomnessCheck.h
@@ -1,16 +1,15 @@
 //===--- LimitedRandomnessCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_LIMITED_RANDOMNESS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_LIMITED_RANDOMNESS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/PostfixOperatorCheck.cpp b/clang-tidy/cert/PostfixOperatorCheck.cpp
index b8e84df..45c7481 100644
--- a/clang-tidy/cert/PostfixOperatorCheck.cpp
+++ b/clang-tidy/cert/PostfixOperatorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- PostfixOperatorCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/PostfixOperatorCheck.h b/clang-tidy/cert/PostfixOperatorCheck.h
index 29c2306..4a6133b 100644
--- a/clang-tidy/cert/PostfixOperatorCheck.h
+++ b/clang-tidy/cert/PostfixOperatorCheck.h
@@ -1,16 +1,15 @@
 //===--- PostfixOperatorCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_POSTFIX_OPERATOR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_POSTFIX_OPERATOR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
index 6ae9bd2..3be83cf 100644
--- a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
+++ b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProperlySeededRandomGeneratorCheck.cpp - clang-tidy---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
index ac5507c..04d1f7b 100644
--- a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
+++ b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
@@ -1,16 +1,15 @@
 //===--- ProperlySeededRandomGeneratorCheck.h - clang-tidy-------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PROPERLY_SEEDED_RANDOM_GENERATOR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PROPERLY_SEEDED_RANDOM_GENERATOR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include <string>
 
 namespace clang {
diff --git a/clang-tidy/cert/SetLongJmpCheck.cpp b/clang-tidy/cert/SetLongJmpCheck.cpp
index 89ba5e7..87ac2de 100644
--- a/clang-tidy/cert/SetLongJmpCheck.cpp
+++ b/clang-tidy/cert/SetLongJmpCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SetLongJmpCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,10 +19,10 @@
 namespace tidy {
 namespace cert {
 
-const char SetLongJmpCheck::DiagWording[] =
+namespace {
+const char DiagWording[] =
     "do not call %0; consider using exception handling instead";
 
-namespace {
 class SetJmpMacroCallbacks : public PPCallbacks {
   SetLongJmpCheck &Check;
 
@@ -37,12 +36,14 @@
       return;
 
     if (II->getName() == "setjmp")
-      Check.diag(Range.getBegin(), Check.DiagWording) << II;
+      Check.diag(Range.getBegin(), DiagWording) << II;
   }
 };
 } // namespace
 
-void SetLongJmpCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+void SetLongJmpCheck::registerPPCallbacks(const SourceManager &SM,
+                                          Preprocessor *PP,
+                                          Preprocessor *ModuleExpanderPP) {
   // This checker only applies to C++, where exception handling is a superior
   // solution to setjmp/longjmp calls.
   if (!getLangOpts().CPlusPlus)
@@ -50,8 +51,7 @@
 
   // Per [headers]p5, setjmp must be exposed as a macro instead of a function,
   // despite the allowance in C for setjmp to also be an extern function.
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<SetJmpMacroCallbacks>(*this));
+  PP->addPPCallbacks(llvm::make_unique<SetJmpMacroCallbacks>(*this));
 }
 
 void SetLongJmpCheck::registerMatchers(MatchFinder *Finder) {
@@ -63,10 +63,10 @@
   // In case there is an implementation that happens to define setjmp as a
   // function instead of a macro, this will also catch use of it. However, we
   // are primarily searching for uses of longjmp.
-  Finder->addMatcher(callExpr(callee(functionDecl(anyOf(hasName("setjmp"),
-                                                        hasName("longjmp")))))
-                         .bind("expr"),
-                     this);
+  Finder->addMatcher(
+      callExpr(callee(functionDecl(hasAnyName("setjmp", "longjmp"))))
+          .bind("expr"),
+      this);
 }
 
 void SetLongJmpCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tidy/cert/SetLongJmpCheck.h b/clang-tidy/cert/SetLongJmpCheck.h
index 1d6c098..d9cef1b 100644
--- a/clang-tidy/cert/SetLongJmpCheck.h
+++ b/clang-tidy/cert/SetLongJmpCheck.h
@@ -1,16 +1,15 @@
 //===--- SetLongJmpCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -26,9 +25,8 @@
       : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
-
-  static const char DiagWording[];
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace cert
diff --git a/clang-tidy/cert/StaticObjectExceptionCheck.cpp b/clang-tidy/cert/StaticObjectExceptionCheck.cpp
index 30f86aa..363c96a 100644
--- a/clang-tidy/cert/StaticObjectExceptionCheck.cpp
+++ b/clang-tidy/cert/StaticObjectExceptionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StaticObjectExceptionCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/StaticObjectExceptionCheck.h b/clang-tidy/cert/StaticObjectExceptionCheck.h
index 463f433..64a1eb5 100644
--- a/clang-tidy/cert/StaticObjectExceptionCheck.h
+++ b/clang-tidy/cert/StaticObjectExceptionCheck.h
@@ -1,16 +1,15 @@
 //===--- StaticObjectExceptionCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/StrToNumCheck.cpp b/clang-tidy/cert/StrToNumCheck.cpp
index 0b3ea43..9d26060 100644
--- a/clang-tidy/cert/StrToNumCheck.cpp
+++ b/clang-tidy/cert/StrToNumCheck.cpp
@@ -1,9 +1,8 @@
-//===--- Err34CCheck.cpp - clang-tidy--------------------------------------===//
+//===-- StrToNumCheck.cpp - clang-tidy ------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/StrToNumCheck.h b/clang-tidy/cert/StrToNumCheck.h
index 55f13be..3ac090b 100644
--- a/clang-tidy/cert/StrToNumCheck.h
+++ b/clang-tidy/cert/StrToNumCheck.h
@@ -1,16 +1,15 @@
 //===--- StrToNumCheck.h - clang-tidy----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_STRTONUMCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_STRTONUMCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/ThrownExceptionTypeCheck.cpp b/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
index 37fb355..9478405 100644
--- a/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
+++ b/clang-tidy/cert/ThrownExceptionTypeCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ThrownExceptionTypeCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/ThrownExceptionTypeCheck.h b/clang-tidy/cert/ThrownExceptionTypeCheck.h
index 2f9d887..dc37b6a 100644
--- a/clang-tidy/cert/ThrownExceptionTypeCheck.h
+++ b/clang-tidy/cert/ThrownExceptionTypeCheck.h
@@ -1,16 +1,15 @@
 //===--- ThrownExceptionTypeCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_THROWNEXCEPTIONTYPECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_THROWNEXCEPTIONTYPECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.cpp b/clang-tidy/cert/VariadicFunctionDefCheck.cpp
index ea6112a..8ee67f9 100644
--- a/clang-tidy/cert/VariadicFunctionDefCheck.cpp
+++ b/clang-tidy/cert/VariadicFunctionDefCheck.cpp
@@ -1,9 +1,8 @@
-//===--- VariadicfunctiondefCheck.cpp - clang-tidy-------------------------===//
+//===-- VariadicFunctionDefCheck.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.h b/clang-tidy/cert/VariadicFunctionDefCheck.h
index e215e8d..24408ac 100644
--- a/clang-tidy/cert/VariadicFunctionDefCheck.h
+++ b/clang-tidy/cert/VariadicFunctionDefCheck.h
@@ -1,16 +1,15 @@
 //===--- VariadicFunctionDefCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_VARIADICFUNCTIONDEF_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_VARIADICFUNCTIONDEF_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp
index eaed15f..9e7bf63 100644
--- a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidGotoCheck.cpp - clang-tidy-----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h
index cf7dd76..f27e22c 100644
--- a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h
+++ b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h
@@ -1,9 +1,8 @@
 //===--- AvoidGotoCheck.h - clang-tidy---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
index 0870f1e..7c7fd1b 100644
--- a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -1,9 +1,8 @@
-//===--- CppCoreGuidelinesModule.cpp - clang-tidy -------------------------===//
+//===-- CppCoreGuidelinesTidyModule.cpp - clang-tidy ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,6 +12,7 @@
 #include "../misc/NonPrivateMemberVariablesInClassesCheck.h"
 #include "../misc/UnconventionalAssignOperatorCheck.h"
 #include "../modernize/AvoidCArraysCheck.h"
+#include "../modernize/UseOverrideCheck.h"
 #include "../readability/MagicNumbersCheck.h"
 #include "AvoidGotoCheck.h"
 #include "InterfacesGlobalInitCheck.h"
@@ -47,6 +47,8 @@
         "cppcoreguidelines-avoid-goto");
     CheckFactories.registerCheck<readability::MagicNumbersCheck>(
         "cppcoreguidelines-avoid-magic-numbers");
+    CheckFactories.registerCheck<modernize::UseOverrideCheck>(
+        "cppcoreguidelines-explicit-virtual-functions");
     CheckFactories.registerCheck<InterfacesGlobalInitCheck>(
         "cppcoreguidelines-interfaces-global-init");
     CheckFactories.registerCheck<MacroUsageCheck>(
@@ -92,6 +94,9 @@
     Opts["cppcoreguidelines-non-private-member-variables-in-classes."
          "IgnoreClassesWithAllMemberVariablesBeingPublic"] = "1";
 
+    Opts["cppcoreguidelines-explicit-virtual-functions."
+         "IgnoreDestructors"] = "1";
+
     return Options;
   }
 };
diff --git a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
index 59993cb..d9c91b2 100644
--- a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InterfacesGlobalInitCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h
index 13712d1..ecaaaa3 100644
--- a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h
+++ b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h
@@ -1,9 +1,8 @@
 //===--- InterfacesGlobalInitCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp b/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
index 8b893c7..ac5ec13 100644
--- a/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MacroUsageCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -37,7 +36,8 @@
         IgnoreCommandLineMacros(IgnoreCommandLine) {}
   void MacroDefined(const Token &MacroNameTok,
                     const MacroDirective *MD) override {
-    if (MD->getMacroInfo()->isUsedForHeaderGuard() ||
+    if (SM.isWrittenInBuiltinFile(MD->getLocation()) ||
+        MD->getMacroInfo()->isUsedForHeaderGuard() ||
         MD->getMacroInfo()->getNumTokens() == 0)
       return;
 
@@ -68,14 +68,14 @@
   Options.store(Opts, "IgnoreCommandLineMacros", IgnoreCommandLineMacros);
 }
 
-void MacroUsageCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+void MacroUsageCheck::registerPPCallbacks(const SourceManager &SM,
+                                          Preprocessor *PP,
+                                          Preprocessor *ModuleExpanderPP) {
   if (!getLangOpts().CPlusPlus11)
     return;
 
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<MacroUsageCallbacks>(this, Compiler.getSourceManager(),
-                                             AllowedRegexp, CheckCapsOnly,
-                                             IgnoreCommandLineMacros));
+  PP->addPPCallbacks(llvm::make_unique<MacroUsageCallbacks>(
+      this, SM, AllowedRegexp, CheckCapsOnly, IgnoreCommandLineMacros));
 }
 
 void MacroUsageCheck::warnMacro(const MacroDirective *MD, StringRef MacroName) {
diff --git a/clang-tidy/cppcoreguidelines/MacroUsageCheck.h b/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
index a39d55a..978edd8 100644
--- a/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
+++ b/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
@@ -1,9 +1,8 @@
 //===--- MacroUsageCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,7 +30,8 @@
         CheckCapsOnly(Options.get("CheckCapsOnly", 0)),
         IgnoreCommandLineMacros(Options.get("IgnoreCommandLineMacros", 1)) {}
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void warnMacro(const MacroDirective *MD, StringRef MacroName);
   void warnNaming(const MacroDirective *MD, StringRef MacroName);
 
diff --git a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
index 132d84a..5731116 100644
--- a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NarrowingConversionsCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
index 3e72248..cc598ed 100644
--- a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
+++ b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h
@@ -1,9 +1,8 @@
 //===--- NarrowingConversionsCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp b/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp
index f9cec51..b78e7d1 100644
--- a/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NoMallocCheck.cpp - clang-tidy------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/NoMallocCheck.h b/clang-tidy/cppcoreguidelines/NoMallocCheck.h
index 4cec8a8..023202a 100644
--- a/clang-tidy/cppcoreguidelines/NoMallocCheck.h
+++ b/clang-tidy/cppcoreguidelines/NoMallocCheck.h
@@ -1,9 +1,8 @@
 //===--- NoMallocCheck.h - clang-tidy----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
index 0b7e0a3..11d1e3e 100644
--- a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
@@ -1,9 +1,8 @@
 //===--- OwningMemoryCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h
index e68e4c0..0498eea 100644
--- a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h
+++ b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h
@@ -1,9 +1,8 @@
 //===--- OwningMemoryCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
index af41386..6939ec9 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProBoundsArrayToPointerDecayCheck.cpp - clang-tidy----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
index 0afffb6..2809965 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
@@ -1,9 +1,8 @@
 //===--- ProBoundsArrayToPointerDecayCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
index 9fbb121..28fccfd 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProBoundsConstantArrayIndexCheck.cpp - clang-tidy-----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -32,13 +31,13 @@
 }
 
 void ProBoundsConstantArrayIndexCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
   if (!getLangOpts().CPlusPlus)
     return;
 
-  Inserter.reset(new utils::IncludeInserter(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
-  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+  Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                       IncludeStyle);
+  PP->addPPCallbacks(Inserter->CreatePPCallbacks());
 }
 
 void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
index 28b24a6..c75795a 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
@@ -1,9 +1,8 @@
 //===--- ProBoundsConstantArrayIndexCheck.h - clang-tidy---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -29,7 +28,8 @@
 
 public:
   ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context);
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
index dfbb51b..384c8be 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProBoundsPointerArithmeticCheck.cpp - clang-tidy------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
index 5ecf93c..ab43c78 100644
--- a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -1,9 +1,8 @@
 //===--- ProBoundsPointerArithmeticCheck.h - clang-tidy----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
index 4b6fb42..419c676 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeConstCastCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
index 92a3a1b..2fbfdd3 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeConstCastCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp
index bc2418d..18fad57 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeCstyleCastCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h
index c08b883..aebc57e 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeCstyleCastCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
index 82f50a1..c6cfe5e 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeMemberInitCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h
index 20d3f60..807acfe 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeMemberInitCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
index e56e638..4c4c6ce 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeReinterpretCastCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
index 9610546..5afd461 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeReinterpretCast.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
index f43e4fa..59503ba 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeStaticCastDowncastCheck.cpp - clang-tidy-------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
index b6d76a6..e7c45ae 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeStaticCastDowncastCheck.h - clang-tidy-----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp
index 09752f6..e50dd4e 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeUnionAccessCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h
index fc7dd67..70080f4 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeUnionAccessCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
index 56227b2..650e668 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ProTypeVarargCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h
index 558c856..98acc5a 100644
--- a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h
+++ b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h
@@ -1,9 +1,8 @@
 //===--- ProTypeVarargCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 53b2f72..8ad4750 100644
--- a/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SlicingCheck.cpp - clang-tidy-------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/SlicingCheck.h b/clang-tidy/cppcoreguidelines/SlicingCheck.h
index 9ee91bc..a2322a9 100644
--- a/clang-tidy/cppcoreguidelines/SlicingCheck.h
+++ b/clang-tidy/cppcoreguidelines/SlicingCheck.h
@@ -1,9 +1,8 @@
 //===--- SlicingCheck.h - clang-tidy-----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
index df3c279..8f95e50 100644
--- a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
+++ b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SpecialMemberFunctionsCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
index 8ab0c92..71caa4d 100644
--- a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
+++ b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h
@@ -1,9 +1,8 @@
 //===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp b/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
index e6a67e0..7f83ac6 100644
--- a/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
+++ b/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DefaultArgumentsCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/DefaultArgumentsCheck.h b/clang-tidy/fuchsia/DefaultArgumentsCheck.h
index f54fd96..8d26c35 100644
--- a/clang-tidy/fuchsia/DefaultArgumentsCheck.h
+++ b/clang-tidy/fuchsia/DefaultArgumentsCheck.h
@@ -1,16 +1,15 @@
 //===--- DefaultArgumentsCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_DEFAULT_ARGUMENTS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_DEFAULT_ARGUMENTS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/fuchsia/FuchsiaTidyModule.cpp b/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
index 0d3bbfe..034a30e 100644
--- a/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
+++ b/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- FuchsiaTidyModule.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
index a49c952..a5f9d6e 100644
--- a/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MultipleInheritanceCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tidy/fuchsia/MultipleInheritanceCheck.h
index 6250e3e..c79050a 100644
--- a/clang-tidy/fuchsia/MultipleInheritanceCheck.h
+++ b/clang-tidy/fuchsia/MultipleInheritanceCheck.h
@@ -1,16 +1,15 @@
 //===--- MultipleInheritanceCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLE_INHERITANCE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLE_INHERITANCE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp b/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
index 4aab1e0..fb77efc 100644
--- a/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
+++ b/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- OverloadedOperatorCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.h b/clang-tidy/fuchsia/OverloadedOperatorCheck.h
index a22e5ae..122d5dc 100644
--- a/clang-tidy/fuchsia/OverloadedOperatorCheck.h
+++ b/clang-tidy/fuchsia/OverloadedOperatorCheck.h
@@ -1,16 +1,15 @@
 //===--- OverloadedOperatorCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_OVERLOADED_OPERATOR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_OVERLOADED_OPERATOR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp
index 4817e90..08981fc 100644
--- a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp
+++ b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RestrictSystemIncludesCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -24,7 +23,7 @@
 class RestrictedIncludesPPCallbacks : public PPCallbacks {
 public:
   explicit RestrictedIncludesPPCallbacks(RestrictSystemIncludesCheck &Check,
-                                         SourceManager &SM)
+                                         const SourceManager &SM)
       : Check(Check), SM(SM) {}
 
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
@@ -54,7 +53,7 @@
   llvm::SmallDenseMap<FileID, FileIncludes> IncludeDirectives;
 
   RestrictSystemIncludesCheck &Check;
-  SourceManager &SM;
+  const SourceManager &SM;
 };
 
 void RestrictedIncludesPPCallbacks::InclusionDirective(
@@ -102,10 +101,9 @@
 }
 
 void RestrictSystemIncludesCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<RestrictedIncludesPPCallbacks>(
-          *this, Compiler.getSourceManager()));
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(
+      llvm::make_unique<RestrictedIncludesPPCallbacks>(*this, SM));
 }
 
 void RestrictSystemIncludesCheck::storeOptions(
diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
index d4e5ac1..0539b73 100644
--- a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
+++ b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
@@ -1,16 +1,15 @@
 //===--- RestrictSystemIncludesCheck.h - clang-tidy---------- ----*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_RESTRICTINCLUDESSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_RESTRICTINCLUDESSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../ClangTidyDiagnosticConsumer.h"
 #include "../utils/OptionsUtils.h"
 
@@ -30,7 +29,8 @@
         AllowedIncludes(Options.get("Includes", "*")),
         AllowedIncludesGlobList(AllowedIncludes) {}
 
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   bool contains(StringRef FileName) {
     return AllowedIncludesGlobList.contains(FileName);
diff --git a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
index c8ffd2e..cd6de92 100644
--- a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
+++ b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StaticallyConstructedObjectsCheck.cpp - clang-tidy----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
index 6df9b1c..adf48aa 100644
--- a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
+++ b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
@@ -1,16 +1,15 @@
 //===--- StaticallyConstructedObjectsCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_STATICALLY_CONSTRUCTED_OBJECTS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_STATICALLY_CONSTRUCTED_OBJECTS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/fuchsia/TrailingReturnCheck.cpp b/clang-tidy/fuchsia/TrailingReturnCheck.cpp
index 71dc472..a1da0db 100644
--- a/clang-tidy/fuchsia/TrailingReturnCheck.cpp
+++ b/clang-tidy/fuchsia/TrailingReturnCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TrailingReturnCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/TrailingReturnCheck.h b/clang-tidy/fuchsia/TrailingReturnCheck.h
index 4a16c4e..e0aab1f 100644
--- a/clang-tidy/fuchsia/TrailingReturnCheck.h
+++ b/clang-tidy/fuchsia/TrailingReturnCheck.h
@@ -1,16 +1,15 @@
 //===--- TrailingReturnCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_TRAILING_RETURN_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_TRAILING_RETURN_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp b/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
index 82f4410..54a4d73 100644
--- a/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
+++ b/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- VirtualInheritanceCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/VirtualInheritanceCheck.h b/clang-tidy/fuchsia/VirtualInheritanceCheck.h
index b2c84c4..88ff0dc 100644
--- a/clang-tidy/fuchsia/VirtualInheritanceCheck.h
+++ b/clang-tidy/fuchsia/VirtualInheritanceCheck.h
@@ -1,16 +1,15 @@
 //===--- VirtualInheritanceCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_VIRTUAL_INHERITANCE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_VIRTUAL_INHERITANCE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tidy/google/AvoidCStyleCastsCheck.cpp
index d6ea7e0..6a16d88 100644
--- a/clang-tidy/google/AvoidCStyleCastsCheck.cpp
+++ b/clang-tidy/google/AvoidCStyleCastsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidCStyleCastsCheck.cpp - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/AvoidCStyleCastsCheck.h b/clang-tidy/google/AvoidCStyleCastsCheck.h
index ea7e34c..72f96d0 100644
--- a/clang-tidy/google/AvoidCStyleCastsCheck.h
+++ b/clang-tidy/google/AvoidCStyleCastsCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidCStyleCastsCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDCSTYLECASTSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDCSTYLECASTSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp
index ad74181..bfc3467 100644
--- a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp
+++ b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidThrowingObjCExceptionCheck.cpp - clang-tidy------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
index 9498226..692a37f 100644
--- a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
+++ b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidThrowingObjCExceptionCheck.h - clang-tidy----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_AVOID_THROWING_EXCEPTION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_AVOID_THROWING_EXCEPTION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp
new file mode 100644
index 0000000..d279343
--- /dev/null
+++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp
@@ -0,0 +1,88 @@
+//===--- AvoidUnderscoreInGoogletestNameCheck.cpp - clang-tidy --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+
+#include "AvoidUnderscoreInGoogletestNameCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/MacroArgs.h"
+
+namespace clang {
+namespace tidy {
+namespace google {
+namespace readability {
+
+constexpr llvm::StringLiteral kDisabledTestPrefix = "DISABLED_";
+
+// Determines whether the macro is a Googletest test macro.
+static bool isGoogletestTestMacro(StringRef MacroName) {
+  static const llvm::StringSet<> MacroNames = {"TEST", "TEST_F", "TEST_P",
+                                               "TYPED_TEST", "TYPED_TEST_P"};
+  return MacroNames.find(MacroName) != MacroNames.end();
+}
+
+namespace {
+
+class AvoidUnderscoreInGoogletestNameCallback : public PPCallbacks {
+public:
+  AvoidUnderscoreInGoogletestNameCallback(
+      Preprocessor *PP, AvoidUnderscoreInGoogletestNameCheck *Check)
+      : PP(PP), Check(Check) {}
+
+  // Detects expansions of the TEST, TEST_F, TEST_P, TYPED_TEST, TYPED_TEST_P
+  // macros and checks that their arguments do not have any underscores.
+  void MacroExpands(const Token &MacroNameToken,
+                    const MacroDefinition &MacroDefinition, SourceRange Range,
+                    const MacroArgs *Args) override {
+    IdentifierInfo *NameIdentifierInfo = MacroNameToken.getIdentifierInfo();
+    if (!NameIdentifierInfo)
+      return;
+    StringRef MacroName = NameIdentifierInfo->getName();
+    if (!isGoogletestTestMacro(MacroName) || !Args ||
+        Args->getNumMacroArguments() < 2)
+      return;
+    const Token *TestCaseNameToken = Args->getUnexpArgument(0);
+    const Token *TestNameToken = Args->getUnexpArgument(1);
+    if (!TestCaseNameToken || !TestNameToken)
+      return;
+    std::string TestCaseName = PP->getSpelling(*TestCaseNameToken);
+    if (TestCaseName.find('_') != std::string::npos)
+      Check->diag(TestCaseNameToken->getLocation(),
+                  "avoid using \"_\" in test case name \"%0\" according to "
+                  "Googletest FAQ")
+          << TestCaseName;
+
+    std::string TestNameMaybeDisabled = PP->getSpelling(*TestNameToken);
+    StringRef TestName = TestNameMaybeDisabled;
+    TestName.consume_front(kDisabledTestPrefix);
+    if (TestName.contains('_'))
+      Check->diag(TestNameToken->getLocation(),
+                  "avoid using \"_\" in test name \"%0\" according to "
+                  "Googletest FAQ")
+          << TestName;
+  }
+
+private:
+  Preprocessor *PP;
+  AvoidUnderscoreInGoogletestNameCheck *Check;
+};
+
+} // namespace
+
+void AvoidUnderscoreInGoogletestNameCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(
+      llvm::make_unique<AvoidUnderscoreInGoogletestNameCallback>(PP, this));
+}
+
+} // namespace readability
+} // namespace google
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h
new file mode 100644
index 0000000..6a690f6
--- /dev/null
+++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h
@@ -0,0 +1,34 @@
+//===--- AvoidUnderscoreInGoogletestNameCheck.h - clang-tidy ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace google {
+namespace readability {
+
+// Check for underscores in the names of googletest tests, per
+// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
+class AvoidUnderscoreInGoogletestNameCheck : public ClangTidyCheck {
+public:
+  using ClangTidyCheck::ClangTidyCheck;
+
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+};
+
+} // namespace readability
+} // namespace google
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H
diff --git a/clang-tidy/google/CMakeLists.txt b/clang-tidy/google/CMakeLists.txt
index 2ded4aa..4d0a326 100644
--- a/clang-tidy/google/CMakeLists.txt
+++ b/clang-tidy/google/CMakeLists.txt
@@ -3,6 +3,7 @@
 add_clang_library(clangTidyGoogleModule
   AvoidCStyleCastsCheck.cpp
   AvoidThrowingObjCExceptionCheck.cpp
+  AvoidUnderscoreInGoogletestNameCheck.cpp
   DefaultArgumentsCheck.cpp
   ExplicitConstructorCheck.cpp
   ExplicitMakePairCheck.cpp
diff --git a/clang-tidy/google/DefaultArgumentsCheck.cpp b/clang-tidy/google/DefaultArgumentsCheck.cpp
index ccbd870..1ec2924 100644
--- a/clang-tidy/google/DefaultArgumentsCheck.cpp
+++ b/clang-tidy/google/DefaultArgumentsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DefaultArgumentsCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/DefaultArgumentsCheck.h b/clang-tidy/google/DefaultArgumentsCheck.h
index 1457a09..574965d 100644
--- a/clang-tidy/google/DefaultArgumentsCheck.h
+++ b/clang-tidy/google/DefaultArgumentsCheck.h
@@ -1,16 +1,15 @@
 //===--- DefaultArgumentsCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_DEFAULT_ARGUMENTS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_DEFAULT_ARGUMENTS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tidy/google/ExplicitConstructorCheck.cpp
index 778ce89..69731c2 100644
--- a/clang-tidy/google/ExplicitConstructorCheck.cpp
+++ b/clang-tidy/google/ExplicitConstructorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ExplicitConstructorCheck.cpp - clang-tidy ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/ExplicitConstructorCheck.h b/clang-tidy/google/ExplicitConstructorCheck.h
index 81e6679..b6a76f6 100644
--- a/clang-tidy/google/ExplicitConstructorCheck.h
+++ b/clang-tidy/google/ExplicitConstructorCheck.h
@@ -1,16 +1,15 @@
 //===--- ExplicitConstructorCheck.h - clang-tidy ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICITCONSTRUCTORCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICITCONSTRUCTORCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/ExplicitMakePairCheck.cpp b/clang-tidy/google/ExplicitMakePairCheck.cpp
index 7e82751..51df3a8 100644
--- a/clang-tidy/google/ExplicitMakePairCheck.cpp
+++ b/clang-tidy/google/ExplicitMakePairCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ExplicitMakePairCheck.cpp - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/ExplicitMakePairCheck.h b/clang-tidy/google/ExplicitMakePairCheck.h
index a29825f..8029384 100644
--- a/clang-tidy/google/ExplicitMakePairCheck.h
+++ b/clang-tidy/google/ExplicitMakePairCheck.h
@@ -1,16 +1,15 @@
 //===--- ExplicitMakePairCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICITMAKEPAIRCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICITMAKEPAIRCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp
index f706470..8096d65 100644
--- a/clang-tidy/google/FunctionNamingCheck.cpp
+++ b/clang-tidy/google/FunctionNamingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- FunctionNamingCheck.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -94,12 +93,16 @@
   if (!getLangOpts().ObjC)
     return;
 
-  // Match function declarations that are not in system headers and are not
-  // main.
+  // Enforce Objective-C function naming conventions on all functions except:
+  // • Functions defined in system headers.
+  // • C++ member functions.
+  // • Namespaced functions.
+  // • Implicitly defined functions.
+  // • The main function.
   Finder->addMatcher(
       functionDecl(
           unless(anyOf(isExpansionInSystemHeader(), cxxMethodDecl(),
-                       hasAncestor(namespaceDecl()), isMain(),
+                       hasAncestor(namespaceDecl()), isMain(), isImplicit(),
                        matchesName(validFunctionNameRegex(true)),
                        allOf(isStaticStorageClass(),
                              matchesName(validFunctionNameRegex(false))))))
diff --git a/clang-tidy/google/FunctionNamingCheck.h b/clang-tidy/google/FunctionNamingCheck.h
index 46499e9..c45f87d 100644
--- a/clang-tidy/google/FunctionNamingCheck.h
+++ b/clang-tidy/google/FunctionNamingCheck.h
@@ -1,16 +1,15 @@
 //===--- FunctionNamingCheck.h - clang-tidy ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_FUNCTION_NAMING_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_FUNCTION_NAMING_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
diff --git a/clang-tidy/google/GlobalNamesInHeadersCheck.cpp b/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
index 9f03f7d..a83e636 100644
--- a/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
+++ b/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
@@ -1,9 +1,8 @@
 //===--- GlobalNamesInHeadersCheck.cpp - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/GlobalNamesInHeadersCheck.h b/clang-tidy/google/GlobalNamesInHeadersCheck.h
index 79a6e28..730ef60 100644
--- a/clang-tidy/google/GlobalNamesInHeadersCheck.h
+++ b/clang-tidy/google/GlobalNamesInHeadersCheck.h
@@ -1,16 +1,15 @@
 //===--- GlobalNamesInHeadersCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBALNAMESINHEADERSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBALNAMESINHEADERSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/HeaderFileExtensionsUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp
index 6388523..ce83390 100644
--- a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp
+++ b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- GlobalVariableDeclarationCheck.cpp - clang-tidy-------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -80,12 +79,16 @@
 void GlobalVariableDeclarationCheck::check(
     const MatchFinder::MatchResult &Result) {
   if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("global_var")) {
+    if (Decl->isStaticDataMember())
+      return;
     diag(Decl->getLocation(),
          "non-const global variable '%0' must have a name which starts with "
          "'g[A-Z]'")
         << Decl->getName() << generateFixItHint(Decl, false);
   }
   if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("global_const")) {
+    if (Decl->isStaticDataMember())
+      return;
     diag(Decl->getLocation(),
          "const global variable '%0' must have a name which starts with "
          "an appropriate prefix")
diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.h b/clang-tidy/google/GlobalVariableDeclarationCheck.h
index ed0352b..9ea0136 100644
--- a/clang-tidy/google/GlobalVariableDeclarationCheck.h
+++ b/clang-tidy/google/GlobalVariableDeclarationCheck.h
@@ -1,16 +1,15 @@
 //===--- GlobalVariableDeclarationCheck.h - clang-tidy-----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_GLOBAL_VARIABLE_DECLARATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OBJC_GLOBAL_VARIABLE_DECLARATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/GoogleTidyModule.cpp b/clang-tidy/google/GoogleTidyModule.cpp
index 7996cfc..c2a9ec5 100644
--- a/clang-tidy/google/GoogleTidyModule.cpp
+++ b/clang-tidy/google/GoogleTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- GoogleTidyModule.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,6 +14,7 @@
 #include "../readability/NamespaceCommentCheck.h"
 #include "AvoidCStyleCastsCheck.h"
 #include "AvoidThrowingObjCExceptionCheck.h"
+#include "AvoidUnderscoreInGoogletestNameCheck.h"
 #include "DefaultArgumentsCheck.h"
 #include "ExplicitConstructorCheck.h"
 #include "ExplicitMakePairCheck.h"
@@ -61,6 +61,9 @@
         "google-runtime-operator");
     CheckFactories.registerCheck<runtime::NonConstReferences>(
         "google-runtime-references");
+    CheckFactories
+        .registerCheck<readability::AvoidUnderscoreInGoogletestNameCheck>(
+            "google-readability-avoid-underscore-in-googletest-name");
     CheckFactories.registerCheck<readability::AvoidCStyleCastsCheck>(
         "google-readability-casting");
     CheckFactories.registerCheck<readability::TodoCommentCheck>(
diff --git a/clang-tidy/google/IntegerTypesCheck.cpp b/clang-tidy/google/IntegerTypesCheck.cpp
index 07ee081..fb6fd3b 100644
--- a/clang-tidy/google/IntegerTypesCheck.cpp
+++ b/clang-tidy/google/IntegerTypesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IntegerTypesCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -55,7 +54,9 @@
 
 void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) {
   // Find all TypeLocs. The relevant Style Guide rule only applies to C++.
-  if (!getLangOpts().CPlusPlus)
+  // This check is also not applied in Objective-C++ sources as Objective-C
+  // often uses built-in integer types other than `int`.
+  if (!getLangOpts().CPlusPlus || getLangOpts().ObjC)
     return;
   // Match any integer types, unless they are passed to a printf-based API:
   //
diff --git a/clang-tidy/google/IntegerTypesCheck.h b/clang-tidy/google/IntegerTypesCheck.h
index 8d8f903..518e31e 100644
--- a/clang-tidy/google/IntegerTypesCheck.h
+++ b/clang-tidy/google/IntegerTypesCheck.h
@@ -1,16 +1,15 @@
 //===--- IntegerTypesCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_INTEGERTYPESCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_INTEGERTYPESCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 #include <memory>
 
diff --git a/clang-tidy/google/NonConstReferences.cpp b/clang-tidy/google/NonConstReferences.cpp
index 856bc5b..6e0fcfe 100644
--- a/clang-tidy/google/NonConstReferences.cpp
+++ b/clang-tidy/google/NonConstReferences.cpp
@@ -1,9 +1,8 @@
 //===--- NonConstReferences.cpp - clang-tidy --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/NonConstReferences.h b/clang-tidy/google/NonConstReferences.h
index a665813..548448b 100644
--- a/clang-tidy/google/NonConstReferences.h
+++ b/clang-tidy/google/NonConstReferences.h
@@ -1,16 +1,15 @@
 //===--- NonConstReferences.h - clang-tidy ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_NON_CONST_REFERENCES_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_NON_CONST_REFERENCES_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/OverloadedUnaryAndCheck.cpp b/clang-tidy/google/OverloadedUnaryAndCheck.cpp
index 57702c7..1d4d104 100644
--- a/clang-tidy/google/OverloadedUnaryAndCheck.cpp
+++ b/clang-tidy/google/OverloadedUnaryAndCheck.cpp
@@ -1,9 +1,8 @@
 //===--- OverloadedUnaryAndCheck.cpp - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/OverloadedUnaryAndCheck.h b/clang-tidy/google/OverloadedUnaryAndCheck.h
index 5492eba..bafbd29 100644
--- a/clang-tidy/google/OverloadedUnaryAndCheck.h
+++ b/clang-tidy/google/OverloadedUnaryAndCheck.h
@@ -1,16 +1,15 @@
 //===--- OverloadedUnaryAndCheck.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OVERLOADEDUNARYANDCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_OVERLOADEDUNARYANDCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/google/TodoCommentCheck.cpp b/clang-tidy/google/TodoCommentCheck.cpp
index f1c79ce..40d65a6 100644
--- a/clang-tidy/google/TodoCommentCheck.cpp
+++ b/clang-tidy/google/TodoCommentCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TodoCommentCheck.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -56,8 +55,10 @@
       Handler(llvm::make_unique<TodoCommentHandler>(
           *this, Context->getOptions().User)) {}
 
-void TodoCommentCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addCommentHandler(Handler.get());
+void TodoCommentCheck::registerPPCallbacks(const SourceManager &SM,
+                                           Preprocessor *PP,
+                                           Preprocessor *ModuleExpanderPP) {
+  PP->addCommentHandler(Handler.get());
 }
 
 } // namespace readability
diff --git a/clang-tidy/google/TodoCommentCheck.h b/clang-tidy/google/TodoCommentCheck.h
index dbdc366..d1343b7 100644
--- a/clang-tidy/google/TodoCommentCheck.h
+++ b/clang-tidy/google/TodoCommentCheck.h
@@ -1,16 +1,15 @@
 //===--- TodoCommentCheck.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_TODOCOMMENTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_TODOCOMMENTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -23,7 +22,8 @@
 class TodoCommentCheck : public ClangTidyCheck {
 public:
   TodoCommentCheck(StringRef Name, ClangTidyContext *Context);
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 
 private:
   class TodoCommentHandler;
diff --git a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
index 94e1729..cdb6149 100644
--- a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
+++ b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnnamedNamespaceInHeaderCheck.cpp - clang-tidy ---------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
index 4d310f5..517ff8b 100644
--- a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
+++ b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
@@ -1,16 +1,15 @@
 //===--- UnnamedNamespaceInHeaderCheck.h - clang-tidy -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UNNAMEDNAMESPACEINHEADERCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UNNAMEDNAMESPACEINHEADERCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/HeaderFileExtensionsUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp b/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp
index 7490f02..f11a7d1 100644
--- a/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp
+++ b/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UsingNamespaceDirectiveCheck.cpp - clang-tidy ----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/UsingNamespaceDirectiveCheck.h b/clang-tidy/google/UsingNamespaceDirectiveCheck.h
index 2be65c1..c9bcf48 100644
--- a/clang-tidy/google/UsingNamespaceDirectiveCheck.h
+++ b/clang-tidy/google/UsingNamespaceDirectiveCheck.h
@@ -1,16 +1,15 @@
 //===--- UsingNamespaceDirectiveCheck.h - clang-tidy ------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_USINGNAMESPACEDIRECTIVECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_USINGNAMESPACEDIRECTIVECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
index 890a56f..a588428 100644
--- a/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
+++ b/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ExceptionBaseclassCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/ExceptionBaseclassCheck.h b/clang-tidy/hicpp/ExceptionBaseclassCheck.h
index 778979d..1022013 100644
--- a/clang-tidy/hicpp/ExceptionBaseclassCheck.h
+++ b/clang-tidy/hicpp/ExceptionBaseclassCheck.h
@@ -1,9 +1,8 @@
 //===--- ExceptionBaseclassCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/HICPPTidyModule.cpp b/clang-tidy/hicpp/HICPPTidyModule.cpp
index 5b5f451..ad367dc 100644
--- a/clang-tidy/hicpp/HICPPTidyModule.cpp
+++ b/clang-tidy/hicpp/HICPPTidyModule.cpp
@@ -1,9 +1,8 @@
 //===------- HICPPTidyModule.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/LICENSE.TXT b/clang-tidy/hicpp/LICENSE.TXT
index fb8f513..b432d4e 100644
--- a/clang-tidy/hicpp/LICENSE.TXT
+++ b/clang-tidy/hicpp/LICENSE.TXT
@@ -1,8 +1,8 @@
 ------------------------------------------------------------------------------
 clang-tidy High-Integrity C++ Files
 ------------------------------------------------------------------------------
-All clang-tidy files are licensed under the LLVM license with the following
-additions:
+All clang-tidy files are licensed under the same terms as the rest of the LLVM
+project with the following additions:
 
 Any file referencing a High-Integrity C++ Coding guideline:
 
diff --git a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp
index 03f4edb..e30b4f1 100644
--- a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp
+++ b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MultiwayPathsCoveredCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h
index 498dad6..d21afbb5 100644
--- a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h
+++ b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h
@@ -1,9 +1,8 @@
 //===--- MultiwayPathsCoveredCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/NoAssemblerCheck.cpp b/clang-tidy/hicpp/NoAssemblerCheck.cpp
index 06969a8..af5a1cb 100644
--- a/clang-tidy/hicpp/NoAssemblerCheck.cpp
+++ b/clang-tidy/hicpp/NoAssemblerCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NoAssemblerCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/NoAssemblerCheck.h b/clang-tidy/hicpp/NoAssemblerCheck.h
index 416ccb0..d91c5de 100644
--- a/clang-tidy/hicpp/NoAssemblerCheck.h
+++ b/clang-tidy/hicpp/NoAssemblerCheck.h
@@ -1,9 +1,8 @@
 //===--- NoAssemblerCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/SignedBitwiseCheck.cpp b/clang-tidy/hicpp/SignedBitwiseCheck.cpp
index 9738369..781a443 100644
--- a/clang-tidy/hicpp/SignedBitwiseCheck.cpp
+++ b/clang-tidy/hicpp/SignedBitwiseCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SignedBitwiseCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/hicpp/SignedBitwiseCheck.h b/clang-tidy/hicpp/SignedBitwiseCheck.h
index 24338ad..34d5f09 100644
--- a/clang-tidy/hicpp/SignedBitwiseCheck.h
+++ b/clang-tidy/hicpp/SignedBitwiseCheck.h
@@ -1,9 +1,8 @@
 //===--- SignedBitwiseCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/CMakeLists.txt b/clang-tidy/llvm/CMakeLists.txt
index ce69c05..085fb85 100644
--- a/clang-tidy/llvm/CMakeLists.txt
+++ b/clang-tidy/llvm/CMakeLists.txt
@@ -4,6 +4,7 @@
   HeaderGuardCheck.cpp
   IncludeOrderCheck.cpp
   LLVMTidyModule.cpp
+  PreferIsaOrDynCastInConditionalsCheck.cpp
   TwineLocalCheck.cpp
 
   LINK_LIBS
diff --git a/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tidy/llvm/HeaderGuardCheck.cpp
index c0e449e..bde460c 100644
--- a/clang-tidy/llvm/HeaderGuardCheck.cpp
+++ b/clang-tidy/llvm/HeaderGuardCheck.cpp
@@ -1,9 +1,8 @@
 //===--- HeaderGuardCheck.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/HeaderGuardCheck.h b/clang-tidy/llvm/HeaderGuardCheck.h
index ca2d7ef..46021e2 100644
--- a/clang-tidy/llvm/HeaderGuardCheck.h
+++ b/clang-tidy/llvm/HeaderGuardCheck.h
@@ -1,9 +1,8 @@
 //===--- HeaderGuardCheck.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/IncludeOrderCheck.cpp b/clang-tidy/llvm/IncludeOrderCheck.cpp
index f1fdb39..9c3ab0b 100644
--- a/clang-tidy/llvm/IncludeOrderCheck.cpp
+++ b/clang-tidy/llvm/IncludeOrderCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,7 +20,8 @@
 namespace {
 class IncludeOrderPPCallbacks : public PPCallbacks {
 public:
-  explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check, SourceManager &SM)
+  explicit IncludeOrderPPCallbacks(ClangTidyCheck &Check,
+                                   const SourceManager &SM)
       : LookForMainModule(true), Check(Check), SM(SM) {}
 
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
@@ -46,14 +46,14 @@
   bool LookForMainModule;
 
   ClangTidyCheck &Check;
-  SourceManager &SM;
+  const SourceManager &SM;
 };
 } // namespace
 
-void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      ::llvm::make_unique<IncludeOrderPPCallbacks>(
-          *this, Compiler.getSourceManager()));
+void IncludeOrderCheck::registerPPCallbacks(const SourceManager &SM,
+                                            Preprocessor *PP,
+                                            Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(::llvm::make_unique<IncludeOrderPPCallbacks>(*this, SM));
 }
 
 static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
diff --git a/clang-tidy/llvm/IncludeOrderCheck.h b/clang-tidy/llvm/IncludeOrderCheck.h
index ad876b9..b95c380 100644
--- a/clang-tidy/llvm/IncludeOrderCheck.h
+++ b/clang-tidy/llvm/IncludeOrderCheck.h
@@ -1,16 +1,15 @@
 //===--- IncludeOrderCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_INCLUDE_ORDER_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_INCLUDE_ORDER_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -23,7 +22,8 @@
 public:
   IncludeOrderCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace llvm
diff --git a/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tidy/llvm/LLVMTidyModule.cpp
index ea46ca9..fb7b52a 100644
--- a/clang-tidy/llvm/LLVMTidyModule.cpp
+++ b/clang-tidy/llvm/LLVMTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- LLVMTidyModule.cpp - clang-tidy ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,6 +12,7 @@
 #include "../readability/NamespaceCommentCheck.h"
 #include "HeaderGuardCheck.h"
 #include "IncludeOrderCheck.h"
+#include "PreferIsaOrDynCastInConditionalsCheck.h"
 #include "TwineLocalCheck.h"
 
 namespace clang {
@@ -26,6 +26,8 @@
     CheckFactories.registerCheck<IncludeOrderCheck>("llvm-include-order");
     CheckFactories.registerCheck<readability::NamespaceCommentCheck>(
         "llvm-namespace-comment");
+    CheckFactories.registerCheck<PreferIsaOrDynCastInConditionalsCheck>(
+        "llvm-prefer-isa-or-dyn-cast-in-conditionals");
     CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
   }
 };
diff --git a/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
new file mode 100644
index 0000000..252ef3b
--- /dev/null
+++ b/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp
@@ -0,0 +1,135 @@
+//===--- PreferIsaOrDynCastInConditionalsCheck.cpp - clang-tidy
+//---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PreferIsaOrDynCastInConditionalsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ast_matchers {
+AST_MATCHER(Expr, isMacroID) { return Node.getExprLoc().isMacroID(); }
+} // namespace ast_matchers
+
+namespace tidy {
+namespace llvm {
+
+void PreferIsaOrDynCastInConditionalsCheck::registerMatchers(
+    MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  auto Condition = hasCondition(implicitCastExpr(has(
+      callExpr(
+          allOf(unless(isMacroID()), unless(cxxMemberCallExpr()),
+                anyOf(callee(namedDecl(hasName("cast"))),
+                      callee(namedDecl(hasName("dyn_cast")).bind("dyn_cast")))))
+          .bind("call"))));
+
+  auto Any = anyOf(
+      has(declStmt(containsDeclaration(
+          0,
+          varDecl(hasInitializer(
+              callExpr(allOf(unless(isMacroID()), unless(cxxMemberCallExpr()),
+                             callee(namedDecl(hasName("cast")))))
+                  .bind("assign")))))),
+      Condition);
+
+  auto CallExpression =
+      callExpr(
+          allOf(unless(isMacroID()), unless(cxxMemberCallExpr()),
+                allOf(callee(namedDecl(anyOf(hasName("isa"), hasName("cast"),
+                                             hasName("cast_or_null"),
+                                             hasName("dyn_cast"),
+                                             hasName("dyn_cast_or_null")))
+                                 .bind("func")),
+                      hasArgument(0, anyOf(declRefExpr().bind("arg"),
+                                           cxxMemberCallExpr().bind("arg"))))))
+          .bind("rhs");
+
+  Finder->addMatcher(
+      stmt(anyOf(ifStmt(Any), whileStmt(Any), doStmt(Condition),
+                 binaryOperator(
+                     allOf(unless(isExpansionInFileMatching(
+                               "llvm/include/llvm/Support/Casting.h")),
+                           hasOperatorName("&&"),
+                           hasLHS(implicitCastExpr().bind("lhs")),
+                           hasRHS(anyOf(implicitCastExpr(has(CallExpression)),
+                                        CallExpression))))
+                     .bind("and"))),
+      this);
+}
+
+void PreferIsaOrDynCastInConditionalsCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  if (const auto *MatchedDecl = Result.Nodes.getNodeAs<CallExpr>("assign")) {
+    SourceLocation StartLoc = MatchedDecl->getCallee()->getExprLoc();
+    SourceLocation EndLoc =
+        StartLoc.getLocWithOffset(StringRef("cast").size() - 1);
+
+    diag(MatchedDecl->getBeginLoc(),
+         "cast<> in conditional will assert rather than return a null pointer")
+        << FixItHint::CreateReplacement(SourceRange(StartLoc, EndLoc),
+                                        "dyn_cast");
+  } else if (const auto *MatchedDecl =
+                 Result.Nodes.getNodeAs<CallExpr>("call")) {
+    SourceLocation StartLoc = MatchedDecl->getCallee()->getExprLoc();
+    SourceLocation EndLoc =
+        StartLoc.getLocWithOffset(StringRef("cast").size() - 1);
+
+    StringRef Message =
+        "cast<> in conditional will assert rather than return a null pointer";
+    if (Result.Nodes.getNodeAs<NamedDecl>("dyn_cast"))
+      Message = "return value from dyn_cast<> not used";
+
+    diag(MatchedDecl->getBeginLoc(), Message)
+        << FixItHint::CreateReplacement(SourceRange(StartLoc, EndLoc), "isa");
+  } else if (const auto *MatchedDecl =
+                 Result.Nodes.getNodeAs<BinaryOperator>("and")) {
+    const auto *LHS = Result.Nodes.getNodeAs<ImplicitCastExpr>("lhs");
+    const auto *RHS = Result.Nodes.getNodeAs<CallExpr>("rhs");
+    const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg");
+    const auto *Func = Result.Nodes.getNodeAs<NamedDecl>("func");
+
+    assert(LHS && "LHS is null");
+    assert(RHS && "RHS is null");
+    assert(Arg && "Arg is null");
+    assert(Func && "Func is null");
+
+    StringRef LHSString(Lexer::getSourceText(
+        CharSourceRange::getTokenRange(LHS->getSourceRange()),
+        *Result.SourceManager, getLangOpts()));
+
+    StringRef ArgString(Lexer::getSourceText(
+        CharSourceRange::getTokenRange(Arg->getSourceRange()),
+        *Result.SourceManager, getLangOpts()));
+
+    if (ArgString != LHSString)
+      return;
+
+    StringRef RHSString(Lexer::getSourceText(
+        CharSourceRange::getTokenRange(RHS->getSourceRange()),
+        *Result.SourceManager, getLangOpts()));
+
+    std::string Replacement("isa_and_nonnull");
+    Replacement += RHSString.substr(Func->getName().size());
+
+    diag(MatchedDecl->getBeginLoc(),
+         "isa_and_nonnull<> is preferred over an explicit test for null "
+         "followed by calling isa<>")
+        << FixItHint::CreateReplacement(SourceRange(MatchedDecl->getBeginLoc(),
+                                                    MatchedDecl->getEndLoc()),
+                                        Replacement);
+  }
+}
+
+} // namespace llvm
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h b/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h
new file mode 100644
index 0000000..354693c
--- /dev/null
+++ b/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.h
@@ -0,0 +1,64 @@
+//===--- PreferIsaOrDynCastInConditionalsCheck.h - clang-tidy ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_AVOIDCASTINCONDITIONALCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_AVOIDCASTINCONDITIONALCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace llvm {
+
+/// \brief Looks at conditionals and finds and replaces cases of ``cast<>``, which will
+/// assert rather than return a null pointer, and ``dyn_cast<>`` where
+/// the return value is not captured.  Additionally, finds and replaces cases that match the
+/// pattern ``var && isa<X>(var)``, where ``var`` is evaluated twice.
+///
+/// Finds cases like these:
+/// \code
+///  if (auto x = cast<X>(y)) {}
+///  // is replaced by:
+///  if (auto x = dyn_cast<X>(y)) {}
+///
+///  if (cast<X>(y)) {}
+///  // is replaced by:
+///  if (isa<X>(y)) {}
+///
+///  if (dyn_cast<X>(y)) {}
+///  // is replaced by:
+///  if (isa<X>(y)) {}
+///
+///  if (var && isa<T>(var)) {}
+///  // is replaced by:
+///  if (isa_and_nonnull<T>(var.foo())) {}
+/// \endcode
+///
+///  // Other cases are ignored, e.g.:
+/// \code
+///  if (auto f = cast<Z>(y)->foo()) {}
+///  if (cast<Z>(y)->foo()) {}
+///  if (X.cast(y)) {}
+/// \endcode
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/llvm-prefer-isa-or-dyn-cast-in-conditionals.html
+class PreferIsaOrDynCastInConditionalsCheck : public ClangTidyCheck {
+public:
+  PreferIsaOrDynCastInConditionalsCheck(StringRef Name,
+                                        ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace llvm
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_AVOIDCASTINCONDITIONALCHECK_H
diff --git a/clang-tidy/llvm/TwineLocalCheck.cpp b/clang-tidy/llvm/TwineLocalCheck.cpp
index 744ddd9..2fddf6d 100644
--- a/clang-tidy/llvm/TwineLocalCheck.cpp
+++ b/clang-tidy/llvm/TwineLocalCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TwineLocalCheck.cpp - clang-tidy ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/TwineLocalCheck.h b/clang-tidy/llvm/TwineLocalCheck.h
index 9f7979b..0cb655a 100644
--- a/clang-tidy/llvm/TwineLocalCheck.h
+++ b/clang-tidy/llvm/TwineLocalCheck.h
@@ -1,16 +1,15 @@
 //===--- TwineLocalCheck.h - clang-tidy -------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_TWINE_LOCAL_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_TWINE_LOCAL_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/DefinitionsInHeadersCheck.cpp b/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
index f4dab39..a36f307 100644
--- a/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
+++ b/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DefinitionsInHeadersCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/DefinitionsInHeadersCheck.h b/clang-tidy/misc/DefinitionsInHeadersCheck.h
index 428b05c..dda6d69 100644
--- a/clang-tidy/misc/DefinitionsInHeadersCheck.h
+++ b/clang-tidy/misc/DefinitionsInHeadersCheck.h
@@ -1,16 +1,15 @@
 //===--- DefinitionsInHeadersCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DEFINITIONS_IN_HEADERS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DEFINITIONS_IN_HEADERS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/HeaderFileExtensionsUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/misc/MiscTidyModule.cpp b/clang-tidy/misc/MiscTidyModule.cpp
index dd9061a..ba160d1 100644
--- a/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tidy/misc/MiscTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- MiscTidyModule.cpp - clang-tidy ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/MisplacedConstCheck.cpp b/clang-tidy/misc/MisplacedConstCheck.cpp
index 515b22c..1e1b2b0 100644
--- a/clang-tidy/misc/MisplacedConstCheck.cpp
+++ b/clang-tidy/misc/MisplacedConstCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MisplacedConstCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/MisplacedConstCheck.h b/clang-tidy/misc/MisplacedConstCheck.h
index 410edf7..55803b4 100644
--- a/clang-tidy/misc/MisplacedConstCheck.h
+++ b/clang-tidy/misc/MisplacedConstCheck.h
@@ -1,16 +1,15 @@
 //===--- MisplacedConstCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISPLACED_CONST_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISPLACED_CONST_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/NewDeleteOverloadsCheck.cpp b/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
index 5e29119..a96d190 100644
--- a/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
+++ b/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NewDeleteOverloadsCheck.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/NewDeleteOverloadsCheck.h b/clang-tidy/misc/NewDeleteOverloadsCheck.h
index 3e99892..cd23a74 100644
--- a/clang-tidy/misc/NewDeleteOverloadsCheck.h
+++ b/clang-tidy/misc/NewDeleteOverloadsCheck.h
@@ -1,16 +1,15 @@
 //===--- NewDeleteOverloadsCheck.h - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NEWDELETEOVERLOADS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NEWDELETEOVERLOADS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/SmallVector.h"
 #include <map>
 
diff --git a/clang-tidy/misc/NonCopyableObjects.cpp b/clang-tidy/misc/NonCopyableObjects.cpp
index de15275..53cc273 100644
--- a/clang-tidy/misc/NonCopyableObjects.cpp
+++ b/clang-tidy/misc/NonCopyableObjects.cpp
@@ -1,9 +1,8 @@
 //===--- NonCopyableObjects.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/NonCopyableObjects.h b/clang-tidy/misc/NonCopyableObjects.h
index 38a45fd..6529fdd 100644
--- a/clang-tidy/misc/NonCopyableObjects.h
+++ b/clang-tidy/misc/NonCopyableObjects.h
@@ -1,16 +1,15 @@
 //===--- NonCopyableObjects.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
index c0bdbfb..7f57fec 100644
--- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
+++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NonPrivateMemberVariablesInClassesCheck.cpp - clang-tidy ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,8 +22,8 @@
   return std::distance(Node.method_begin(), Node.method_end()) != 0;
 }
 
-AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) {
-  return hasMethod(unless(isStaticStorageClass()))
+AST_MATCHER(CXXRecordDecl, hasNonStaticNonImplicitMethod) {
+  return hasMethod(unless(anyOf(isStaticStorageClass(), isImplicit())))
       .matches(Node, Finder, Builder);
 }
 
@@ -67,10 +66,11 @@
       IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
 
   // We only want the records that not only contain the mutable data (non-static
-  // member variables), but also have some logic (non-static member functions).
-  // We may optionally ignore records where all the member variables are public.
+  // member variables), but also have some logic (non-static, non-implicit
+  // member functions).  We may optionally ignore records where all the member
+  // variables are public.
   Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(),
-                                   hasNonStaticMethod(),
+                                   hasNonStaticNonImplicitMethod(),
                                    unless(ShouldIgnoreRecord),
                                    forEach(InterestingField.bind("field")))
                          .bind("record"),
diff --git a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
index c39e356..7bc4425 100644
--- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
+++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
@@ -1,16 +1,15 @@
 //===--- NonPrivateMemberVariablesInClassesCheck.h - clang-tidy -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tidy/misc/RedundantExpressionCheck.cpp
index e9b0f4d..33a8b9a 100644
--- a/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantExpressionCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/RedundantExpressionCheck.h b/clang-tidy/misc/RedundantExpressionCheck.h
index c0f8bf5..d07e2b7 100644
--- a/clang-tidy/misc/RedundantExpressionCheck.h
+++ b/clang-tidy/misc/RedundantExpressionCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantExpressionCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANT_EXPRESSION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REDUNDANT_EXPRESSION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/StaticAssertCheck.cpp b/clang-tidy/misc/StaticAssertCheck.cpp
index 583ed7a..a2f3179 100644
--- a/clang-tidy/misc/StaticAssertCheck.cpp
+++ b/clang-tidy/misc/StaticAssertCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StaticAssertCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -146,7 +145,7 @@
   const LangOptions &Opts = ASTCtx->getLangOpts();
   const SourceManager &SM = ASTCtx->getSourceManager();
 
-  llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getFileID(AssertLoc));
+  const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getFileID(AssertLoc));
   if (!Buffer)
     return SourceLocation();
 
diff --git a/clang-tidy/misc/StaticAssertCheck.h b/clang-tidy/misc/StaticAssertCheck.h
index faefce1..b6d7211 100644
--- a/clang-tidy/misc/StaticAssertCheck.h
+++ b/clang-tidy/misc/StaticAssertCheck.h
@@ -1,16 +1,15 @@
 //===--- StaticAssertCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STATICASSERTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STATICASSERTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
 
diff --git a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
index 759c3f0..b7077a1 100644
--- a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
+++ b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ThrowByValueCatchByReferenceCheck.cpp - clang-tidy----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
index a2e7df7..b3c8935 100644
--- a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
+++ b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
@@ -1,16 +1,15 @@
 //===--- ThrowByValueCatchByReferenceCheck.h - clang-tidy--------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_THROW_BY_VALUE_CATCH_BY_REFERENCE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_THROW_BY_VALUE_CATCH_BY_REFERENCE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
index 84dd410..8c87dae 100644
--- a/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
+++ b/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnconventionalAssignOperatorCheck.cpp - clang-tidy -----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UnconventionalAssignOperatorCheck.h b/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
index ee91dca..86e0938 100644
--- a/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
+++ b/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
@@ -1,16 +1,15 @@
 //===--- UnconventionalAssignOperatorCheck.h - clang-tidy -------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_ASSIGNOPERATORSIGNATURECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp b/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp
index 99758d3..9363fa9 100644
--- a/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp
+++ b/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UniqueptrResetReleaseCheck.cpp - clang-tidy ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UniqueptrResetReleaseCheck.h b/clang-tidy/misc/UniqueptrResetReleaseCheck.h
index cf18a5a..b302f15 100644
--- a/clang-tidy/misc/UniqueptrResetReleaseCheck.h
+++ b/clang-tidy/misc/UniqueptrResetReleaseCheck.h
@@ -1,16 +1,15 @@
 //===--- UniqueptrResetReleaseCheck.h - clang-tidy --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNIQUEPTRRESETRELEASECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNIQUEPTRRESETRELEASECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/UnusedAliasDeclsCheck.cpp b/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
index 4beb432..c301aea 100644
--- a/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
+++ b/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnusedAliasDeclsCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UnusedAliasDeclsCheck.h b/clang-tidy/misc/UnusedAliasDeclsCheck.h
index 8cce375..f25e8d8 100644
--- a/clang-tidy/misc/UnusedAliasDeclsCheck.h
+++ b/clang-tidy/misc/UnusedAliasDeclsCheck.h
@@ -1,16 +1,15 @@
 //===--- UnusedAliasDeclsCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_ALIAS_DECLS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_ALIAS_DECLS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/DenseMap.h"
 
 namespace clang {
diff --git a/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tidy/misc/UnusedParametersCheck.cpp
index cee0915..01dce8f 100644
--- a/clang-tidy/misc/UnusedParametersCheck.cpp
+++ b/clang-tidy/misc/UnusedParametersCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnusedParametersCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UnusedParametersCheck.h b/clang-tidy/misc/UnusedParametersCheck.h
index b9bae26..7e9b8c9 100644
--- a/clang-tidy/misc/UnusedParametersCheck.h
+++ b/clang-tidy/misc/UnusedParametersCheck.h
@@ -1,16 +1,15 @@
 //===--- UnusedParametersCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_PARAMETERS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_PARAMETERS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index 48009b5..3dabca9 100644
--- a/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ b/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnusedUsingDeclsCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -155,7 +154,10 @@
   for (const auto &Context : Contexts) {
     if (!Context.IsUsed) {
       diag(Context.FoundUsingDecl->getLocation(), "using decl %0 is unused")
-          << Context.FoundUsingDecl
+          << Context.FoundUsingDecl;
+      // Emit a fix and a fix description of the check;
+      diag(Context.FoundUsingDecl->getLocation(),
+           /*FixDescription=*/"remove the using", DiagnosticIDs::Note)
           << FixItHint::CreateRemoval(Context.UsingDeclRange);
     }
   }
diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.h b/clang-tidy/misc/UnusedUsingDeclsCheck.h
index 2a41a8f..2e46f3c 100644
--- a/clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ b/clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -1,16 +1,15 @@
 //===--- UnusedUsingDeclsCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include <vector>
 
diff --git a/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tidy/modernize/AvoidBindCheck.cpp
index bd47702..c51b6e8 100644
--- a/clang-tidy/modernize/AvoidBindCheck.cpp
+++ b/clang-tidy/modernize/AvoidBindCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidBindCheck.cpp - clang-tidy-----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -170,7 +169,7 @@
   Ref->printPretty(Stream, nullptr, Result.Context->getPrintingPolicy());
   Stream << "(";
   addFunctionCallArgs(Args, Stream);
-  Stream << "); };";
+  Stream << "); }";
 
   Diag << FixItHint::CreateReplacement(MatchedDecl->getSourceRange(),
                                        Stream.str());
diff --git a/clang-tidy/modernize/AvoidBindCheck.h b/clang-tidy/modernize/AvoidBindCheck.h
index 5ae0241..4b39330 100644
--- a/clang-tidy/modernize/AvoidBindCheck.h
+++ b/clang-tidy/modernize/AvoidBindCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidBindCheck.h - clang-tidy---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOID_BIND_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOID_BIND_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tidy/modernize/AvoidCArraysCheck.cpp
index dd19483..e3dffd0 100644
--- a/clang-tidy/modernize/AvoidCArraysCheck.cpp
+++ b/clang-tidy/modernize/AvoidCArraysCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidCArraysCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,6 +30,12 @@
   return Node.isExternCContext();
 }
 
+AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) {
+  const clang::DeclContext *DC = Node.getDeclContext();
+  const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(DC);
+  return FD ? FD->isMain() : false;
+}
+
 } // namespace
 
 namespace clang {
@@ -44,7 +49,8 @@
 
   Finder->addMatcher(
       typeLoc(hasValidBeginLoc(), hasType(arrayType()),
-              unless(anyOf(hasParent(varDecl(isExternC())),
+              unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())),
+                           hasParent(varDecl(isExternC())),
                            hasParent(fieldDecl(
                                hasParent(recordDecl(isExternCContext())))),
                            hasAncestor(functionDecl(isExternC())))))
diff --git a/clang-tidy/modernize/AvoidCArraysCheck.h b/clang-tidy/modernize/AvoidCArraysCheck.h
index afef884..48e38bf 100644
--- a/clang-tidy/modernize/AvoidCArraysCheck.h
+++ b/clang-tidy/modernize/AvoidCArraysCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidCArraysCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCARRAYSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCARRAYSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
index bef85f7..c1539bf 100644
--- a/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
+++ b/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ConcatNestedNamespacesCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -40,6 +39,7 @@
                                 const SourceRange &ReplacementRange,
                                 const SourceManager &Sources,
                                 const LangOptions &LangOpts) {
+  // FIXME: This logic breaks when there is a comment with ':'s in the middle.
   CharSourceRange TextRange =
       Lexer::getAsCharRange(ReplacementRange, Sources, LangOpts);
   StringRef CurrentNamespacesText =
diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
index 547690d..2c589fc 100644
--- a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
+++ b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
@@ -1,16 +1,15 @@
 //===--- ConcatNestedNamespacesCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_CONCATNESTEDNAMESPACESCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_CONCATNESTEDNAMESPACESCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 
diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
index 1ff3f89..af4d47c 100644
--- a/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
+++ b/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DeprecatedHeadersCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -41,11 +40,11 @@
 };
 } // namespace
 
-void DeprecatedHeadersCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  if (this->getLangOpts().CPlusPlus) {
-    Compiler.getPreprocessor().addPPCallbacks(
-        ::llvm::make_unique<IncludeModernizePPCallbacks>(*this,
-                                                         this->getLangOpts()));
+void DeprecatedHeadersCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  if (getLangOpts().CPlusPlus) {
+    PP->addPPCallbacks(
+        ::llvm::make_unique<IncludeModernizePPCallbacks>(*this, getLangOpts()));
   }
 }
 
diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tidy/modernize/DeprecatedHeadersCheck.h
index ee7254e..dfe6b85 100644
--- a/clang-tidy/modernize/DeprecatedHeadersCheck.h
+++ b/clang-tidy/modernize/DeprecatedHeadersCheck.h
@@ -1,16 +1,15 @@
 //===--- DeprecatedHeadersCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_C_HEADERS_TO_CXX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_C_HEADERS_TO_CXX_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -37,7 +36,8 @@
 public:
   DeprecatedHeadersCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace modernize
diff --git a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
index c9f0649..cd09421 100644
--- a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
+++ b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DeprecatedIosBaseAliasesCheck.cpp - clang-tidy--------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h
index bbccd41..55c1d42 100644
--- a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h
+++ b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h
@@ -1,16 +1,15 @@
 //===--- DeprecatedIosBaseAliasesCheck.h - clang-tidy------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_DEPRECATEDIOSBASEALIASESCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_DEPRECATEDIOSBASEALIASESCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tidy/modernize/LoopConvertCheck.cpp
index aa11b71..f9e941c 100644
--- a/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -1,9 +1,8 @@
 //===--- LoopConvertCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/LoopConvertCheck.h b/clang-tidy/modernize/LoopConvertCheck.h
index 75ab25a..1806572 100644
--- a/clang-tidy/modernize/LoopConvertCheck.h
+++ b/clang-tidy/modernize/LoopConvertCheck.h
@@ -1,16 +1,15 @@
 //===--- LoopConvertCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_LOOP_CONVERT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "LoopConvertUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tidy/modernize/LoopConvertUtils.cpp
index f65f7a1..80d80a7 100644
--- a/clang-tidy/modernize/LoopConvertUtils.cpp
+++ b/clang-tidy/modernize/LoopConvertUtils.cpp
@@ -1,9 +1,8 @@
 //===--- LoopConvertUtils.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/LoopConvertUtils.h b/clang-tidy/modernize/LoopConvertUtils.h
index f0fa11a..3cead29 100644
--- a/clang-tidy/modernize/LoopConvertUtils.h
+++ b/clang-tidy/modernize/LoopConvertUtils.h
@@ -1,9 +1,8 @@
 //===--- LoopConvertUtils.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/MakeSharedCheck.cpp b/clang-tidy/modernize/MakeSharedCheck.cpp
index 541c2cb..11d2443 100644
--- a/clang-tidy/modernize/MakeSharedCheck.cpp
+++ b/clang-tidy/modernize/MakeSharedCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MakeSharedCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/MakeSharedCheck.h b/clang-tidy/modernize/MakeSharedCheck.h
index cf01446..95bf6b7 100644
--- a/clang-tidy/modernize/MakeSharedCheck.h
+++ b/clang-tidy/modernize/MakeSharedCheck.h
@@ -1,9 +1,8 @@
 //===--- MakeSharedCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index 15b88b8..b371345 100644
--- a/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MakeSmartPtrCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -66,11 +65,13 @@
   return LangOpts.CPlusPlus11;
 }
 
-void MakeSmartPtrCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM,
+                                            Preprocessor *PP,
+                                            Preprocessor *ModuleExpanderPP) {
   if (isLanguageVersionSupported(getLangOpts())) {
-    Inserter = llvm::make_unique<utils::IncludeInserter>(
-        Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
-    Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+    Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                         IncludeStyle);
+    PP->addPPCallbacks(Inserter->CreatePPCallbacks());
   }
 }
 
@@ -277,7 +278,7 @@
     return false;
 
   std::string ArraySizeExpr;
-  if (const auto* ArraySize = New->getArraySize()) {
+  if (const auto* ArraySize = New->getArraySize().getValueOr(nullptr)) {
     ArraySizeExpr = Lexer::getSourceText(CharSourceRange::getTokenRange(
                                              ArraySize->getSourceRange()),
                                          SM, getLangOpts())
diff --git a/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tidy/modernize/MakeSmartPtrCheck.h
index 02428d7..30fdab8 100644
--- a/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ b/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -1,16 +1,15 @@
 //===--- MakeSmartPtrCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
@@ -27,7 +26,8 @@
   MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
                     StringRef MakeSmartPtrFunctionName);
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
-  void registerPPCallbacks(clang::CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
 
diff --git a/clang-tidy/modernize/MakeUniqueCheck.cpp b/clang-tidy/modernize/MakeUniqueCheck.cpp
index 3ebbb07..1ee4fd7 100644
--- a/clang-tidy/modernize/MakeUniqueCheck.cpp
+++ b/clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MakeUniqueCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/MakeUniqueCheck.h b/clang-tidy/modernize/MakeUniqueCheck.h
index 587b41e..113c329 100644
--- a/clang-tidy/modernize/MakeUniqueCheck.h
+++ b/clang-tidy/modernize/MakeUniqueCheck.h
@@ -1,9 +1,8 @@
 //===--- MakeUniqueCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tidy/modernize/ModernizeTidyModule.cpp
index fcf535b..45ecdf9 100644
--- a/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- ModernizeTidyModule.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tidy/modernize/PassByValueCheck.cpp
index f54c575..a83e54a 100644
--- a/clang-tidy/modernize/PassByValueCheck.cpp
+++ b/clang-tidy/modernize/PassByValueCheck.cpp
@@ -1,9 +1,8 @@
 //===--- PassByValueCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -165,14 +164,16 @@
       this);
 }
 
-void PassByValueCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+void PassByValueCheck::registerPPCallbacks(const SourceManager &SM,
+                                           Preprocessor *PP,
+                                           Preprocessor *ModuleExpanderPP) {
   // Only register the preprocessor callbacks for C++; the functionality
   // currently does not provide any benefit to other languages, despite being
   // benign.
   if (getLangOpts().CPlusPlus) {
-    Inserter.reset(new utils::IncludeInserter(
-        Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
-    Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+    Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                         IncludeStyle);
+    PP->addPPCallbacks(Inserter->CreatePPCallbacks());
   }
 }
 
diff --git a/clang-tidy/modernize/PassByValueCheck.h b/clang-tidy/modernize/PassByValueCheck.h
index 37deb3f..7c74195 100644
--- a/clang-tidy/modernize/PassByValueCheck.h
+++ b/clang-tidy/modernize/PassByValueCheck.h
@@ -1,16 +1,15 @@
 //===--- PassByValueCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_PASS_BY_VALUE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_PASS_BY_VALUE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 
 #include <memory>
@@ -23,7 +22,8 @@
 public:
   PassByValueCheck(StringRef Name, ClangTidyContext *Context);
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
-  void registerPPCallbacks(clang::CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
diff --git a/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tidy/modernize/RawStringLiteralCheck.cpp
index a4aef41..415010b 100644
--- a/clang-tidy/modernize/RawStringLiteralCheck.cpp
+++ b/clang-tidy/modernize/RawStringLiteralCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RawStringLiteralCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/RawStringLiteralCheck.h b/clang-tidy/modernize/RawStringLiteralCheck.h
index f7721f6..fd38dc2 100644
--- a/clang-tidy/modernize/RawStringLiteralCheck.h
+++ b/clang-tidy/modernize/RawStringLiteralCheck.h
@@ -1,16 +1,15 @@
 //===--- RawStringLiteralCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RAW_STRING_LITERAL_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RAW_STRING_LITERAL_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include <bitset>
 
 namespace clang {
diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tidy/modernize/RedundantVoidArgCheck.cpp
index ea49ab7..46de805 100644
--- a/clang-tidy/modernize/RedundantVoidArgCheck.cpp
+++ b/clang-tidy/modernize/RedundantVoidArgCheck.cpp
@@ -1,9 +1,8 @@
 //===- RedundantVoidArgCheck.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -102,10 +101,15 @@
 void RedundantVoidArgCheck::processFunctionDecl(
     const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
   if (Function->isThisDeclarationADefinition()) {
-    const Stmt *Body = Function->getBody();
     SourceLocation Start = Function->getBeginLoc();
-    SourceLocation End =
-        Body ? Body->getBeginLoc().getLocWithOffset(-1) : Function->getEndLoc();
+    SourceLocation End = Function->getEndLoc();
+    if (const Stmt *Body = Function->getBody()) {
+      End = Body->getBeginLoc();
+      if (End.isMacroID() &&
+          Result.SourceManager->isAtStartOfImmediateMacroExpansion(End))
+        End = Result.SourceManager->getExpansionLoc(End);
+      End = End.getLocWithOffset(-1);
+    }
     removeVoidArgumentTokens(Result, SourceRange(Start, End),
                              "function definition");
   } else {
@@ -173,10 +177,8 @@
 
 void RedundantVoidArgCheck::removeVoidToken(Token VoidToken,
                                             StringRef Diagnostic) {
-  SourceLocation VoidLoc(VoidToken.getLocation());
-  auto VoidRange =
-      CharSourceRange::getTokenRange(VoidLoc, VoidLoc.getLocWithOffset(3));
-  diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidRange);
+  SourceLocation VoidLoc = VoidToken.getLocation();
+  diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidLoc);
 }
 
 void RedundantVoidArgCheck::processTypedefNameDecl(
diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.h b/clang-tidy/modernize/RedundantVoidArgCheck.h
index c990ef4..eca7085 100644
--- a/clang-tidy/modernize/RedundantVoidArgCheck.h
+++ b/clang-tidy/modernize/RedundantVoidArgCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantVoidArgCheck.h - clang-tidy --------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REDUNDANT_VOID_ARG_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REDUNDANT_VOID_ARG_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "clang/Lex/Token.h"
 
 #include <string>
diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
index 3281ef6..c1c2235 100644
--- a/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ b/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ReplaceAutoPtrCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -133,15 +132,17 @@
                      this);
 }
 
-void ReplaceAutoPtrCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM,
+                                              Preprocessor *PP,
+                                              Preprocessor *ModuleExpanderPP) {
   // Only register the preprocessor callbacks for C++; the functionality
   // currently does not provide any benefit to other languages, despite being
   // benign.
   if (!getLangOpts().CPlusPlus)
     return;
-  Inserter.reset(new utils::IncludeInserter(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
-  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+  Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                       IncludeStyle);
+  PP->addPPCallbacks(Inserter->CreatePPCallbacks());
 }
 
 void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.h b/clang-tidy/modernize/ReplaceAutoPtrCheck.h
index 5b73d51..d1c66fc 100644
--- a/clang-tidy/modernize/ReplaceAutoPtrCheck.h
+++ b/clang-tidy/modernize/ReplaceAutoPtrCheck.h
@@ -1,16 +1,15 @@
 //===--- ReplaceAutoPtrCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_AUTO_PTR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_AUTO_PTR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 
 namespace clang {
@@ -46,7 +45,8 @@
   ReplaceAutoPtrCheck(StringRef Name, ClangTidyContext *Context);
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
index 9a71569..44c108c 100644
--- a/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
+++ b/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ReplaceRandomShuffleCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -44,11 +43,10 @@
 }
 
 void ReplaceRandomShuffleCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
-  Compiler.getPreprocessor().addPPCallbacks(
-      IncludeInserter->CreatePPCallbacks());
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                              IncludeStyle);
+  PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
 }
 
 void ReplaceRandomShuffleCheck::storeOptions(
diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
index 050d740..3c5f662 100644
--- a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
+++ b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
@@ -1,16 +1,15 @@
 //===--- ReplaceRandomShuffleCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_RANDOM_SHUFFLE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REPLACE_RANDOM_SHUFFLE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 
 namespace clang {
@@ -25,7 +24,8 @@
 class ReplaceRandomShuffleCheck : public ClangTidyCheck {
 public:
   ReplaceRandomShuffleCheck(StringRef Name, ClangTidyContext *Context);
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
diff --git a/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
index e5857f7..f7e2717 100644
--- a/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
+++ b/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ReturnBracedInitListCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ReturnBracedInitListCheck.h b/clang-tidy/modernize/ReturnBracedInitListCheck.h
index eda982a..553a042 100644
--- a/clang-tidy/modernize/ReturnBracedInitListCheck.h
+++ b/clang-tidy/modernize/ReturnBracedInitListCheck.h
@@ -1,16 +1,15 @@
 //===--- ReturnBracedInitListCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/ShrinkToFitCheck.cpp b/clang-tidy/modernize/ShrinkToFitCheck.cpp
index bc0749b..607dc5f 100644
--- a/clang-tidy/modernize/ShrinkToFitCheck.cpp
+++ b/clang-tidy/modernize/ShrinkToFitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ShrinkToFitCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ShrinkToFitCheck.h b/clang-tidy/modernize/ShrinkToFitCheck.h
index 1e3745c..7d589b2 100644
--- a/clang-tidy/modernize/ShrinkToFitCheck.h
+++ b/clang-tidy/modernize/ShrinkToFitCheck.h
@@ -1,16 +1,15 @@
 //===--- ShrinkToFitCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_SHRINKTOFITCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_SHRINKTOFITCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UnaryStaticAssertCheck.cpp b/clang-tidy/modernize/UnaryStaticAssertCheck.cpp
index 5ddbb93..d93a024 100644
--- a/clang-tidy/modernize/UnaryStaticAssertCheck.cpp
+++ b/clang-tidy/modernize/UnaryStaticAssertCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnaryStaticAssertCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UnaryStaticAssertCheck.h b/clang-tidy/modernize/UnaryStaticAssertCheck.h
index b83c2c4..f43dd5a 100644
--- a/clang-tidy/modernize/UnaryStaticAssertCheck.h
+++ b/clang-tidy/modernize/UnaryStaticAssertCheck.h
@@ -1,16 +1,15 @@
 //===--- UnaryStaticAssertCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_UNARY_STATIC_ASSERT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_UNARY_STATIC_ASSERT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tidy/modernize/UseAutoCheck.cpp
index 0fecd24..e9f54f8 100644
--- a/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tidy/modernize/UseAutoCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseAutoCheck.cpp - clang-tidy-------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseAutoCheck.h b/clang-tidy/modernize/UseAutoCheck.h
index a061c5f..600de1e 100644
--- a/clang-tidy/modernize/UseAutoCheck.h
+++ b/clang-tidy/modernize/UseAutoCheck.h
@@ -1,16 +1,15 @@
 //===--- UseAutoCheck.h - clang-tidy-----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_AUTO_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_AUTO_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
index 13afbb4..011837e 100644
--- a/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
+++ b/clang-tidy/modernize/UseBoolLiteralsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseBoolLiteralsCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseBoolLiteralsCheck.h b/clang-tidy/modernize/UseBoolLiteralsCheck.h
index c9c7363..7368588 100644
--- a/clang-tidy/modernize/UseBoolLiteralsCheck.h
+++ b/clang-tidy/modernize/UseBoolLiteralsCheck.h
@@ -1,16 +1,15 @@
 //===--- UseBoolLiteralsCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_BOOL_LITERALS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_BOOL_LITERALS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp
index 23a3e1f..3c2e0e9 100644
--- a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp
+++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseDefaultMemberInitCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -256,17 +255,20 @@
   CharSourceRange InitRange =
       CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc());
 
+  bool ValueInit = isa<ImplicitValueInitExpr>(Init->getInit());
+  bool CanAssign = UseAssignment && (!ValueInit || !Init->getInit()->getType()->isEnumeralType());
+
   auto Diag =
       diag(Field->getLocation(), "use default member initializer for %0")
       << Field
-      << FixItHint::CreateInsertion(FieldEnd, UseAssignment ? " = " : "{")
+      << FixItHint::CreateInsertion(FieldEnd, CanAssign ? " = " : "{")
       << FixItHint::CreateInsertionFromRange(FieldEnd, InitRange);
 
-  if (UseAssignment && isa<ImplicitValueInitExpr>(Init->getInit()))
+  if (CanAssign && ValueInit)
     Diag << FixItHint::CreateInsertion(
         FieldEnd, getValueOfValueInit(Init->getInit()->getType()));
 
-  if (!UseAssignment)
+  if (!CanAssign)
     Diag << FixItHint::CreateInsertion(FieldEnd, "}");
 
   Diag << FixItHint::CreateRemoval(Init->getSourceRange());
@@ -274,7 +276,7 @@
 
 void UseDefaultMemberInitCheck::checkExistingInit(
     const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
-  const FieldDecl *Field = Init->getMember();
+  const FieldDecl *Field = Init->getAnyMember();
 
   if (!sameValue(Field->getInClassInitializer(), Init->getInit()))
     return;
diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.h b/clang-tidy/modernize/UseDefaultMemberInitCheck.h
index d8887a0..f1e6222 100644
--- a/clang-tidy/modernize/UseDefaultMemberInitCheck.h
+++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.h
@@ -1,16 +1,15 @@
 //===--- UseDefaultMemberInitCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_MEMBER_INIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_DEFAULT_MEMBER_INIT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tidy/modernize/UseEmplaceCheck.cpp
index b6c142d..786bb5a 100644
--- a/clang-tidy/modernize/UseEmplaceCheck.cpp
+++ b/clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseEmplaceCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseEmplaceCheck.h b/clang-tidy/modernize/UseEmplaceCheck.h
index 2efb212..5382eb6 100644
--- a/clang-tidy/modernize/UseEmplaceCheck.h
+++ b/clang-tidy/modernize/UseEmplaceCheck.h
@@ -1,16 +1,15 @@
 //===--- UseEmplaceCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EMPLACE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EMPLACE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include <string>
 #include <vector>
 
diff --git a/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
index 4245bfe..ae6f91c 100644
--- a/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ b/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseEqualsDefaultCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseEqualsDefaultCheck.h b/clang-tidy/modernize/UseEqualsDefaultCheck.h
index a55c222..014b90c 100644
--- a/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ b/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -1,16 +1,15 @@
 //===--- UseEqualsDefaultCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DEFAULT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DEFAULT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tidy/modernize/UseEqualsDeleteCheck.cpp
index fc8425d..4c366b4 100644
--- a/clang-tidy/modernize/UseEqualsDeleteCheck.cpp
+++ b/clang-tidy/modernize/UseEqualsDeleteCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseEqualsDeleteCheck.cpp - clang-tidy-----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseEqualsDeleteCheck.h b/clang-tidy/modernize/UseEqualsDeleteCheck.h
index 716f045..b6cd010 100644
--- a/clang-tidy/modernize/UseEqualsDeleteCheck.h
+++ b/clang-tidy/modernize/UseEqualsDeleteCheck.h
@@ -1,16 +1,15 @@
 //===--- UseEqualsDeleteCheck.h - clang-tidy---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DELETE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_EQUALS_DELETE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tidy/modernize/UseNodiscardCheck.cpp
index f655515..d2ac7d5 100644
--- a/clang-tidy/modernize/UseNodiscardCheck.cpp
+++ b/clang-tidy/modernize/UseNodiscardCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseNodiscardCheck.cpp - clang-tidy -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseNodiscardCheck.h b/clang-tidy/modernize/UseNodiscardCheck.h
index 00563e7..325e5f8 100644
--- a/clang-tidy/modernize/UseNodiscardCheck.h
+++ b/clang-tidy/modernize/UseNodiscardCheck.h
@@ -1,16 +1,15 @@
 //===--- UseNodiscardCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USENODISCARDCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USENODISCARDCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tidy/modernize/UseNoexceptCheck.cpp
index 869381a..4b9c498 100644
--- a/clang-tidy/modernize/UseNoexceptCheck.cpp
+++ b/clang-tidy/modernize/UseNoexceptCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseNoexceptCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseNoexceptCheck.h b/clang-tidy/modernize/UseNoexceptCheck.h
index a15867b..828eb57 100644
--- a/clang-tidy/modernize/UseNoexceptCheck.h
+++ b/clang-tidy/modernize/UseNoexceptCheck.h
@@ -1,16 +1,15 @@
 //===--- UseNoexceptCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tidy/modernize/UseNullptrCheck.cpp
index 3bf09c1..45e59c3 100644
--- a/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseNullptrCheck.cpp - clang-tidy----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseNullptrCheck.h b/clang-tidy/modernize/UseNullptrCheck.h
index 4b33f1e..dab6ca9 100644
--- a/clang-tidy/modernize/UseNullptrCheck.h
+++ b/clang-tidy/modernize/UseNullptrCheck.h
@@ -1,16 +1,15 @@
 //===--- UseNullptrCheck.h - clang-tidy--------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NULLPTR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NULLPTR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tidy/modernize/UseOverrideCheck.cpp
index 9429eb2..2f15213 100644
--- a/clang-tidy/modernize/UseOverrideCheck.cpp
+++ b/clang-tidy/modernize/UseOverrideCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseOverrideCheck.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -18,9 +17,28 @@
 namespace tidy {
 namespace modernize {
 
+UseOverrideCheck::UseOverrideCheck(StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      IgnoreDestructors(Options.get("IgnoreDestructors", false)),
+      OverrideSpelling(Options.get("OverrideSpelling", "override")),
+      FinalSpelling(Options.get("FinalSpelling", "final")) {}
+
+void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IgnoreDestructors", IgnoreDestructors);
+  Options.store(Opts, "OverrideSpelling", OverrideSpelling);
+  Options.store(Opts, "FinalSpelling", FinalSpelling);
+}
+
 void UseOverrideCheck::registerMatchers(MatchFinder *Finder) {
   // Only register the matcher for C++11.
-  if (getLangOpts().CPlusPlus11)
+  if (!getLangOpts().CPlusPlus11)
+    return;
+
+  if (IgnoreDestructors)
+    Finder->addMatcher(
+        cxxMethodDecl(isOverride(), unless(cxxDestructorDecl())).bind("method"),
+        this);
+  else
     Finder->addMatcher(cxxMethodDecl(isOverride()).bind("method"), this);
 }
 
@@ -68,6 +86,8 @@
   const auto *Method = Result.Nodes.getNodeAs<FunctionDecl>("method");
   const SourceManager &Sources = *Result.SourceManager;
 
+  ASTContext &Context = *Result.Context;
+
   assert(Method != nullptr);
   if (Method->getInstantiatedFromMemberFunction() != nullptr)
     Method = Method->getInstantiatedFromMemberFunction();
@@ -87,25 +107,24 @@
     return; // Nothing to do.
 
   std::string Message;
-
   if (OnlyVirtualSpecified) {
-    Message =
-        "prefer using 'override' or (rarely) 'final' instead of 'virtual'";
+    Message = "prefer using '%0' or (rarely) '%1' instead of 'virtual'";
   } else if (KeywordCount == 0) {
-    Message = "annotate this function with 'override' or (rarely) 'final'";
+    Message = "annotate this function with '%0' or (rarely) '%1'";
   } else {
     StringRef Redundant =
-        HasVirtual ? (HasOverride && HasFinal ? "'virtual' and 'override' are"
+        HasVirtual ? (HasOverride && HasFinal ? "'virtual' and '%0' are"
                                               : "'virtual' is")
-                   : "'override' is";
-    StringRef Correct = HasFinal ? "'final'" : "'override'";
+                   : "'%0' is";
+    StringRef Correct = HasFinal ? "'%1'" : "'%0'";
 
     Message = (llvm::Twine(Redundant) +
                " redundant since the function is already declared " + Correct)
                   .str();
   }
 
-  DiagnosticBuilder Diag = diag(Method->getLocation(), Message);
+  auto Diag = diag(Method->getLocation(), Message)
+              << OverrideSpelling << FinalSpelling;
 
   CharSourceRange FileRange = Lexer::makeFileCharRange(
       CharSourceRange::getTokenRange(Method->getSourceRange()), Sources,
@@ -122,7 +141,7 @@
   // Add 'override' on inline declarations that don't already have it.
   if (!HasFinal && !HasOverride) {
     SourceLocation InsertLoc;
-    StringRef ReplacementText = "override ";
+    std::string ReplacementText = OverrideSpelling + " ";
     SourceLocation MethodLoc = Method->getLocation();
 
     for (Token T : Tokens) {
@@ -152,7 +171,7 @@
       // end of the declaration of the function, but prefer to put it on the
       // same line as the declaration if the beginning brace for the start of
       // the body falls on the next line.
-      ReplacementText = " override";
+      ReplacementText = " " + OverrideSpelling;
       auto LastTokenIter = std::prev(Tokens.end());
       // When try statement is used instead of compound statement as
       // method body - insert override keyword before it.
@@ -165,23 +184,30 @@
       // For declarations marked with "= 0" or "= [default|delete]", the end
       // location will point until after those markings. Therefore, the override
       // keyword shouldn't be inserted at the end, but before the '='.
-      if (Tokens.size() > 2 && (GetText(Tokens.back(), Sources) == "0" ||
-                                Tokens.back().is(tok::kw_default) ||
-                                Tokens.back().is(tok::kw_delete)) &&
+      if (Tokens.size() > 2 &&
+          (GetText(Tokens.back(), Sources) == "0" ||
+           Tokens.back().is(tok::kw_default) ||
+           Tokens.back().is(tok::kw_delete)) &&
           GetText(Tokens[Tokens.size() - 2], Sources) == "=") {
         InsertLoc = Tokens[Tokens.size() - 2].getLocation();
         // Check if we need to insert a space.
         if ((Tokens[Tokens.size() - 2].getFlags() & Token::LeadingSpace) == 0)
-          ReplacementText = " override ";
-      } else if (GetText(Tokens.back(), Sources) == "ABSTRACT") {
+          ReplacementText = " " + OverrideSpelling + " ";
+      } else if (GetText(Tokens.back(), Sources) == "ABSTRACT")
         InsertLoc = Tokens.back().getLocation();
-      }
     }
 
     if (!InsertLoc.isValid()) {
       InsertLoc = FileRange.getEnd();
-      ReplacementText = " override";
+      ReplacementText = " " + OverrideSpelling;
     }
+
+    // If the override macro has been specified just ensure it exists,
+    // if not don't apply a fixit but keep the warning.
+    if (OverrideSpelling != "override" &&
+        !Context.Idents.get(OverrideSpelling).hasMacroDefinition())
+      return;
+
     Diag << FixItHint::CreateInsertion(InsertLoc, ReplacementText);
   }
 
diff --git a/clang-tidy/modernize/UseOverrideCheck.h b/clang-tidy/modernize/UseOverrideCheck.h
index 83ce7da..ed16395 100644
--- a/clang-tidy/modernize/UseOverrideCheck.h
+++ b/clang-tidy/modernize/UseOverrideCheck.h
@@ -1,16 +1,15 @@
 //===--- UseOverrideCheck.h - clang-tidy ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEOVERRIDECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEOVERRIDECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -19,10 +18,16 @@
 /// Use C++11's `override` and remove `virtual` where applicable.
 class UseOverrideCheck : public ClangTidyCheck {
 public:
-  UseOverrideCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  UseOverrideCheck(StringRef Name, ClangTidyContext *Context);
+
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+private:
+  const bool IgnoreDestructors;
+  const std::string OverrideSpelling;
+  const std::string FinalSpelling;
 };
 
 } // namespace modernize
diff --git a/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
index 74f050b..6490f02 100644
--- a/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
+++ b/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseTransparentFunctorsCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseTransparentFunctorsCheck.h b/clang-tidy/modernize/UseTransparentFunctorsCheck.h
index 4bdce76..dce4e99 100644
--- a/clang-tidy/modernize/UseTransparentFunctorsCheck.h
+++ b/clang-tidy/modernize/UseTransparentFunctorsCheck.h
@@ -1,16 +1,15 @@
 //===--- UseTransparentFunctorsCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_TRANSPARENT_FUNCTORS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_TRANSPARENT_FUNCTORS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp b/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp
index 05b2dd8..cb3f551 100644
--- a/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp
+++ b/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseUncaughtExceptionsCheck.cpp - clang-tidy--------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseUncaughtExceptionsCheck.h b/clang-tidy/modernize/UseUncaughtExceptionsCheck.h
index 2b9660c..2c4386e 100644
--- a/clang-tidy/modernize/UseUncaughtExceptionsCheck.h
+++ b/clang-tidy/modernize/UseUncaughtExceptionsCheck.h
@@ -1,16 +1,15 @@
 //===--- UseUncaughtExceptionsCheck.h - clang-tidy------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_UNCAUGHT_EXCEPTIONS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_UNCAUGHT_EXCEPTIONS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tidy/modernize/UseUsingCheck.cpp
index a690e44..bd23462 100644
--- a/clang-tidy/modernize/UseUsingCheck.cpp
+++ b/clang-tidy/modernize/UseUsingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UseUsingCheck.cpp - clang-tidy------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseUsingCheck.h b/clang-tidy/modernize/UseUsingCheck.h
index 022eef0..ea11609 100644
--- a/clang-tidy/modernize/UseUsingCheck.h
+++ b/clang-tidy/modernize/UseUsingCheck.h
@@ -1,16 +1,15 @@
 //===--- UseUsingCheck.h - clang-tidy----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_USING_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_USING_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/mpi/BufferDerefCheck.cpp b/clang-tidy/mpi/BufferDerefCheck.cpp
index 8e2c0e3..8ababfe 100644
--- a/clang-tidy/mpi/BufferDerefCheck.cpp
+++ b/clang-tidy/mpi/BufferDerefCheck.cpp
@@ -1,9 +1,8 @@
 //===--- BufferDerefCheck.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/mpi/BufferDerefCheck.h b/clang-tidy/mpi/BufferDerefCheck.h
index 8490fa1..040e3f7 100644
--- a/clang-tidy/mpi/BufferDerefCheck.h
+++ b/clang-tidy/mpi/BufferDerefCheck.h
@@ -1,16 +1,15 @@
 //===--- BufferDerefCheck.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MPI_BUFFER_DEREF_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MPI_BUFFER_DEREF_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/mpi/MPITidyModule.cpp b/clang-tidy/mpi/MPITidyModule.cpp
index 55e187d..b295d5f 100644
--- a/clang-tidy/mpi/MPITidyModule.cpp
+++ b/clang-tidy/mpi/MPITidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- MPITidyModule.cpp - clang-tidy -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/mpi/TypeMismatchCheck.cpp b/clang-tidy/mpi/TypeMismatchCheck.cpp
index a1f92b8..a9661e0 100644
--- a/clang-tidy/mpi/TypeMismatchCheck.cpp
+++ b/clang-tidy/mpi/TypeMismatchCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TypeMismatchCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/mpi/TypeMismatchCheck.h b/clang-tidy/mpi/TypeMismatchCheck.h
index dd56c46..a563e29 100644
--- a/clang-tidy/mpi/TypeMismatchCheck.h
+++ b/clang-tidy/mpi/TypeMismatchCheck.h
@@ -1,16 +1,15 @@
 //===--- TypeMismatchCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MPI_TYPE_MISMATCH_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MPI_TYPE_MISMATCH_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 
 namespace clang {
diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
index d5e2027..eb18dcd 100644
--- a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
+++ b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidNSErrorInitCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.h b/clang-tidy/objc/AvoidNSErrorInitCheck.h
index 379b8a2..030a532 100644
--- a/clang-tidy/objc/AvoidNSErrorInitCheck.h
+++ b/clang-tidy/objc/AvoidNSErrorInitCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidNSErrorInitCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/objc/AvoidSpinlockCheck.cpp b/clang-tidy/objc/AvoidSpinlockCheck.cpp
index 319d945..ac3d2b2 100644
--- a/clang-tidy/objc/AvoidSpinlockCheck.cpp
+++ b/clang-tidy/objc/AvoidSpinlockCheck.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidSpinlockCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/AvoidSpinlockCheck.h b/clang-tidy/objc/AvoidSpinlockCheck.h
index d9dbf8c..dd40962 100644
--- a/clang-tidy/objc/AvoidSpinlockCheck.h
+++ b/clang-tidy/objc/AvoidSpinlockCheck.h
@@ -1,16 +1,15 @@
 //===--- AvoidSpinlockCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/objc/CMakeLists.txt b/clang-tidy/objc/CMakeLists.txt
index 4063bba..4eeb148 100644
--- a/clang-tidy/objc/CMakeLists.txt
+++ b/clang-tidy/objc/CMakeLists.txt
@@ -6,6 +6,7 @@
   ForbiddenSubclassingCheck.cpp
   ObjCTidyModule.cpp
   PropertyDeclarationCheck.cpp
+  SuperSelfCheck.cpp
 
   LINK_LIBS
   clangAST
diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
index 0599b21..6b8e795 100644
--- a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
+++ b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ForbiddenSubclassingCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.h b/clang-tidy/objc/ForbiddenSubclassingCheck.h
index 6c7e08b..c05ba08 100644
--- a/clang-tidy/objc/ForbiddenSubclassingCheck.h
+++ b/clang-tidy/objc/ForbiddenSubclassingCheck.h
@@ -1,16 +1,15 @@
 //===--- ForbiddenSubclassingCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/ADT/StringRef.h"
 #include <string>
 #include <vector>
diff --git a/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tidy/objc/ObjCTidyModule.cpp
index 19152c2..636e2c0 100644
--- a/clang-tidy/objc/ObjCTidyModule.cpp
+++ b/clang-tidy/objc/ObjCTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- ObjCTidyModule.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,6 +13,7 @@
 #include "AvoidSpinlockCheck.h"
 #include "ForbiddenSubclassingCheck.h"
 #include "PropertyDeclarationCheck.h"
+#include "SuperSelfCheck.h"
 
 using namespace clang::ast_matchers;
 
@@ -32,6 +32,8 @@
         "objc-forbidden-subclassing");
     CheckFactories.registerCheck<PropertyDeclarationCheck>(
         "objc-property-declaration");
+    CheckFactories.registerCheck<SuperSelfCheck>(
+        "objc-super-self");
   }
 };
 
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp
index 94b82f0..094c193 100644
--- a/clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- PropertyDeclarationCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -81,7 +80,8 @@
 }
 
 bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) {
-  auto RegexExp = llvm::Regex("^[a-zA-Z]+_[a-zA-Z0-9][a-zA-Z0-9_]+$");
+  auto RegexExp =
+      llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$");
   return RegexExp.match(PropertyName);
 }
 
@@ -92,31 +92,21 @@
   if (Prefix.lower() != Prefix) {
     return false;
   }
-  auto RegexExp =
-      llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
+  auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
   return RegexExp.match(PropertyName.substr(Start + 1));
 }
 }  // namespace
 
-PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name,
-                                                   ClangTidyContext *Context)
-    : ClangTidyCheck(Name, Context),
-      SpecialAcronyms(
-          utils::options::parseStringList(Options.get("Acronyms", ""))),
-      IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)),
-      EscapedAcronyms() {}
-
 void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
   // this check should only be applied to ObjC sources.
   if (!getLangOpts().ObjC) return;
 
-  Finder->addMatcher(
-      objcPropertyDecl(
-          // the property name should be in Lower Camel Case like
-          // 'lowerCamelCase'
-          unless(matchesName(validPropertyNameRegex(true))))
-          .bind("property"),
-      this);
+  Finder->addMatcher(objcPropertyDecl(
+                         // the property name should be in Lower Camel Case like
+                         // 'lowerCamelCase'
+                         unless(matchesName(validPropertyNameRegex(true))))
+                         .bind("property"),
+                     this);
 }
 
 void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
@@ -146,12 +136,6 @@
       << generateFixItHint(MatchedDecl, StandardProperty);
 }
 
-void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
-  Options.store(Opts, "Acronyms",
-                utils::options::serializeStringList(SpecialAcronyms));
-  Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms);
-}
-
 }  // namespace objc
 }  // namespace tidy
 }  // namespace clang
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h
index b2683ba..769f0c4 100644
--- a/clang-tidy/objc/PropertyDeclarationCheck.h
+++ b/clang-tidy/objc/PropertyDeclarationCheck.h
@@ -1,18 +1,15 @@
 //===--- PropertyDeclarationCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H
 
-#include "../ClangTidy.h"
-#include <string>
-#include <vector>
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -28,15 +25,10 @@
 /// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html
 class PropertyDeclarationCheck : public ClangTidyCheck {
 public:
-  PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context);
+  PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  void storeOptions(ClangTidyOptions::OptionMap &Options) override;
-
-private:
-  const std::vector<std::string> SpecialAcronyms;
-  const bool IncludeDefaultAcronyms;
-  std::vector<std::string> EscapedAcronyms;
 };
 
 } // namespace objc
diff --git a/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tidy/objc/SuperSelfCheck.cpp
new file mode 100644
index 0000000..7aafd66
--- /dev/null
+++ b/clang-tidy/objc/SuperSelfCheck.cpp
@@ -0,0 +1,127 @@
+//===--- SuperSelfCheck.cpp - clang-tidy ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SuperSelfCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+namespace {
+
+/// \brief Matches Objective-C methods in the initializer family.
+///
+/// Example matches -init and -initWithInt:.
+///   (matcher = objcMethodDecl(isInitializer()))
+/// \code
+///   @interface Foo
+///   - (instancetype)init;
+///   - (instancetype)initWithInt:(int)i;
+///   + (instancetype)init;
+///   - (void)bar;
+///   @end
+/// \endcode
+AST_MATCHER(ObjCMethodDecl, isInitializer) {
+  return Node.getMethodFamily() == OMF_init;
+}
+
+/// \brief Matches Objective-C implementations of classes that directly or
+/// indirectly have a superclass matching \c InterfaceDecl.
+///
+/// Note that a class is not considered to be a subclass of itself.
+///
+/// Example matches implementation declarations for Y and Z.
+///   (matcher = objcInterfaceDecl(isSubclassOf(hasName("X"))))
+/// \code
+///   @interface X
+///   @end
+///   @interface Y : X
+///   @end
+///   @implementation Y  // directly derived
+///   @end
+///   @interface Z : Y
+///   @end
+///   @implementation Z  // indirectly derived
+///   @end
+/// \endcode
+AST_MATCHER_P(ObjCImplementationDecl, isSubclassOf,
+              ast_matchers::internal::Matcher<ObjCInterfaceDecl>,
+              InterfaceDecl) {
+  // Check if any of the superclasses of the class match.
+  for (const ObjCInterfaceDecl *SuperClass =
+           Node.getClassInterface()->getSuperClass();
+       SuperClass != nullptr; SuperClass = SuperClass->getSuperClass()) {
+    if (InterfaceDecl.matches(*SuperClass, Finder, Builder))
+      return true;
+  }
+
+  // No matches found.
+  return false;
+}
+
+/// \brief Matches Objective-C message expressions where the receiver is the
+/// super instance.
+///
+/// Example matches the invocations of -banana and -orange.
+///   (matcher = objcMessageExpr(isMessagingSuperInstance()))
+/// \code
+///   - (void)banana {
+///     [self apple]
+///     [super banana];
+///     [super orange];
+///   }
+/// \endcode
+AST_MATCHER(ObjCMessageExpr, isMessagingSuperInstance) {
+  return Node.getReceiverKind() == ObjCMessageExpr::SuperInstance;
+}
+
+} // namespace
+
+void SuperSelfCheck::registerMatchers(MatchFinder *Finder) {
+  // This check should only be applied to Objective-C sources.
+  if (!getLangOpts().ObjC)
+    return;
+
+  Finder->addMatcher(
+      objcMessageExpr(
+          hasSelector("self"), isMessagingSuperInstance(),
+          hasAncestor(objcMethodDecl(isInitializer(),
+                                     hasDeclContext(objcImplementationDecl(
+                                         isSubclassOf(hasName("NSObject")))))))
+          .bind("message"),
+      this);
+}
+
+void SuperSelfCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Message = Result.Nodes.getNodeAs<ObjCMessageExpr>("message");
+
+  auto Diag = diag(Message->getExprLoc(), "suspicious invocation of %0 in "
+                                          "initializer; did you mean to "
+                                          "invoke a superclass initializer?")
+              << Message->getMethodDecl();
+
+  SourceLocation ReceiverLoc = Message->getReceiverRange().getBegin();
+  if (ReceiverLoc.isMacroID() || ReceiverLoc.isInvalid())
+    return;
+
+  SourceLocation SelectorLoc = Message->getSelectorStartLoc();
+  if (SelectorLoc.isMacroID() || SelectorLoc.isInvalid())
+    return;
+
+  Diag << FixItHint::CreateReplacement(Message->getSourceRange(),
+                                       StringRef("[super init]"));
+}
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/objc/SuperSelfCheck.h b/clang-tidy/objc/SuperSelfCheck.h
new file mode 100644
index 0000000..ed5d1cd
--- /dev/null
+++ b/clang-tidy/objc/SuperSelfCheck.h
@@ -0,0 +1,36 @@
+//===--- SuperSelfCheck.h - clang-tidy --------------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+/// Finds invocations of -self on super instances in initializers of subclasses
+/// of NSObject and recommends calling a superclass initializer instead.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/objc-super-self.html
+class SuperSelfCheck : public ClangTidyCheck {
+public:
+  SuperSelfCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H
diff --git a/clang-tidy/openmp/CMakeLists.txt b/clang-tidy/openmp/CMakeLists.txt
new file mode 100644
index 0000000..bbd65f2
--- /dev/null
+++ b/clang-tidy/openmp/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyOpenMPModule
+  ExceptionEscapeCheck.cpp
+  OpenMPTidyModule.cpp
+  UseDefaultNoneCheck.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangTidy
+  clangTidyUtils
+  )
diff --git a/clang-tidy/openmp/ExceptionEscapeCheck.cpp b/clang-tidy/openmp/ExceptionEscapeCheck.cpp
new file mode 100644
index 0000000..c3894a6
--- /dev/null
+++ b/clang-tidy/openmp/ExceptionEscapeCheck.cpp
@@ -0,0 +1,84 @@
+//===--- ExceptionEscapeCheck.cpp - clang-tidy ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExceptionEscapeCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace openmp {
+
+ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name,
+                                           ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      RawIgnoredExceptions(Options.get("IgnoredExceptions", "")) {
+  llvm::SmallVector<StringRef, 8> FunctionsThatShouldNotThrowVec,
+      IgnoredExceptionsVec;
+
+  llvm::StringSet<> IgnoredExceptions;
+  StringRef(RawIgnoredExceptions).split(IgnoredExceptionsVec, ",", -1, false);
+  llvm::transform(IgnoredExceptionsVec, IgnoredExceptionsVec.begin(),
+                  [](StringRef S) { return S.trim(); });
+  IgnoredExceptions.insert(IgnoredExceptionsVec.begin(),
+                           IgnoredExceptionsVec.end());
+  Tracer.ignoreExceptions(std::move(IgnoredExceptions));
+  Tracer.ignoreBadAlloc(true);
+}
+
+void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IgnoredExceptions", RawIgnoredExceptions);
+}
+
+void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) {
+  // Don't register the check if OpenMP is not enabled; the OpenMP pragmas are
+  // completely ignored then, so no OpenMP entires will be present in the AST.
+  if (!getLangOpts().OpenMP)
+    return;
+  // Similarly, if C++ Exceptions are not enabled, nothing to do.
+  if (!getLangOpts().CPlusPlus || !getLangOpts().CXXExceptions)
+    return;
+
+  Finder->addMatcher(ompExecutableDirective(
+                         unless(isStandaloneDirective()),
+                         hasStructuredBlock(stmt().bind("structured-block")))
+                         .bind("directive"),
+                     this);
+}
+
+void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Directive =
+      Result.Nodes.getNodeAs<OMPExecutableDirective>("directive");
+  assert(Directive && "Expected to match some OpenMP Executable directive.");
+  const auto *StructuredBlock =
+      Result.Nodes.getNodeAs<Stmt>("structured-block");
+  assert(StructuredBlock && "Expected to get some OpenMP Structured Block.");
+
+  if (Tracer.analyze(StructuredBlock).getBehaviour() !=
+      utils::ExceptionAnalyzer::State::Throwing)
+    return; // No exceptions have been proven to escape out of the struc. block.
+
+  // FIXME: We should provide more information about the exact location where
+  // the exception is thrown, maybe the full path the exception escapes.
+
+  diag(StructuredBlock->getBeginLoc(),
+       "an exception thrown inside of the OpenMP '%0' region is not caught in "
+       "that same region")
+      << getOpenMPDirectiveName(Directive->getDirectiveKind());
+}
+
+} // namespace openmp
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/openmp/ExceptionEscapeCheck.h b/clang-tidy/openmp/ExceptionEscapeCheck.h
new file mode 100644
index 0000000..bcbeccd
--- /dev/null
+++ b/clang-tidy/openmp/ExceptionEscapeCheck.h
@@ -0,0 +1,41 @@
+//===--- ExceptionEscapeCheck.h - clang-tidy --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_EXCEPTIONESCAPECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_EXCEPTIONESCAPECHECK_H
+
+#include "../ClangTidy.h"
+#include "../utils/ExceptionAnalyzer.h"
+
+namespace clang {
+namespace tidy {
+namespace openmp {
+
+/// Analyzes OpenMP Structured Blocks and checks that no exception escapes
+/// out of the Structured Block it was thrown in.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/openmp-exception-escape.html
+class ExceptionEscapeCheck : public ClangTidyCheck {
+public:
+  ExceptionEscapeCheck(StringRef Name, ClangTidyContext *Context);
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::string RawIgnoredExceptions;
+
+  utils::ExceptionAnalyzer Tracer;
+};
+
+} // namespace openmp
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_EXCEPTIONESCAPECHECK_H
diff --git a/clang-tidy/openmp/OpenMPTidyModule.cpp b/clang-tidy/openmp/OpenMPTidyModule.cpp
new file mode 100644
index 0000000..cb0e247
--- /dev/null
+++ b/clang-tidy/openmp/OpenMPTidyModule.cpp
@@ -0,0 +1,41 @@
+//===--- OpenMPTidyModule.cpp - clang-tidy--------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+#include "ExceptionEscapeCheck.h"
+#include "UseDefaultNoneCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace openmp {
+
+/// This module is for OpenMP-specific checks.
+class OpenMPModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<ExceptionEscapeCheck>(
+        "openmp-exception-escape");
+    CheckFactories.registerCheck<UseDefaultNoneCheck>(
+        "openmp-use-default-none");
+  }
+};
+
+// Register the OpenMPTidyModule using this statically initialized variable.
+static ClangTidyModuleRegistry::Add<OpenMPModule>
+    X("openmp-module", "Adds OpenMP-specific checks.");
+
+} // namespace openmp
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the OpenMPModule.
+volatile int OpenMPModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/openmp/UseDefaultNoneCheck.cpp b/clang-tidy/openmp/UseDefaultNoneCheck.cpp
new file mode 100644
index 0000000..d25498d
--- /dev/null
+++ b/clang-tidy/openmp/UseDefaultNoneCheck.cpp
@@ -0,0 +1,65 @@
+//===--- UseDefaultNoneCheck.cpp - clang-tidy -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseDefaultNoneCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace openmp {
+
+void UseDefaultNoneCheck::registerMatchers(MatchFinder *Finder) {
+  // Don't register the check if OpenMP is not enabled; the OpenMP pragmas are
+  // completely ignored then, so no OpenMP entires will be present in the AST.
+  if (!getLangOpts().OpenMP)
+    return;
+
+  Finder->addMatcher(
+      ompExecutableDirective(
+          allOf(isAllowedToContainClauseKind(OMPC_default),
+                anyOf(unless(hasAnyClause(ompDefaultClause())),
+                      hasAnyClause(ompDefaultClause(unless(isNoneKind()))
+                                       .bind("clause")))))
+          .bind("directive"),
+      this);
+}
+
+void UseDefaultNoneCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Directive =
+      Result.Nodes.getNodeAs<OMPExecutableDirective>("directive");
+  assert(Directive != nullptr && "Expected to match some directive.");
+
+  if (const auto *Clause = Result.Nodes.getNodeAs<OMPDefaultClause>("clause")) {
+    diag(Directive->getBeginLoc(),
+         "OpenMP directive '%0' specifies 'default(%1)' clause, consider using "
+         "'default(none)' clause instead")
+        << getOpenMPDirectiveName(Directive->getDirectiveKind())
+        << getOpenMPSimpleClauseTypeName(Clause->getClauseKind(),
+                                         Clause->getDefaultKind());
+    diag(Clause->getBeginLoc(), "existing 'default' clause specified here",
+         DiagnosticIDs::Note);
+    return;
+  }
+
+  diag(Directive->getBeginLoc(),
+       "OpenMP directive '%0' does not specify 'default' clause, consider "
+       "specifying 'default(none)' clause")
+      << getOpenMPDirectiveName(Directive->getDirectiveKind());
+}
+
+} // namespace openmp
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/openmp/UseDefaultNoneCheck.h b/clang-tidy/openmp/UseDefaultNoneCheck.h
new file mode 100644
index 0000000..c5ff882
--- /dev/null
+++ b/clang-tidy/openmp/UseDefaultNoneCheck.h
@@ -0,0 +1,36 @@
+//===--- UseDefaultNoneCheck.h - clang-tidy ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_USEDEFAULTNONECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_USEDEFAULTNONECHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace openmp {
+
+/// Finds OpenMP directives that are allowed to contain a ``default`` clause,
+/// but either don't specify it or the clause is specified but with the kind
+/// other than ``none``, and suggests to use the ``default(none)`` clause.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/openmp-use-default-none.html
+class UseDefaultNoneCheck : public ClangTidyCheck {
+public:
+  UseDefaultNoneCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace openmp
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_USEDEFAULTNONECHECK_H
diff --git a/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tidy/performance/FasterStringFindCheck.cpp
index 0c3d249..bb0a02f 100644
--- a/clang-tidy/performance/FasterStringFindCheck.cpp
+++ b/clang-tidy/performance/FasterStringFindCheck.cpp
@@ -1,9 +1,8 @@
 //===--- FasterStringFindCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/FasterStringFindCheck.h b/clang-tidy/performance/FasterStringFindCheck.h
index ff666f2..7d46d06 100644
--- a/clang-tidy/performance/FasterStringFindCheck.h
+++ b/clang-tidy/performance/FasterStringFindCheck.h
@@ -1,16 +1,15 @@
 //===--- FasterStringFindCheck.h - clang-tidy--------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_FASTER_STRING_FIND_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_FASTER_STRING_FIND_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 #include <string>
 #include <vector>
diff --git a/clang-tidy/performance/ForRangeCopyCheck.cpp b/clang-tidy/performance/ForRangeCopyCheck.cpp
index 4b90df4..e004009 100644
--- a/clang-tidy/performance/ForRangeCopyCheck.cpp
+++ b/clang-tidy/performance/ForRangeCopyCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ForRangeCopyCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/ForRangeCopyCheck.h b/clang-tidy/performance/ForRangeCopyCheck.h
index de8b2c9..3745c7b 100644
--- a/clang-tidy/performance/ForRangeCopyCheck.h
+++ b/clang-tidy/performance/ForRangeCopyCheck.h
@@ -1,16 +1,15 @@
 //===--- ForRangeCopyCheck.h - clang-tidy------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_FORRANGECOPYCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_FORRANGECOPYCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp b/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
index 6e73119..e3b90d3 100644
--- a/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
+++ b/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ImplicitConversionInLoopCheck.cpp - clang-tidy--------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/ImplicitConversionInLoopCheck.h b/clang-tidy/performance/ImplicitConversionInLoopCheck.h
index 55cb84c..b372003 100644
--- a/clang-tidy/performance/ImplicitConversionInLoopCheck.h
+++ b/clang-tidy/performance/ImplicitConversionInLoopCheck.h
@@ -1,16 +1,15 @@
 //===--- ImplicitConversionInLoopCheck.h - clang-tidy------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CONVERSION_IN_LOOP_CHECK_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_IMPLICIT_CONVERSION_IN_LOOP_CHECK_H_
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tidy/performance/InefficientAlgorithmCheck.cpp
index 8cee281..5ce5ffa 100644
--- a/clang-tidy/performance/InefficientAlgorithmCheck.cpp
+++ b/clang-tidy/performance/InefficientAlgorithmCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InefficientAlgorithmCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/InefficientAlgorithmCheck.h b/clang-tidy/performance/InefficientAlgorithmCheck.h
index 72506cf..b8a6d49 100644
--- a/clang-tidy/performance/InefficientAlgorithmCheck.h
+++ b/clang-tidy/performance/InefficientAlgorithmCheck.h
@@ -1,16 +1,15 @@
 //===--- InefficientAlgorithmCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENTALGORITHMCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENTALGORITHMCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/InefficientStringConcatenationCheck.cpp b/clang-tidy/performance/InefficientStringConcatenationCheck.cpp
index a17916d..fe4b5a9 100644
--- a/clang-tidy/performance/InefficientStringConcatenationCheck.cpp
+++ b/clang-tidy/performance/InefficientStringConcatenationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InefficientStringConcatenationCheck.cpp - clang-tidy--------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/InefficientStringConcatenationCheck.h b/clang-tidy/performance/InefficientStringConcatenationCheck.h
index 12a154c..83f27bb 100644
--- a/clang-tidy/performance/InefficientStringConcatenationCheck.h
+++ b/clang-tidy/performance/InefficientStringConcatenationCheck.h
@@ -1,17 +1,16 @@
 //===--- InefficientStringConcatenationCheck.h - clang-tidy-----------*- C++
 //-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENTSTRINGCONCATENATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENTSTRINGCONCATENATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tidy/performance/InefficientVectorOperationCheck.cpp
index 5b08376..622649a 100644
--- a/clang-tidy/performance/InefficientVectorOperationCheck.cpp
+++ b/clang-tidy/performance/InefficientVectorOperationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InefficientVectorOperationCheck.cpp - clang-tidy------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/InefficientVectorOperationCheck.h b/clang-tidy/performance/InefficientVectorOperationCheck.h
index 1427ff1..bfd84d1 100644
--- a/clang-tidy/performance/InefficientVectorOperationCheck.h
+++ b/clang-tidy/performance/InefficientVectorOperationCheck.h
@@ -1,16 +1,15 @@
 //===--- InefficientVectorOperationCheck.h - clang-tidy----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENT_VECTOR_OPERATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_INEFFICIENT_VECTOR_OPERATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tidy/performance/MoveConstArgCheck.cpp
index c64769f..8b5838f 100644
--- a/clang-tidy/performance/MoveConstArgCheck.cpp
+++ b/clang-tidy/performance/MoveConstArgCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MoveConstArgCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/MoveConstArgCheck.h b/clang-tidy/performance/MoveConstArgCheck.h
index 13ed9ae..7fc10ad 100644
--- a/clang-tidy/performance/MoveConstArgCheck.h
+++ b/clang-tidy/performance/MoveConstArgCheck.h
@@ -1,16 +1,15 @@
 //===--- MoveConstArgCheck.h - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONSTANTARGUMENTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONSTANTARGUMENTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tidy/performance/MoveConstructorInitCheck.cpp
index 52283fb..aa5c819 100644
--- a/clang-tidy/performance/MoveConstructorInitCheck.cpp
+++ b/clang-tidy/performance/MoveConstructorInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MoveConstructorInitCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -92,10 +91,11 @@
   }
 }
 
-void MoveConstructorInitCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Inserter.reset(new utils::IncludeInserter(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
-  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+void MoveConstructorInitCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                       IncludeStyle);
+  PP->addPPCallbacks(Inserter->CreatePPCallbacks());
 }
 
 void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
diff --git a/clang-tidy/performance/MoveConstructorInitCheck.h b/clang-tidy/performance/MoveConstructorInitCheck.h
index 3b7dda0..a84d052 100644
--- a/clang-tidy/performance/MoveConstructorInitCheck.h
+++ b/clang-tidy/performance/MoveConstructorInitCheck.h
@@ -1,16 +1,15 @@
 //===--- MoveConstructorInitCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_MOVECONSTRUCTORINITCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_MOVECONSTRUCTORINITCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 
 #include <memory>
@@ -29,7 +28,8 @@
   MoveConstructorInitCheck(StringRef Name, ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  void registerPPCallbacks(clang::CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
 
 private:
diff --git a/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp b/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp
index adc5910..0f9f8cb 100644
--- a/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp
+++ b/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NoexceptMoveConstructorCheck.cpp - clang-tidy---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/NoexceptMoveConstructorCheck.h b/clang-tidy/performance/NoexceptMoveConstructorCheck.h
index 9687ab1..bf000bd 100644
--- a/clang-tidy/performance/NoexceptMoveConstructorCheck.h
+++ b/clang-tidy/performance/NoexceptMoveConstructorCheck.h
@@ -1,16 +1,15 @@
 //===--- NoexceptMoveConstructorCheck.h - clang-tidy-------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_NOEXCEPTMOVECONSTRUCTORCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_NOEXCEPTMOVECONSTRUCTORCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tidy/performance/PerformanceTidyModule.cpp
index 646c659..f4b620a 100644
--- a/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -1,9 +1,8 @@
-//===--- PeformanceTidyModule.cpp - clang-tidy ----------------------------===//
+//===-- PerformanceTidyModule.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/TypePromotionInMathFnCheck.cpp b/clang-tidy/performance/TypePromotionInMathFnCheck.cpp
index 8ff31a0..652a6f9 100644
--- a/clang-tidy/performance/TypePromotionInMathFnCheck.cpp
+++ b/clang-tidy/performance/TypePromotionInMathFnCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TypePromotionInMathFnCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -36,11 +35,10 @@
           Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {}
 
 void TypePromotionInMathFnCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle);
-  Compiler.getPreprocessor().addPPCallbacks(
-      IncludeInserter->CreatePPCallbacks());
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  IncludeInserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                              IncludeStyle);
+  PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
 }
 
 void TypePromotionInMathFnCheck::storeOptions(
diff --git a/clang-tidy/performance/TypePromotionInMathFnCheck.h b/clang-tidy/performance/TypePromotionInMathFnCheck.h
index 2242957..d1cc042 100644
--- a/clang-tidy/performance/TypePromotionInMathFnCheck.h
+++ b/clang-tidy/performance/TypePromotionInMathFnCheck.h
@@ -1,16 +1,15 @@
 //===--- TypePromotionInMathFnCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_TYPE_PROMOTION_IN_MATH_FN_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_TYPE_PROMOTION_IN_MATH_FN_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 
 namespace clang {
@@ -30,7 +29,8 @@
 public:
   TypePromotionInMathFnCheck(StringRef Name, ClangTidyContext *Context);
 
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
diff --git a/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index 6f31057..7e36b37 100644
--- a/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -1,9 +1,8 @@
 //===--- UnnecessaryCopyInitialization.cpp - clang-tidy--------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/UnnecessaryCopyInitialization.h b/clang-tidy/performance/UnnecessaryCopyInitialization.h
index 1844aa4..0a530e3 100644
--- a/clang-tidy/performance/UnnecessaryCopyInitialization.h
+++ b/clang-tidy/performance/UnnecessaryCopyInitialization.h
@@ -1,16 +1,15 @@
 //===--- UnnecessaryCopyInitialization.h - clang-tidy------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_COPY_INITIALIZATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_COPY_INITIALIZATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
index ff3674f..cf66081 100644
--- a/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
+++ b/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UnnecessaryValueParamCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -169,10 +168,10 @@
 }
 
 void UnnecessaryValueParamCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  Inserter.reset(new utils::IncludeInserter(
-      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
-  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                       IncludeStyle);
+  PP->addPPCallbacks(Inserter->CreatePPCallbacks());
 }
 
 void UnnecessaryValueParamCheck::storeOptions(
diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.h b/clang-tidy/performance/UnnecessaryValueParamCheck.h
index a1d6586..c9d22e6 100644
--- a/clang-tidy/performance/UnnecessaryValueParamCheck.h
+++ b/clang-tidy/performance/UnnecessaryValueParamCheck.h
@@ -1,16 +1,15 @@
 //===--- UnnecessaryValueParamCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_VALUE_PARAM_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARY_VALUE_PARAM_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/IncludeInserter.h"
 #include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
 
@@ -28,7 +27,8 @@
   UnnecessaryValueParamCheck(StringRef Name, ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void onEndOfTranslationUnit() override;
 
diff --git a/clang-tidy/plugin/CMakeLists.txt b/clang-tidy/plugin/CMakeLists.txt
index 7a12d7f..25b094f 100644
--- a/clang-tidy/plugin/CMakeLists.txt
+++ b/clang-tidy/plugin/CMakeLists.txt
@@ -21,6 +21,7 @@
   clangTidyMiscModule
   clangTidyModernizeModule
   clangTidyObjCModule
+  clangTidyOpenMPModule
   clangTidyPerformanceModule
   clangTidyPortabilityModule
   clangTidyReadabilityModule
diff --git a/clang-tidy/plugin/ClangTidyPlugin.cpp b/clang-tidy/plugin/ClangTidyPlugin.cpp
index 561dc82..80208c7 100644
--- a/clang-tidy/plugin/ClangTidyPlugin.cpp
+++ b/clang-tidy/plugin/ClangTidyPlugin.cpp
@@ -1,9 +1,8 @@
 //===- ClangTidyPlugin.cpp - clang-tidy as a clang plugin -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/portability/PortabilityTidyModule.cpp b/clang-tidy/portability/PortabilityTidyModule.cpp
index 013cbcf..e12821e 100644
--- a/clang-tidy/portability/PortabilityTidyModule.cpp
+++ b/clang-tidy/portability/PortabilityTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- PortabilityTidyModule.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/portability/SIMDIntrinsicsCheck.cpp b/clang-tidy/portability/SIMDIntrinsicsCheck.cpp
index e104368..d9e3d26 100644
--- a/clang-tidy/portability/SIMDIntrinsicsCheck.cpp
+++ b/clang-tidy/portability/SIMDIntrinsicsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SIMDIntrinsicsCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/portability/SIMDIntrinsicsCheck.h b/clang-tidy/portability/SIMDIntrinsicsCheck.h
index ebcc855..8f3a990 100644
--- a/clang-tidy/portability/SIMDIntrinsicsCheck.h
+++ b/clang-tidy/portability/SIMDIntrinsicsCheck.h
@@ -1,16 +1,15 @@
 //===--- SIMDIntrinsicsCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SIMD_INTRINSICS_CHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SIMD_INTRINSICS_CHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 #include "llvm/ADT/SmallString.h"
 
diff --git a/clang-tidy/readability/AvoidConstParamsInDecls.cpp b/clang-tidy/readability/AvoidConstParamsInDecls.cpp
index 51fc489..91e1495 100644
--- a/clang-tidy/readability/AvoidConstParamsInDecls.cpp
+++ b/clang-tidy/readability/AvoidConstParamsInDecls.cpp
@@ -1,9 +1,8 @@
 //===--- AvoidConstParamsInDecls.cpp - clang-tidy--------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/AvoidConstParamsInDecls.h b/clang-tidy/readability/AvoidConstParamsInDecls.h
index f2d91e8..08aac94 100644
--- a/clang-tidy/readability/AvoidConstParamsInDecls.h
+++ b/clang-tidy/readability/AvoidConstParamsInDecls.h
@@ -1,16 +1,15 @@
 //===--- AvoidConstParamsInDecls.h - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_CONST_PARAMS_IN_DECLS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_CONST_PARAMS_IN_DECLS_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tidy/readability/BracesAroundStatementsCheck.cpp
index 5f5294c..117ef36 100644
--- a/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ b/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- BracesAroundStatementsCheck.cpp - clang-tidy ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/BracesAroundStatementsCheck.h b/clang-tidy/readability/BracesAroundStatementsCheck.h
index 919ca46..7c019c6 100644
--- a/clang-tidy/readability/BracesAroundStatementsCheck.h
+++ b/clang-tidy/readability/BracesAroundStatementsCheck.h
@@ -1,16 +1,15 @@
 //===--- BracesAroundStatementsCheck.h - clang-tidy -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_BRACESAROUNDSTATEMENTSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_BRACESAROUNDSTATEMENTSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tidy/readability/ConstReturnTypeCheck.cpp
index d9654df..0f237ec 100644
--- a/clang-tidy/readability/ConstReturnTypeCheck.cpp
+++ b/clang-tidy/readability/ConstReturnTypeCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ConstReturnTypeCheck.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,8 +22,8 @@
 
 // Finds the location of the qualifying `const` token in the `FunctionDecl`'s
 // return type. Returns `None` when the return type is not `const`-qualified or
-// `const` does not appear in `Def`'s source like when the type is an alias or a
-// macro.
+// `const` does not appear in `Def`'s source, like when the type is an alias or
+// a macro.
 static llvm::Optional<Token>
 findConstToRemove(const FunctionDecl *Def,
                   const MatchFinder::MatchResult &Result) {
diff --git a/clang-tidy/readability/ConstReturnTypeCheck.h b/clang-tidy/readability/ConstReturnTypeCheck.h
index 2c7e94d..3a5fb08 100644
--- a/clang-tidy/readability/ConstReturnTypeCheck.h
+++ b/clang-tidy/readability/ConstReturnTypeCheck.h
@@ -1,16 +1,15 @@
 //===--- ConstReturnTypeCheck.h - clang-tidy --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONSTRETURNTYPECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONSTRETURNTYPECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
index 97f9eb7..fe0e1c0 100644
--- a/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ b/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ContainerSizeEmptyCheck.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "ContainerSizeEmptyCheck.h"
diff --git a/clang-tidy/readability/ContainerSizeEmptyCheck.h b/clang-tidy/readability/ContainerSizeEmptyCheck.h
index bde83f8..26a6b9e 100644
--- a/clang-tidy/readability/ContainerSizeEmptyCheck.h
+++ b/clang-tidy/readability/ContainerSizeEmptyCheck.h
@@ -1,16 +1,15 @@
 //===--- ContainerSizeEmptyCheck.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONTAINERSIZEEMPTYCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONTAINERSIZEEMPTYCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/DeleteNullPointerCheck.cpp b/clang-tidy/readability/DeleteNullPointerCheck.cpp
index 02b9bbe..0c5eace 100644
--- a/clang-tidy/readability/DeleteNullPointerCheck.cpp
+++ b/clang-tidy/readability/DeleteNullPointerCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DeleteNullPointerCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/DeleteNullPointerCheck.h b/clang-tidy/readability/DeleteNullPointerCheck.h
index 501f6f7..0e310f7 100644
--- a/clang-tidy/readability/DeleteNullPointerCheck.h
+++ b/clang-tidy/readability/DeleteNullPointerCheck.h
@@ -1,16 +1,15 @@
 //===--- DeleteNullPointerCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETE_NULL_POINTER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETE_NULL_POINTER_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/DeletedDefaultCheck.cpp b/clang-tidy/readability/DeletedDefaultCheck.cpp
index e99ca83..ff2f00b 100644
--- a/clang-tidy/readability/DeletedDefaultCheck.cpp
+++ b/clang-tidy/readability/DeletedDefaultCheck.cpp
@@ -1,9 +1,8 @@
 //===--- DeletedDefaultCheck.cpp - clang-tidy------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/DeletedDefaultCheck.h b/clang-tidy/readability/DeletedDefaultCheck.h
index 0608b07..ab7f141 100644
--- a/clang-tidy/readability/DeletedDefaultCheck.h
+++ b/clang-tidy/readability/DeletedDefaultCheck.h
@@ -1,16 +1,15 @@
 //===--- DeletedDefaultCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DELETED_DEFAULT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tidy/readability/ElseAfterReturnCheck.cpp
index be8de25..520586d 100644
--- a/clang-tidy/readability/ElseAfterReturnCheck.cpp
+++ b/clang-tidy/readability/ElseAfterReturnCheck.cpp
@@ -1,58 +1,63 @@
-//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===//

-//

-//                     The LLVM Compiler Infrastructure

-//

-// This file is distributed under the University of Illinois Open Source

-// License. See LICENSE.TXT for details.

-//

-//===----------------------------------------------------------------------===//

-

-#include "ElseAfterReturnCheck.h"

-#include "clang/AST/ASTContext.h"

-#include "clang/ASTMatchers/ASTMatchFinder.h"

-#include "clang/Tooling/FixIt.h"

-

-using namespace clang::ast_matchers;

-

-namespace clang {

-namespace tidy {

-namespace readability {

-

-void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {

-  const auto ControlFlowInterruptorMatcher =

-      stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),

-                 breakStmt().bind("break"),

-                 expr(ignoringImplicit(cxxThrowExpr().bind("throw")))));

-  Finder->addMatcher(

-      compoundStmt(forEach(

-          ifStmt(unless(isConstexpr()),

-                 hasThen(stmt(

-                     anyOf(ControlFlowInterruptorMatcher,

-                           compoundStmt(has(ControlFlowInterruptorMatcher))))),

-                 hasElse(stmt().bind("else")))

-              .bind("if"))),

-      this);

-}

-

-void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {

-  const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");

-  SourceLocation ElseLoc = If->getElseLoc();

-  std::string ControlFlowInterruptor;

-  for (const auto *BindingName : {"return", "continue", "break", "throw"})

-    if (Result.Nodes.getNodeAs<Stmt>(BindingName))

-      ControlFlowInterruptor = BindingName;

-

-  DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'")

-                           << ControlFlowInterruptor;

-  Diag << tooling::fixit::createRemoval(ElseLoc);

-

-  // FIXME: Removing the braces isn't always safe. Do a more careful analysis.

-  // FIXME: Change clang-format to correctly un-indent the code.

-  if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("else"))

-    Diag << tooling::fixit::createRemoval(CS->getLBracLoc())

-         << tooling::fixit::createRemoval(CS->getRBracLoc());

-}

-

-} // namespace readability

-} // namespace tidy

-} // namespace clang

+//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ElseAfterReturnCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
+  const auto InterruptsControlFlow =
+      stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),
+                 breakStmt().bind("break"),
+                 expr(ignoringImplicit(cxxThrowExpr().bind("throw")))));
+  Finder->addMatcher(
+      compoundStmt(forEach(
+          ifStmt(unless(isConstexpr()),
+                 // FIXME: Explore alternatives for the
+                 // `if (T x = ...) {... return; } else { <use x> }`
+                 // pattern:
+                 //   * warn, but don't fix;
+                 //   * fix by pulling out the variable declaration out of
+                 //     the condition.
+                 unless(hasConditionVariableStatement(anything())),
+                 hasThen(stmt(anyOf(InterruptsControlFlow,
+                                    compoundStmt(has(InterruptsControlFlow))))),
+                 hasElse(stmt().bind("else")))
+              .bind("if"))),
+      this);
+}
+
+void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
+  SourceLocation ElseLoc = If->getElseLoc();
+  std::string ControlFlowInterruptor;
+  for (const auto *BindingName : {"return", "continue", "break", "throw"})
+    if (Result.Nodes.getNodeAs<Stmt>(BindingName))
+      ControlFlowInterruptor = BindingName;
+
+  DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'")
+                           << ControlFlowInterruptor;
+  Diag << tooling::fixit::createRemoval(ElseLoc);
+
+  // FIXME: Removing the braces isn't always safe. Do a more careful analysis.
+  // FIXME: Change clang-format to correctly un-indent the code.
+  if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("else"))
+    Diag << tooling::fixit::createRemoval(CS->getLBracLoc())
+         << tooling::fixit::createRemoval(CS->getRBracLoc());
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/readability/ElseAfterReturnCheck.h b/clang-tidy/readability/ElseAfterReturnCheck.h
index 8479ab5..0aa47b5 100644
--- a/clang-tidy/readability/ElseAfterReturnCheck.h
+++ b/clang-tidy/readability/ElseAfterReturnCheck.h
@@ -1,16 +1,15 @@
 //===--- ElseAfterReturnCheck.h - clang-tidy---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ELSEAFTERRETURNCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ELSEAFTERRETURNCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tidy/readability/FunctionSizeCheck.cpp
index 4d91f2e..d98bec2 100644
--- a/clang-tidy/readability/FunctionSizeCheck.cpp
+++ b/clang-tidy/readability/FunctionSizeCheck.cpp
@@ -1,9 +1,8 @@
-//===--- FunctionSize.cpp - clang-tidy ------------------------------------===//
+//===-- FunctionSizeCheck.cpp - clang-tidy --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/FunctionSizeCheck.h b/clang-tidy/readability/FunctionSizeCheck.h
index 7defccd..d85dbc9 100644
--- a/clang-tidy/readability/FunctionSizeCheck.h
+++ b/clang-tidy/readability/FunctionSizeCheck.h
@@ -1,16 +1,15 @@
 //===--- FunctionSizeCheck.h - clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_FUNCTIONSIZECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_FUNCTIONSIZECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tidy/readability/IdentifierNamingCheck.cpp
index fb3c02e..7e56fe1 100644
--- a/clang-tidy/readability/IdentifierNamingCheck.cpp
+++ b/clang-tidy/readability/IdentifierNamingCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IdentifierNamingCheck.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -241,10 +240,11 @@
   Finder->addMatcher(nestedNameSpecifierLoc().bind("nestedNameLoc"), this);
 }
 
-void IdentifierNamingCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<IdentifierNamingCheckPPCallbacks>(
-          &Compiler.getPreprocessor(), this));
+void IdentifierNamingCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  ModuleExpanderPP->addPPCallbacks(
+      llvm::make_unique<IdentifierNamingCheckPPCallbacks>(ModuleExpanderPP,
+                                                          this));
 }
 
 static bool matchesStyle(StringRef Name,
diff --git a/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tidy/readability/IdentifierNamingCheck.h
index c236ad5..b7487e0 100644
--- a/clang-tidy/readability/IdentifierNamingCheck.h
+++ b/clang-tidy/readability/IdentifierNamingCheck.h
@@ -1,16 +1,15 @@
 //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERNAMINGCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 
@@ -39,7 +38,8 @@
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
   void onEndOfTranslationUnit() override;
 
   enum CaseType {
diff --git a/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index b8ae224..aae5bcf 100644
--- a/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -1,9 +1,8 @@
 //===--- ImplicitBoolConversionCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tidy/readability/ImplicitBoolConversionCheck.h
index bb062e0..db3dc20 100644
--- a/clang-tidy/readability/ImplicitBoolConversionCheck.h
+++ b/clang-tidy/readability/ImplicitBoolConversionCheck.h
@@ -1,16 +1,15 @@
 //===--- ImplicitBoolConversionCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp
index 280c354..64a955f 100644
--- a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp
+++ b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp
@@ -1,9 +1,8 @@
 //===--- InconsistentDeclarationParameterNameCheck.cpp - clang-tidy-------===//
 //
-//           The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h
index 602856f..94b48ca 100644
--- a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h
+++ b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h
@@ -1,16 +1,15 @@
 //===- InconsistentDeclarationParameterNameCheck.h - clang-tidy-*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_INCONSISTENT_DECLARATION_PARAMETER_NAME_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_INCONSISTENT_DECLARATION_PARAMETER_NAME_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 #include "llvm/ADT/DenseSet.h"
 
diff --git a/clang-tidy/readability/IsolateDeclarationCheck.cpp b/clang-tidy/readability/IsolateDeclarationCheck.cpp
index e9ccb17..32177ad 100644
--- a/clang-tidy/readability/IsolateDeclarationCheck.cpp
+++ b/clang-tidy/readability/IsolateDeclarationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- IsolateDeclarationCheck.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/IsolateDeclarationCheck.h b/clang-tidy/readability/IsolateDeclarationCheck.h
index b7f4793..29f547e 100644
--- a/clang-tidy/readability/IsolateDeclarationCheck.h
+++ b/clang-tidy/readability/IsolateDeclarationCheck.h
@@ -1,16 +1,15 @@
 //===--- IsolateDeclarationCheck.h - clang-tidy -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ISOLATEDECLCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ISOLATEDECLCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tidy/readability/MagicNumbersCheck.cpp
index 0a08721..39aaf89 100644
--- a/clang-tidy/readability/MagicNumbersCheck.cpp
+++ b/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MagicNumbersCheck.cpp - clang-tidy-------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-tidy/readability/MagicNumbersCheck.h b/clang-tidy/readability/MagicNumbersCheck.h
index db4cc88..e59ca17 100644
--- a/clang-tidy/readability/MagicNumbersCheck.h
+++ b/clang-tidy/readability/MagicNumbersCheck.h
@@ -1,16 +1,15 @@
 //===--- MagicNumbersCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include <llvm/ADT/APFloat.h>
 #include <llvm/ADT/SmallVector.h>
 #include <vector>
diff --git a/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tidy/readability/MisleadingIndentationCheck.cpp
index 9791531..0fd5c1f 100644
--- a/clang-tidy/readability/MisleadingIndentationCheck.cpp
+++ b/clang-tidy/readability/MisleadingIndentationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MisleadingIndentationCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -82,6 +81,10 @@
     SourceLocation InnerLoc = Inner->getBeginLoc();
     SourceLocation OuterLoc = CurrentStmt->getBeginLoc();
 
+    if (InnerLoc.isInvalid() || InnerLoc.isMacroID() || OuterLoc.isInvalid() ||
+        OuterLoc.isMacroID())
+      continue;
+
     if (SM.getExpansionLineNumber(InnerLoc) ==
         SM.getExpansionLineNumber(OuterLoc))
       continue;
@@ -89,7 +92,7 @@
     const Stmt *NextStmt = CStmt->body_begin()[i + 1];
     SourceLocation NextLoc = NextStmt->getBeginLoc();
 
-    if (InnerLoc.isMacroID() || OuterLoc.isMacroID() || NextLoc.isMacroID())
+    if (NextLoc.isInvalid() || NextLoc.isMacroID())
       continue;
 
     if (SM.getExpansionColumnNumber(InnerLoc) ==
diff --git a/clang-tidy/readability/MisleadingIndentationCheck.h b/clang-tidy/readability/MisleadingIndentationCheck.h
index 0ca50bb..ed5ba5b 100644
--- a/clang-tidy/readability/MisleadingIndentationCheck.h
+++ b/clang-tidy/readability/MisleadingIndentationCheck.h
@@ -1,16 +1,15 @@
 //===--- MisleadingIndentationCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MISLEADING_INDENTATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MISLEADING_INDENTATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/MisplacedArrayIndexCheck.cpp b/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
index 3d1971b..7b39012 100644
--- a/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
+++ b/clang-tidy/readability/MisplacedArrayIndexCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MisplacedArrayIndexCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/MisplacedArrayIndexCheck.h b/clang-tidy/readability/MisplacedArrayIndexCheck.h
index e9a2231..e4256b5 100644
--- a/clang-tidy/readability/MisplacedArrayIndexCheck.h
+++ b/clang-tidy/readability/MisplacedArrayIndexCheck.h
@@ -1,16 +1,15 @@
 //===--- MisplacedArrayIndexCheck.h - clang-tidy-----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MISPLACED_ARRAY_INDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MISPLACED_ARRAY_INDEX_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/NamedParameterCheck.cpp b/clang-tidy/readability/NamedParameterCheck.cpp
index 6fa9e68..09b03fe 100644
--- a/clang-tidy/readability/NamedParameterCheck.cpp
+++ b/clang-tidy/readability/NamedParameterCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NamedParameterCheck.cpp - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/NamedParameterCheck.h b/clang-tidy/readability/NamedParameterCheck.h
index bd38ad2..33a51b4 100644
--- a/clang-tidy/readability/NamedParameterCheck.h
+++ b/clang-tidy/readability/NamedParameterCheck.h
@@ -1,16 +1,15 @@
 //===--- NamedParameterCheck.h - clang-tidy ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NAMEDPARAMETERCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NAMEDPARAMETERCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tidy/readability/NamespaceCommentCheck.cpp
index 229cc62..6428f8c 100644
--- a/clang-tidy/readability/NamespaceCommentCheck.cpp
+++ b/clang-tidy/readability/NamespaceCommentCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NamespaceCommentCheck.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -103,11 +102,14 @@
     }
   }
 
+  // FIXME: This probably breaks on comments between the namespace and its '{'.
   auto TextRange =
       Lexer::getAsCharRange(SourceRange(NestedNamespaceBegin, LBracketLocation),
                             Sources, getLangOpts());
   StringRef NestedNamespaceName =
-      Lexer::getSourceText(TextRange, Sources, getLangOpts()).rtrim();
+      Lexer::getSourceText(TextRange, Sources, getLangOpts())
+          .rtrim('{') // Drop the { itself.
+          .rtrim();   // Drop any whitespace before it.
   bool IsNested = NestedNamespaceName.contains(':');
 
   if (IsNested)
diff --git a/clang-tidy/readability/NamespaceCommentCheck.h b/clang-tidy/readability/NamespaceCommentCheck.h
index 1b1a231..712cd46 100644
--- a/clang-tidy/readability/NamespaceCommentCheck.h
+++ b/clang-tidy/readability/NamespaceCommentCheck.h
@@ -1,16 +1,15 @@
 //===--- NamespaceCommentCheck.h - clang-tidy -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NAMESPACECOMMENTCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NAMESPACECOMMENTCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "llvm/Support/Regex.h"
 
 namespace clang {
diff --git a/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tidy/readability/NonConstParameterCheck.cpp
index e33191c..4372e74 100644
--- a/clang-tidy/readability/NonConstParameterCheck.cpp
+++ b/clang-tidy/readability/NonConstParameterCheck.cpp
@@ -1,9 +1,8 @@
 //===--- NonConstParameterCheck.cpp - clang-tidy---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/NonConstParameterCheck.h b/clang-tidy/readability/NonConstParameterCheck.h
index 3cc73e9..39959e6 100644
--- a/clang-tidy/readability/NonConstParameterCheck.h
+++ b/clang-tidy/readability/NonConstParameterCheck.h
@@ -1,16 +1,15 @@
 //===--- NonConstParameterCheck.h - clang-tidy-------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NON_CONST_PARAMETER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NON_CONST_PARAMETER_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tidy/readability/ReadabilityTidyModule.cpp
index e032d1f..5b2aed4 100644
--- a/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- ReadabilityTidyModule.cpp - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantControlFlowCheck.cpp b/clang-tidy/readability/RedundantControlFlowCheck.cpp
index d5898ed..003c05f 100644
--- a/clang-tidy/readability/RedundantControlFlowCheck.cpp
+++ b/clang-tidy/readability/RedundantControlFlowCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantControlFlowCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantControlFlowCheck.h b/clang-tidy/readability/RedundantControlFlowCheck.h
index 4b8b6fb..d4513e6 100644
--- a/clang-tidy/readability/RedundantControlFlowCheck.h
+++ b/clang-tidy/readability/RedundantControlFlowCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantControlFlowCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_CONTROL_FLOW_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_CONTROL_FLOW_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tidy/readability/RedundantDeclarationCheck.cpp
index c5b6cc3..ff3809a 100644
--- a/clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ b/clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantDeclarationCheck.cpp - clang-tidy------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantDeclarationCheck.h b/clang-tidy/readability/RedundantDeclarationCheck.h
index 9be79b8..fbd0539 100644
--- a/clang-tidy/readability/RedundantDeclarationCheck.h
+++ b/clang-tidy/readability/RedundantDeclarationCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantDeclarationCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_DECLARATION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_DECLARATION_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
index fa503c5..f2360a0 100644
--- a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
+++ b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantFunctionPtrDereferenceCheck.cpp - clang-tidy-------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h
index 4cf6d11..7a284b3 100644
--- a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h
+++ b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantFunctionPtrDereferenceCheck.h - clang-tidy-----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_FUNCTION_PTR_DEREFERENCE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_FUNCTION_PTR_DEREFERENCE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tidy/readability/RedundantMemberInitCheck.cpp
index 8409f9f..d38d0a2 100644
--- a/clang-tidy/readability/RedundantMemberInitCheck.cpp
+++ b/clang-tidy/readability/RedundantMemberInitCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantMemberInitCheck.cpp - clang-tidy-------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantMemberInitCheck.h b/clang-tidy/readability/RedundantMemberInitCheck.h
index 13cc9d3..73ced11 100644
--- a/clang-tidy/readability/RedundantMemberInitCheck.h
+++ b/clang-tidy/readability/RedundantMemberInitCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantMemberInitCheck.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_MEMBER_INIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_MEMBER_INIT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.cpp b/clang-tidy/readability/RedundantPreprocessorCheck.cpp
index 352e234..ea46d53 100644
--- a/clang-tidy/readability/RedundantPreprocessorCheck.cpp
+++ b/clang-tidy/readability/RedundantPreprocessorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantPreprocessorCheck.cpp - clang-tidy ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -98,10 +97,9 @@
 } // namespace
 
 void RedundantPreprocessorCheck::registerPPCallbacks(
-    CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      ::llvm::make_unique<RedundantPreprocessorCallbacks>(
-          *this, Compiler.getPreprocessor()));
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(
+      ::llvm::make_unique<RedundantPreprocessorCallbacks>(*this, *PP));
 }
 
 } // namespace readability
diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.h b/clang-tidy/readability/RedundantPreprocessorCheck.h
index d440765..af4ccaa 100644
--- a/clang-tidy/readability/RedundantPreprocessorCheck.h
+++ b/clang-tidy/readability/RedundantPreprocessorCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantPreprocessorCheck.h - clang-tidy --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPREPROCESSORCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPREPROCESSORCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -25,7 +24,8 @@
 public:
   RedundantPreprocessorCheck(StringRef Name, ClangTidyContext *Context)
       : ClangTidyCheck(Name, Context) {}
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace readability
diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tidy/readability/RedundantSmartptrGetCheck.cpp
index 189130e..834c0cb 100644
--- a/clang-tidy/readability/RedundantSmartptrGetCheck.cpp
+++ b/clang-tidy/readability/RedundantSmartptrGetCheck.cpp
@@ -1,9 +1,8 @@
 //===--- RedundantSmartptrGetCheck.cpp - clang-tidy -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,6 +30,10 @@
       .bind("redundant_get");
 }
 
+internal::Matcher<Decl> knownSmartptr() {
+  return recordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr"));
+}
+
 void registerMatchersForGetArrowStart(MatchFinder *Finder,
                                       MatchFinder::MatchCallback *Callback) {
   const auto QuacksLikeASmartptr = recordDecl(
@@ -40,21 +43,23 @@
       has(cxxMethodDecl(hasName("operator*"), returns(qualType(references(
                                                   type().bind("op*Type")))))));
 
+  // Make sure we are not missing the known standard types.
+  const auto Smartptr = anyOf(knownSmartptr(), QuacksLikeASmartptr);
+
   // Catch 'ptr.get()->Foo()'
-  Finder->addMatcher(memberExpr(expr().bind("memberExpr"), isArrow(),
-                                hasObjectExpression(ignoringImpCasts(
-                                    callToGet(QuacksLikeASmartptr)))),
-                     Callback);
+  Finder->addMatcher(
+      memberExpr(expr().bind("memberExpr"), isArrow(),
+                 hasObjectExpression(ignoringImpCasts(callToGet(Smartptr)))),
+      Callback);
 
   // Catch '*ptr.get()' or '*ptr->get()'
   Finder->addMatcher(
-      unaryOperator(hasOperatorName("*"),
-                    hasUnaryOperand(callToGet(QuacksLikeASmartptr))),
+      unaryOperator(hasOperatorName("*"), hasUnaryOperand(callToGet(Smartptr))),
       Callback);
 
   // Catch '!ptr.get()'
-  const auto CallToGetAsBool = ignoringParenImpCasts(callToGet(recordDecl(
-      QuacksLikeASmartptr, has(cxxConversionDecl(returns(booleanType()))))));
+  const auto CallToGetAsBool = ignoringParenImpCasts(callToGet(
+      recordDecl(Smartptr, has(cxxConversionDecl(returns(booleanType()))))));
   Finder->addMatcher(
       unaryOperator(hasOperatorName("!"), hasUnaryOperand(CallToGetAsBool)),
       Callback);
@@ -72,10 +77,7 @@
   // This one is harder to do with duck typing.
   // The operator==/!= that we are looking for might be member or non-member,
   // might be on global namespace or found by ADL, might be a template, etc.
-  // For now, lets keep a list of known standard types.
-
-  const auto IsAKnownSmartptr =
-      recordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr"));
+  // For now, lets keep it to the known standard types.
 
   // Matches against nullptr.
   Finder->addMatcher(
@@ -83,7 +85,7 @@
                      hasEitherOperand(ignoringImpCasts(
                          anyOf(cxxNullPtrLiteralExpr(), gnuNullExpr(),
                                integerLiteral(equals(0))))),
-                     hasEitherOperand(callToGet(IsAKnownSmartptr))),
+                     hasEitherOperand(callToGet(knownSmartptr()))),
       Callback);
 
   // FIXME: Match and fix if (l.get() == r.get()).
diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.h b/clang-tidy/readability/RedundantSmartptrGetCheck.h
index a6f5706..66c1354 100644
--- a/clang-tidy/readability/RedundantSmartptrGetCheck.h
+++ b/clang-tidy/readability/RedundantSmartptrGetCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantSmartptrGetCheck.h - clang-tidy ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSMARTPTRGETCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSMARTPTRGETCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tidy/readability/RedundantStringCStrCheck.cpp
index 903a0ed..f7b0dfc 100644
--- a/clang-tidy/readability/RedundantStringCStrCheck.cpp
+++ b/clang-tidy/readability/RedundantStringCStrCheck.cpp
@@ -1,9 +1,8 @@
 //===- RedundantStringCStrCheck.cpp - Check for redundant c_str calls -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clang-tidy/readability/RedundantStringCStrCheck.h b/clang-tidy/readability/RedundantStringCStrCheck.h
index 9406f8e..0448865 100644
--- a/clang-tidy/readability/RedundantStringCStrCheck.h
+++ b/clang-tidy/readability/RedundantStringCStrCheck.h
@@ -1,16 +1,15 @@
 //===--- RedundantStringCStrCheck.h - clang-tidy ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSTRINGCSTRCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTSTRINGCSTRCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tidy/readability/RedundantStringInitCheck.cpp
index 46ce2a4..9a9a383 100644
--- a/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ b/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -1,9 +1,8 @@
 //===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantStringInitCheck.h b/clang-tidy/readability/RedundantStringInitCheck.h
index 0a32eb6..b1f551e 100644
--- a/clang-tidy/readability/RedundantStringInitCheck.h
+++ b/clang-tidy/readability/RedundantStringInitCheck.h
@@ -1,16 +1,15 @@
 //===- RedundantStringInitCheck.h - clang-tidy ------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
index 710635e..ef88d44 100644
--- a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -1,9 +1,8 @@
-//===--- SimplifyBooleanExpr.cpp clang-tidy ---------------------*- C++ -*-===//
+//===-- SimplifyBooleanExprCheck.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tidy/readability/SimplifyBooleanExprCheck.h
index af47453..0649536 100644
--- a/clang-tidy/readability/SimplifyBooleanExprCheck.h
+++ b/clang-tidy/readability/SimplifyBooleanExprCheck.h
@@ -1,16 +1,15 @@
 //===--- SimplifyBooleanExpr.h clang-tidy -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/SimplifySubscriptExprCheck.cpp b/clang-tidy/readability/SimplifySubscriptExprCheck.cpp
index f4c306e..ec060f8 100644
--- a/clang-tidy/readability/SimplifySubscriptExprCheck.cpp
+++ b/clang-tidy/readability/SimplifySubscriptExprCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SimplifySubscriptExprCheck.cpp - clang-tidy-----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/SimplifySubscriptExprCheck.h b/clang-tidy/readability/SimplifySubscriptExprCheck.h
index 86a21b9..01d4e4b 100644
--- a/clang-tidy/readability/SimplifySubscriptExprCheck.h
+++ b/clang-tidy/readability/SimplifySubscriptExprCheck.h
@@ -1,16 +1,15 @@
 //===--- SimplifySubscriptExprCheck.h - clang-tidy---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFYSUBSCRIPTEXPRCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFYSUBSCRIPTEXPRCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
index 92d7879..8458fe3 100644
--- a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
+++ b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StaticAccessedThroughInstanceCheck.cpp - clang-tidy---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h
index c2eebab..3d4d5e7 100644
--- a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h
+++ b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h
@@ -1,16 +1,15 @@
 //===--- StaticAccessedThroughInstanceCheck.h - clang-tidy-------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_ACCESSED_THROUGH_INSTANCE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_ACCESSED_THROUGH_INSTANCE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
index 0554605..ef973a1 100644
--- a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
+++ b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp
@@ -1,9 +1,8 @@
 //===--- StaticDefinitionInAnonymousNamespaceCheck.cpp - clang-tidy--------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
index 03e99fd..18f93b8 100644
--- a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
+++ b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
@@ -1,16 +1,15 @@
 //===--- StaticDefinitionInAnonymousNamespaceCheck.h - clang-tidy*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_DEFINITION_IN_ANONYMOUS_NAMESPACE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STATIC_DEFINITION_IN_ANONYMOUS_NAMESPACE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/StringCompareCheck.cpp b/clang-tidy/readability/StringCompareCheck.cpp
index 38ac43f..1064c3a 100644
--- a/clang-tidy/readability/StringCompareCheck.cpp
+++ b/clang-tidy/readability/StringCompareCheck.cpp
@@ -1,9 +1,8 @@
-//===--- MiscStringCompare.cpp - clang-tidy--------------------------------===//
+//===-- StringCompareCheck.cpp - clang-tidy--------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/StringCompareCheck.h b/clang-tidy/readability/StringCompareCheck.h
index 248d2ee..d58cce6 100644
--- a/clang-tidy/readability/StringCompareCheck.h
+++ b/clang-tidy/readability/StringCompareCheck.h
@@ -1,16 +1,15 @@
 //===--- StringCompareCheck.h - clang-tidy-----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRINGCOMPARECHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRINGCOMPARECHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
index bb2c690..478a3f2 100644
--- a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
+++ b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UniqueptrDeleteReleaseCheck.cpp - clang-tidy----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
index fd86bdb..3e6f184 100644
--- a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
+++ b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
@@ -1,16 +1,15 @@
 //===--- UniqueptrDeleteReleaseCheck.h - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNIQUEPTR_DELETE_RELEASE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UNIQUEPTR_DELETE_RELEASE_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 
 namespace clang {
 namespace tidy {
diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp
index 588fb26..eef63b7 100644
--- a/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp
+++ b/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp
@@ -1,9 +1,8 @@
 //===--- UppercaseLiteralSuffixCheck.cpp - clang-tidy ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
index 7aa631a..c31fc06 100644
--- a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
+++ b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
@@ -1,16 +1,15 @@
 //===--- UppercaseLiteralSuffixCheck.h - clang-tidy -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UPPERCASELITERALSUFFIXCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UPPERCASELITERALSUFFIXCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/OptionsUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/rename_check.py b/clang-tidy/rename_check.py
index 53a5ff9..4eb3d74 100755
--- a/clang-tidy/rename_check.py
+++ b/clang-tidy/rename_check.py
@@ -2,10 +2,9 @@
 #
 #===- rename_check.py - clang-tidy check renamer -------------*- python -*--===#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 
diff --git a/clang-tidy/tool/CMakeLists.txt b/clang-tidy/tool/CMakeLists.txt
index f58cfea..71d57ff 100644
--- a/clang-tidy/tool/CMakeLists.txt
+++ b/clang-tidy/tool/CMakeLists.txt
@@ -9,7 +9,7 @@
   ClangTidyMain.cpp
   )
 add_dependencies(clang-tidy
-  clang-headers
+  clang-resource-headers
   )
 target_link_libraries(clang-tidy
   PRIVATE
@@ -30,6 +30,7 @@
   clangTidyMiscModule
   clangTidyModernizeModule
   clangTidyObjCModule
+  clangTidyOpenMPModule
   clangTidyPerformanceModule
   clangTidyPortabilityModule
   clangTidyReadabilityModule
diff --git a/clang-tidy/tool/ClangTidyMain.cpp b/clang-tidy/tool/ClangTidyMain.cpp
index 12a6024..06291e9 100644
--- a/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tidy/tool/ClangTidyMain.cpp
@@ -1,9 +1,8 @@
 //===--- tools/extra/clang-tidy/ClangTidyMain.cpp - Clang tidy tool -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -305,11 +304,10 @@
 }
 
 llvm::IntrusiveRefCntPtr<vfs::FileSystem>
-getVfsOverlayFromFile(const std::string &OverlayFile) {
-  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFS(
-      new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
+getVfsFromFile(const std::string &OverlayFile,
+               llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS) {
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
-      OverlayFS->getBufferForFile(OverlayFile);
+      BaseFS->getBufferForFile(OverlayFile);
   if (!Buffer) {
     llvm::errs() << "Can't load virtual filesystem overlay file '"
                  << OverlayFile << "': " << Buffer.getError().message()
@@ -324,19 +322,23 @@
                  << OverlayFile << "'.\n";
     return nullptr;
   }
-  OverlayFS->pushOverlay(FS);
-  return OverlayFS;
+  return FS;
 }
 
 static int clangTidyMain(int argc, const char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
   CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory,
                                     cl::ZeroOrMore);
-  llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS(
-      VfsOverlay.empty() ? vfs::getRealFileSystem()
-                         : getVfsOverlayFromFile(VfsOverlay));
-  if (!BaseFS)
-    return 1;
+  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> BaseFS(
+      new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
+
+  if (!VfsOverlay.empty()) {
+    IntrusiveRefCntPtr<vfs::FileSystem> VfsFromFile =
+        getVfsFromFile(VfsOverlay, BaseFS);
+    if (!VfsFromFile)
+      return 1;
+    BaseFS->pushOverlay(VfsFromFile);
+  }
 
   auto OwningOptionsProvider = createOptionsProvider(BaseFS);
   auto *OptionsProvider = OwningOptionsProvider.get();
diff --git a/clang-tidy/tool/clang-tidy-diff.py b/clang-tidy/tool/clang-tidy-diff.py
index 5eb2e3d..8b6ad90 100755
--- a/clang-tidy/tool/clang-tidy-diff.py
+++ b/clang-tidy/tool/clang-tidy-diff.py
@@ -2,10 +2,9 @@
 #
 #===- clang-tidy-diff.py - ClangTidy Diff Checker ------------*- python -*--===#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 
@@ -25,10 +24,94 @@
 """
 
 import argparse
+import glob
 import json
+import multiprocessing
+import os
 import re
+import shutil
 import subprocess
 import sys
+import tempfile
+import threading
+import traceback
+
+try:
+  import yaml
+except ImportError:
+  yaml = None
+
+is_py2 = sys.version[0] == '2'
+
+if is_py2:
+    import Queue as queue
+else:
+    import queue as queue
+
+
+def run_tidy(task_queue, lock, timeout):
+  watchdog = None
+  while True:
+    command = task_queue.get()
+    try:
+      proc = subprocess.Popen(command,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE)
+
+      if timeout is not None:
+        watchdog = threading.Timer(timeout, proc.kill)
+        watchdog.start()
+
+      stdout, stderr = proc.communicate()
+
+      with lock:
+        sys.stdout.write(stdout.decode('utf-8') + '\n')
+        sys.stdout.flush()
+        if stderr:
+          sys.stderr.write(stderr.decode('utf-8') + '\n')
+          sys.stderr.flush()
+    except Exception as e:
+      with lock:
+        sys.stderr.write('Failed: ' + str(e) + ': '.join(command) + '\n')
+    finally:
+      with lock:
+        if (not timeout is None) and (not watchdog is None):
+          if not watchdog.is_alive():
+              sys.stderr.write('Terminated by timeout: ' +
+                               ' '.join(command) + '\n')
+          watchdog.cancel()
+      task_queue.task_done()
+
+
+def start_workers(max_tasks, tidy_caller, task_queue, lock, timeout):
+  for _ in range(max_tasks):
+    t = threading.Thread(target=tidy_caller, args=(task_queue, lock, timeout))
+    t.daemon = True
+    t.start()
+
+def merge_replacement_files(tmpdir, mergefile):
+  """Merge all replacement files in a directory into a single file"""
+  # The fixes suggested by clang-tidy >= 4.0.0 are given under
+  # the top level key 'Diagnostics' in the output yaml files
+  mergekey = "Diagnostics"
+  merged = []
+  for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')):
+    content = yaml.safe_load(open(replacefile, 'r'))
+    if not content:
+      continue # Skip empty files.
+    merged.extend(content.get(mergekey, []))
+
+  if merged:
+    # MainSourceFile: The key is required by the definition inside
+    # include/clang/Tooling/ReplacementsYaml.h, but the value
+    # is actually never used inside clang-apply-replacements,
+    # so we set it to '' here.
+    output = { 'MainSourceFile': '', mergekey: merged }
+    with open(mergefile, 'w') as out:
+      yaml.safe_dump(output, out)
+  else:
+    # Empty the file:
+    open(mergefile, 'w').close()
 
 
 def main():
@@ -48,7 +131,10 @@
                       r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)',
                       help='custom pattern selecting file paths to check '
                       '(case insensitive, overridden by -regex)')
-
+  parser.add_argument('-j', type=int, default=1,
+                      help='number of tidy instances to be run in parallel.')
+  parser.add_argument('-timeout', type=int, default=None,
+                      help='timeout per each file in seconds.')
   parser.add_argument('-fix', action='store_true', default=False,
                       help='apply suggested fixes')
   parser.add_argument('-checks',
@@ -57,9 +143,10 @@
                       default='')
   parser.add_argument('-path', dest='build_path',
                       help='Path used to read a compile command database.')
-  parser.add_argument('-export-fixes', metavar='FILE', dest='export_fixes',
-                      help='Create a yaml file to store suggested fixes in, '
-                      'which can be applied with clang-apply-replacements.')
+  if yaml:
+    parser.add_argument('-export-fixes', metavar='FILE', dest='export_fixes',
+                        help='Create a yaml file to store suggested fixes in, '
+                        'which can be applied with clang-apply-replacements.')
   parser.add_argument('-extra-arg', dest='extra_arg',
                       action='append', default=[],
                       help='Additional argument to append to the compiler '
@@ -85,7 +172,7 @@
     match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % args.p, line)
     if match:
       filename = match.group(2)
-    if filename == None:
+    if filename is None:
       continue
 
     if args.regex is not None:
@@ -103,44 +190,79 @@
         line_count = int(match.group(3))
       if line_count == 0:
         continue
-      end_line = start_line + line_count - 1;
+      end_line = start_line + line_count - 1
       lines_by_file.setdefault(filename, []).append([start_line, end_line])
 
-  if len(lines_by_file) == 0:
+  if not any(lines_by_file):
     print("No relevant changes found.")
     sys.exit(0)
 
-  line_filter_json = json.dumps(
-    [{"name" : name, "lines" : lines_by_file[name]} for name in lines_by_file],
-    separators = (',', ':'))
+  max_task_count = args.j
+  if max_task_count == 0:
+      max_task_count = multiprocessing.cpu_count()
+  max_task_count = min(len(lines_by_file), max_task_count)
 
-  quote = "";
-  if sys.platform == 'win32':
-    line_filter_json=re.sub(r'"', r'"""', line_filter_json)
-  else:
-    quote = "'";
+  tmpdir = None
+  if yaml and args.export_fixes:
+    tmpdir = tempfile.mkdtemp()
 
-  # Run clang-tidy on files containing changes.
-  command = [args.clang_tidy_binary]
-  command.append('-line-filter=' + quote + line_filter_json + quote)
+  # Tasks for clang-tidy.
+  task_queue = queue.Queue(max_task_count)
+  # A lock for console output.
+  lock = threading.Lock()
+
+  # Run a pool of clang-tidy workers.
+  start_workers(max_task_count, run_tidy, task_queue, lock, args.timeout)
+
+  # Form the common args list.
+  common_clang_tidy_args = []
   if args.fix:
-    command.append('-fix')
-  if args.export_fixes:
-    command.append('-export-fixes=' + args.export_fixes)
+    common_clang_tidy_args.append('-fix')
   if args.checks != '':
-    command.append('-checks=' + quote + args.checks + quote)
+    common_clang_tidy_args.append('-checks=' + args.checks)
   if args.quiet:
-    command.append('-quiet')
+    common_clang_tidy_args.append('-quiet')
   if args.build_path is not None:
-    command.append('-p=%s' % args.build_path)
-  command.extend(lines_by_file.keys())
+    common_clang_tidy_args.append('-p=%s' % args.build_path)
   for arg in args.extra_arg:
-      command.append('-extra-arg=%s' % arg)
+    common_clang_tidy_args.append('-extra-arg=%s' % arg)
   for arg in args.extra_arg_before:
-      command.append('-extra-arg-before=%s' % arg)
-  command.extend(clang_tidy_args)
+    common_clang_tidy_args.append('-extra-arg-before=%s' % arg)
 
-  sys.exit(subprocess.call(' '.join(command), shell=True))
+  for name in lines_by_file:
+    line_filter_json = json.dumps(
+      [{"name": name, "lines": lines_by_file[name]}],
+      separators=(',', ':'))
+
+    # Run clang-tidy on files containing changes.
+    command = [args.clang_tidy_binary]
+    command.append('-line-filter=' + line_filter_json)
+    if yaml and args.export_fixes:
+      # Get a temporary file. We immediately close the handle so clang-tidy can
+      # overwrite it.
+      (handle, tmp_name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir)
+      os.close(handle)
+      command.append('-export-fixes=' + tmp_name)
+    command.extend(common_clang_tidy_args)
+    command.append(name)
+    command.extend(clang_tidy_args)
+
+    task_queue.put(command)
+
+  # Wait for all threads to be done.
+  task_queue.join()
+
+  if yaml and args.export_fixes:
+    print('Writing fixes to ' + args.export_fixes + ' ...')
+    try:
+      merge_replacement_files(tmpdir, args.export_fixes)
+    except:
+      sys.stderr.write('Error exporting fixes.\n')
+      traceback.print_exc()
+
+  if tmpdir:
+    shutil.rmtree(tmpdir)
+
 
 if __name__ == '__main__':
   main()
diff --git a/clang-tidy/tool/run-clang-tidy.py b/clang-tidy/tool/run-clang-tidy.py
index 93635cb..648c17e 100755
--- a/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tidy/tool/run-clang-tidy.py
@@ -2,10 +2,9 @@
 #
 #===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 # FIXME: Integrate with clang-tidy-diff.py
@@ -48,7 +47,11 @@
 import tempfile
 import threading
 import traceback
-import yaml
+
+try:
+  import yaml
+except ImportError:
+  yaml = None
 
 is_py2 = sys.version[0] == '2'
 
@@ -169,6 +172,7 @@
     with lock:
       sys.stdout.write(' '.join(invocation) + '\n' + output.decode('utf-8') + '\n')
       if len(err) > 0:
+        sys.stdout.flush()
         sys.stderr.write(err.decode('utf-8') + '\n')
     queue.task_done()
 
@@ -200,9 +204,10 @@
                       'headers to output diagnostics from. Diagnostics from '
                       'the main file of each translation unit are always '
                       'displayed.')
-  parser.add_argument('-export-fixes', metavar='filename', dest='export_fixes',
-                      help='Create a yaml file to store suggested fixes in, '
-                      'which can be applied with clang-apply-replacements.')
+  if yaml:
+    parser.add_argument('-export-fixes', metavar='filename', dest='export_fixes',
+                        help='Create a yaml file to store suggested fixes in, '
+                        'which can be applied with clang-apply-replacements.')
   parser.add_argument('-j', type=int, default=0,
                       help='number of tidy instances to be run in parallel.')
   parser.add_argument('files', nargs='*', default=['.*'],
@@ -255,7 +260,7 @@
     max_task = multiprocessing.cpu_count()
 
   tmpdir = None
-  if args.fix or args.export_fixes:
+  if args.fix or (yaml and args.export_fixes):
     check_clang_apply_replacements_binary(args)
     tmpdir = tempfile.mkdtemp()
 
@@ -293,7 +298,7 @@
       shutil.rmtree(tmpdir)
     os.kill(0, 9)
 
-  if args.export_fixes:
+  if yaml and args.export_fixes:
     print('Writing fixes to ' + args.export_fixes + ' ...')
     try:
       merge_replacement_files(tmpdir, args.export_fixes)
diff --git a/clang-tidy/utils/ASTUtils.cpp b/clang-tidy/utils/ASTUtils.cpp
index 3c0427f..9b8eca1 100644
--- a/clang-tidy/utils/ASTUtils.cpp
+++ b/clang-tidy/utils/ASTUtils.cpp
@@ -1,9 +1,8 @@
 //===---------- ASTUtils.cpp - clang-tidy ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/ASTUtils.h b/clang-tidy/utils/ASTUtils.h
index 4196eeb..ad2a055 100644
--- a/clang-tidy/utils/ASTUtils.h
+++ b/clang-tidy/utils/ASTUtils.h
@@ -1,9 +1,8 @@
 //===---------- ASTUtils.h - clang-tidy -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/CMakeLists.txt b/clang-tidy/utils/CMakeLists.txt
index 9162bce..68ab7a1 100644
--- a/clang-tidy/utils/CMakeLists.txt
+++ b/clang-tidy/utils/CMakeLists.txt
@@ -3,6 +3,7 @@
 add_clang_library(clangTidyUtils
   ASTUtils.cpp
   DeclRefExprUtils.cpp
+  ExceptionAnalyzer.cpp
   ExprSequence.cpp
   FixItHintUtils.cpp
   HeaderFileExtensionsUtils.cpp
diff --git a/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tidy/utils/DeclRefExprUtils.cpp
index 06acd31..628b850 100644
--- a/clang-tidy/utils/DeclRefExprUtils.cpp
+++ b/clang-tidy/utils/DeclRefExprUtils.cpp
@@ -1,9 +1,8 @@
 //===--- DeclRefExprUtils.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/DeclRefExprUtils.h b/clang-tidy/utils/DeclRefExprUtils.h
index c25102f..2cf8edd 100644
--- a/clang-tidy/utils/DeclRefExprUtils.h
+++ b/clang-tidy/utils/DeclRefExprUtils.h
@@ -1,9 +1,8 @@
 //===--- DeclRefExprUtils.h - clang-tidy-------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tidy/utils/ExceptionAnalyzer.cpp
new file mode 100644
index 0000000..09fce32
--- /dev/null
+++ b/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -0,0 +1,262 @@
+//===--- ExceptionAnalyzer.cpp - clang-tidy -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExceptionAnalyzer.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+
+void ExceptionAnalyzer::ExceptionInfo::registerException(
+    const Type *ExceptionType) {
+  assert(ExceptionType != nullptr && "Only valid types are accepted");
+  Behaviour = State::Throwing;
+  ThrownExceptions.insert(ExceptionType);
+}
+
+void ExceptionAnalyzer::ExceptionInfo::registerExceptions(
+    const Throwables &Exceptions) {
+  if (Exceptions.size() == 0)
+    return;
+  Behaviour = State::Throwing;
+  ThrownExceptions.insert(Exceptions.begin(), Exceptions.end());
+}
+
+ExceptionAnalyzer::ExceptionInfo &ExceptionAnalyzer::ExceptionInfo::merge(
+    const ExceptionAnalyzer::ExceptionInfo &Other) {
+  // Only the following two cases require an update to the local
+  // 'Behaviour'. If the local entity is already throwing there will be no
+  // change and if the other entity is throwing the merged entity will throw
+  // as well.
+  // If one of both entities is 'Unknown' and the other one does not throw
+  // the merged entity is 'Unknown' as well.
+  if (Other.Behaviour == State::Throwing)
+    Behaviour = State::Throwing;
+  else if (Other.Behaviour == State::Unknown && Behaviour == State::NotThrowing)
+    Behaviour = State::Unknown;
+
+  ContainsUnknown = ContainsUnknown || Other.ContainsUnknown;
+  ThrownExceptions.insert(Other.ThrownExceptions.begin(),
+                          Other.ThrownExceptions.end());
+  return *this;
+}
+
+static bool isBaseOf(const Type *DerivedType, const Type *BaseType) {
+  const auto *DerivedClass = DerivedType->getAsCXXRecordDecl();
+  const auto *BaseClass = BaseType->getAsCXXRecordDecl();
+  if (!DerivedClass || !BaseClass)
+    return false;
+
+  return !DerivedClass->forallBases(
+      [BaseClass](const CXXRecordDecl *Cur) { return Cur != BaseClass; });
+}
+
+bool ExceptionAnalyzer::ExceptionInfo::filterByCatch(const Type *BaseClass) {
+  llvm::SmallVector<const Type *, 8> TypesToDelete;
+  for (const Type *T : ThrownExceptions) {
+    if (T == BaseClass || isBaseOf(T, BaseClass))
+      TypesToDelete.push_back(T);
+  }
+
+  for (const Type *T : TypesToDelete)
+    ThrownExceptions.erase(T);
+
+  reevaluateBehaviour();
+  return TypesToDelete.size() > 0;
+}
+
+ExceptionAnalyzer::ExceptionInfo &
+ExceptionAnalyzer::ExceptionInfo::filterIgnoredExceptions(
+    const llvm::StringSet<> &IgnoredTypes, bool IgnoreBadAlloc) {
+  llvm::SmallVector<const Type *, 8> TypesToDelete;
+  // Note: Using a 'SmallSet' with 'llvm::remove_if()' is not possible.
+  // Therefore this slightly hacky implementation is required.
+  for (const Type *T : ThrownExceptions) {
+    if (const auto *TD = T->getAsTagDecl()) {
+      if (TD->getDeclName().isIdentifier()) {
+        if ((IgnoreBadAlloc &&
+             (TD->getName() == "bad_alloc" && TD->isInStdNamespace())) ||
+            (IgnoredTypes.count(TD->getName()) > 0))
+          TypesToDelete.push_back(T);
+      }
+    }
+  }
+  for (const Type *T : TypesToDelete)
+    ThrownExceptions.erase(T);
+
+  reevaluateBehaviour();
+  return *this;
+}
+
+void ExceptionAnalyzer::ExceptionInfo::clear() {
+  Behaviour = State::NotThrowing;
+  ContainsUnknown = false;
+  ThrownExceptions.clear();
+}
+
+void ExceptionAnalyzer::ExceptionInfo::reevaluateBehaviour() {
+  if (ThrownExceptions.size() == 0)
+    if (ContainsUnknown)
+      Behaviour = State::Unknown;
+    else
+      Behaviour = State::NotThrowing;
+  else
+    Behaviour = State::Throwing;
+}
+
+ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException(
+    const FunctionDecl *Func,
+    llvm::SmallSet<const FunctionDecl *, 32> &CallStack) {
+  if (CallStack.count(Func))
+    return ExceptionInfo::createNonThrowing();
+
+  if (const Stmt *Body = Func->getBody()) {
+    CallStack.insert(Func);
+    ExceptionInfo Result =
+        throwsException(Body, ExceptionInfo::Throwables(), CallStack);
+    CallStack.erase(Func);
+    return Result;
+  }
+
+  auto Result = ExceptionInfo::createUnknown();
+  if (const auto *FPT = Func->getType()->getAs<FunctionProtoType>()) {
+    for (const QualType Ex : FPT->exceptions())
+      Result.registerException(Ex.getTypePtr());
+  }
+  return Result;
+}
+
+/// Analyzes a single statment on it's throwing behaviour. This is in principle
+/// possible except some 'Unknown' functions are called.
+ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException(
+    const Stmt *St, const ExceptionInfo::Throwables &Caught,
+    llvm::SmallSet<const FunctionDecl *, 32> &CallStack) {
+  auto Results = ExceptionInfo::createNonThrowing();
+  if (!St)
+    return Results;
+
+  if (const auto *Throw = dyn_cast<CXXThrowExpr>(St)) {
+    if (const auto *ThrownExpr = Throw->getSubExpr()) {
+      const auto *ThrownType =
+          ThrownExpr->getType()->getUnqualifiedDesugaredType();
+      if (ThrownType->isReferenceType())
+        ThrownType = ThrownType->castAs<ReferenceType>()
+                         ->getPointeeType()
+                         ->getUnqualifiedDesugaredType();
+      Results.registerException(
+          ThrownExpr->getType()->getUnqualifiedDesugaredType());
+    } else
+      // A rethrow of a caught exception happens which makes it possible
+      // to throw all exception that are caught in the 'catch' clause of
+      // the parent try-catch block.
+      Results.registerExceptions(Caught);
+  } else if (const auto *Try = dyn_cast<CXXTryStmt>(St)) {
+    ExceptionInfo Uncaught =
+        throwsException(Try->getTryBlock(), Caught, CallStack);
+    for (unsigned i = 0; i < Try->getNumHandlers(); ++i) {
+      const CXXCatchStmt *Catch = Try->getHandler(i);
+
+      // Everything is catched through 'catch(...)'.
+      if (!Catch->getExceptionDecl()) {
+        ExceptionInfo Rethrown = throwsException(
+            Catch->getHandlerBlock(), Uncaught.getExceptionTypes(), CallStack);
+        Results.merge(Rethrown);
+        Uncaught.clear();
+      } else {
+        const auto *CaughtType =
+            Catch->getCaughtType()->getUnqualifiedDesugaredType();
+        if (CaughtType->isReferenceType()) {
+          CaughtType = CaughtType->castAs<ReferenceType>()
+                           ->getPointeeType()
+                           ->getUnqualifiedDesugaredType();
+        }
+
+        // If the caught exception will catch multiple previously potential
+        // thrown types (because it's sensitive to inheritance) the throwing
+        // situation changes. First of all filter the exception types and
+        // analyze if the baseclass-exception is rethrown.
+        if (Uncaught.filterByCatch(CaughtType)) {
+          ExceptionInfo::Throwables CaughtExceptions;
+          CaughtExceptions.insert(CaughtType);
+          ExceptionInfo Rethrown = throwsException(Catch->getHandlerBlock(),
+                                                   CaughtExceptions, CallStack);
+          Results.merge(Rethrown);
+        }
+      }
+    }
+    Results.merge(Uncaught);
+  } else if (const auto *Call = dyn_cast<CallExpr>(St)) {
+    if (const FunctionDecl *Func = Call->getDirectCallee()) {
+      ExceptionInfo Excs = throwsException(Func, CallStack);
+      Results.merge(Excs);
+    }
+  } else {
+    for (const Stmt *Child : St->children()) {
+      ExceptionInfo Excs = throwsException(Child, Caught, CallStack);
+      Results.merge(Excs);
+    }
+  }
+  return Results;
+}
+
+ExceptionAnalyzer::ExceptionInfo
+ExceptionAnalyzer::analyzeImpl(const FunctionDecl *Func) {
+  ExceptionInfo ExceptionList;
+
+  // Check if the function has already been analyzed and reuse that result.
+  if (FunctionCache.count(Func) == 0) {
+    llvm::SmallSet<const FunctionDecl *, 32> CallStack;
+    ExceptionList = throwsException(Func, CallStack);
+
+    // Cache the result of the analysis. This is done prior to filtering
+    // because it is best to keep as much information as possible.
+    // The results here might be relevant to different analysis passes
+    // with different needs as well.
+    FunctionCache.insert(std::make_pair(Func, ExceptionList));
+  } else
+    ExceptionList = FunctionCache[Func];
+
+  return ExceptionList;
+}
+
+ExceptionAnalyzer::ExceptionInfo
+ExceptionAnalyzer::analyzeImpl(const Stmt *Stmt) {
+  llvm::SmallSet<const FunctionDecl *, 32> CallStack;
+  return throwsException(Stmt, ExceptionInfo::Throwables(), CallStack);
+}
+
+template <typename T>
+ExceptionAnalyzer::ExceptionInfo
+ExceptionAnalyzer::analyzeDispatch(const T *Node) {
+  ExceptionInfo ExceptionList = analyzeImpl(Node);
+
+  if (ExceptionList.getBehaviour() == State::NotThrowing ||
+      ExceptionList.getBehaviour() == State::Unknown)
+    return ExceptionList;
+
+  // Remove all ignored exceptions from the list of exceptions that can be
+  // thrown.
+  ExceptionList.filterIgnoredExceptions(IgnoredExceptions, IgnoreBadAlloc);
+
+  return ExceptionList;
+}
+
+ExceptionAnalyzer::ExceptionInfo
+ExceptionAnalyzer::analyze(const FunctionDecl *Func) {
+  return analyzeDispatch(Func);
+}
+
+ExceptionAnalyzer::ExceptionInfo
+ExceptionAnalyzer::analyze(const Stmt *Stmt) {
+  return analyzeDispatch(Stmt);
+}
+
+} // namespace utils
+} // namespace tidy
+
+} // namespace clang
diff --git a/clang-tidy/utils/ExceptionAnalyzer.h b/clang-tidy/utils/ExceptionAnalyzer.h
new file mode 100644
index 0000000..2caa1aa
--- /dev/null
+++ b/clang-tidy/utils/ExceptionAnalyzer.h
@@ -0,0 +1,156 @@
+//===--- ExceptionAnalyzer.h - clang-tidy -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+
+/// This class analysis if a `FunctionDecl` can in principle throw an
+/// exception, either directly or indirectly. It can be configured to ignore
+/// custom exception types.
+class ExceptionAnalyzer {
+public:
+  enum class State : std::int8_t {
+    Throwing = 0,    ///< The function can definitly throw given an AST.
+    NotThrowing = 1, ///< This function can not throw, given an AST.
+    Unknown = 2,     ///< This can happen for extern functions without available
+                     ///< definition.
+  };
+
+  /// Bundle the gathered information about an entity like a function regarding
+  /// it's exception behaviour. The 'NonThrowing'-state can be considered as the
+  /// neutral element in terms of information propagation.
+  /// In the case of 'Throwing' state it is possible that 'getExceptionTypes'
+  /// does not include *ALL* possible types as there is the possibility that
+  /// an 'Unknown' function is called that might throw a previously unknown
+  /// exception at runtime.
+  class ExceptionInfo {
+  public:
+    using Throwables = llvm::SmallSet<const Type *, 2>;
+    static ExceptionInfo createUnknown() {
+      return ExceptionInfo(State::Unknown);
+    }
+    static ExceptionInfo createNonThrowing() {
+      return ExceptionInfo(State::Throwing);
+    }
+
+    /// By default the exception situation is unknown and must be
+    /// clarified step-wise.
+    ExceptionInfo() : Behaviour(State::NotThrowing), ContainsUnknown(false) {}
+    ExceptionInfo(State S)
+        : Behaviour(S), ContainsUnknown(S == State::Unknown) {}
+
+    ExceptionInfo(const ExceptionInfo &) = default;
+    ExceptionInfo &operator=(const ExceptionInfo &) = default;
+    ExceptionInfo(ExceptionInfo &&) = default;
+    ExceptionInfo &operator=(ExceptionInfo &&) = default;
+
+    State getBehaviour() const { return Behaviour; }
+
+    /// Register a single exception type as recognized potential exception to be
+    /// thrown.
+    void registerException(const Type *ExceptionType);
+
+    /// Registers a `SmallVector` of exception types as recognized potential
+    /// exceptions to be thrown.
+    void registerExceptions(const Throwables &Exceptions);
+
+    /// Updates the local state according to the other state. That means if
+    /// for example a function contains multiple statements the 'ExceptionInfo'
+    /// for the final function is the merged result of each statement.
+    /// If one of these statements throws the whole function throws and if one
+    /// part is unknown and the rest is non-throwing the result will be
+    /// unknown.
+    ExceptionInfo &merge(const ExceptionInfo &Other);
+
+    /// This method is useful in case 'catch' clauses are analyzed as it is
+    /// possible to catch multiple exception types by one 'catch' if they
+    /// are a subclass of the 'catch'ed exception type.
+    /// Returns 'true' if some exceptions were filtered, otherwise 'false'.
+    bool filterByCatch(const Type *BaseClass);
+
+    /// Filter the set of thrown exception type against a set of ignored
+    /// types that shall not be considered in the exception analysis.
+    /// This includes explicit `std::bad_alloc` ignoring as separate option.
+    ExceptionInfo &
+    filterIgnoredExceptions(const llvm::StringSet<> &IgnoredTypes,
+                            bool IgnoreBadAlloc);
+
+    /// Clear the state to 'NonThrowing' to make the corresponding entity
+    /// neutral.
+    void clear();
+
+    /// References the set of known exception types that can escape from the
+    /// corresponding entity.
+    const Throwables &getExceptionTypes() const { return ThrownExceptions; }
+
+    /// Signal if the there is any 'Unknown' element within the scope of
+    /// the related entity. This might be relevant if the entity is 'Throwing'
+    /// and to ensure that no other exception then 'getExceptionTypes' can
+    /// occur. If there is an 'Unknown' element this can not be guaranteed.
+    bool containsUnknownElements() const { return ContainsUnknown; }
+
+  private:
+    /// Recalculate the 'Behaviour' for example after filtering.
+    void reevaluateBehaviour();
+
+    /// Keep track if the entity related to this 'ExceptionInfo' can in princple
+    /// throw, if it's unknown or if it won't throw.
+    State Behaviour;
+
+    /// Keep track if the entity contains any unknown elements to keep track
+    /// of the certainty of decisions and/or correct 'Behaviour' transition
+    /// after filtering.
+    bool ContainsUnknown;
+
+    /// 'ThrownException' is empty if the 'Behaviour' is either 'NotThrowing' or
+    /// 'Unknown'.
+    Throwables ThrownExceptions;
+  };
+
+  ExceptionAnalyzer() = default;
+
+  void ignoreBadAlloc(bool ShallIgnore) { IgnoreBadAlloc = ShallIgnore; }
+  void ignoreExceptions(llvm::StringSet<> ExceptionNames) {
+    IgnoredExceptions = std::move(ExceptionNames);
+  }
+
+  ExceptionInfo analyze(const FunctionDecl *Func);
+  ExceptionInfo analyze(const Stmt *Stmt);
+
+private:
+  ExceptionInfo
+  throwsException(const FunctionDecl *Func,
+                  llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
+  ExceptionInfo
+  throwsException(const Stmt *St, const ExceptionInfo::Throwables &Caught,
+                  llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
+
+  ExceptionInfo analyzeImpl(const FunctionDecl *Func);
+  ExceptionInfo analyzeImpl(const Stmt *Stmt);
+
+  template <typename T> ExceptionInfo analyzeDispatch(const T *Node);
+
+  bool IgnoreBadAlloc = true;
+  llvm::StringSet<> IgnoredExceptions;
+  std::map<const FunctionDecl *, ExceptionInfo> FunctionCache;
+};
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H
diff --git a/clang-tidy/utils/ExprSequence.cpp b/clang-tidy/utils/ExprSequence.cpp
index c3602ff..0a1558e 100644
--- a/clang-tidy/utils/ExprSequence.cpp
+++ b/clang-tidy/utils/ExprSequence.cpp
@@ -1,9 +1,8 @@
 //===---------- ExprSequence.cpp - clang-tidy -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/ExprSequence.h b/clang-tidy/utils/ExprSequence.h
index 0868a89..7bb87ad 100644
--- a/clang-tidy/utils/ExprSequence.h
+++ b/clang-tidy/utils/ExprSequence.h
@@ -1,9 +1,8 @@
 //===------------- ExprSequence.h - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/FixItHintUtils.cpp b/clang-tidy/utils/FixItHintUtils.cpp
index 9da9365..c30a59e 100644
--- a/clang-tidy/utils/FixItHintUtils.cpp
+++ b/clang-tidy/utils/FixItHintUtils.cpp
@@ -1,9 +1,8 @@
 //===--- FixItHintUtils.cpp - clang-tidy-----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/FixItHintUtils.h b/clang-tidy/utils/FixItHintUtils.h
index e64a6e4..28bbb12 100644
--- a/clang-tidy/utils/FixItHintUtils.h
+++ b/clang-tidy/utils/FixItHintUtils.h
@@ -1,9 +1,8 @@
 //===--- FixItHintUtils.h - clang-tidy---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/HeaderFileExtensionsUtils.cpp b/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
index b734b89..0215b2f 100644
--- a/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
+++ b/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
@@ -1,9 +1,8 @@
 //===--- HeaderFileExtensionsUtils.cpp - clang-tidy--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/HeaderFileExtensionsUtils.h b/clang-tidy/utils/HeaderFileExtensionsUtils.h
index 2012017..5a132e6 100644
--- a/clang-tidy/utils/HeaderFileExtensionsUtils.h
+++ b/clang-tidy/utils/HeaderFileExtensionsUtils.h
@@ -1,9 +1,8 @@
 //===--- HeaderFileExtensionsUtils.h - clang-tidy----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/HeaderGuard.cpp b/clang-tidy/utils/HeaderGuard.cpp
index 515f882..366d7d4 100644
--- a/clang-tidy/utils/HeaderGuard.cpp
+++ b/clang-tidy/utils/HeaderGuard.cpp
@@ -1,9 +1,8 @@
 //===--- HeaderGuard.cpp - clang-tidy -------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -267,10 +266,10 @@
 };
 } // namespace
 
-void HeaderGuardCheck::registerPPCallbacks(CompilerInstance &Compiler) {
-  Compiler.getPreprocessor().addPPCallbacks(
-      llvm::make_unique<HeaderGuardPPCallbacks>(&Compiler.getPreprocessor(),
-                                                this));
+void HeaderGuardCheck::registerPPCallbacks(const SourceManager &SM,
+                                           Preprocessor *PP,
+                                           Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(llvm::make_unique<HeaderGuardPPCallbacks>(PP, this));
 }
 
 bool HeaderGuardCheck::shouldSuggestEndifComment(StringRef FileName) {
diff --git a/clang-tidy/utils/HeaderGuard.h b/clang-tidy/utils/HeaderGuard.h
index a2d8288..8ece331 100644
--- a/clang-tidy/utils/HeaderGuard.h
+++ b/clang-tidy/utils/HeaderGuard.h
@@ -1,9 +1,8 @@
 //===--- HeaderGuard.h - clang-tidy -----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -33,7 +32,8 @@
     utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
                                      HeaderFileExtensions, ',');
   }
-  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
 
   /// Returns ``true`` if the check should suggest inserting a trailing comment
   /// on the ``#endif`` of the header guard. It will use the same name as
diff --git a/clang-tidy/utils/IncludeInserter.cpp b/clang-tidy/utils/IncludeInserter.cpp
index 64e4213..6b366cf 100644
--- a/clang-tidy/utils/IncludeInserter.cpp
+++ b/clang-tidy/utils/IncludeInserter.cpp
@@ -1,9 +1,8 @@
 //===-------- IncludeInserter.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/IncludeInserter.h b/clang-tidy/utils/IncludeInserter.h
index 9578649..36c16ac 100644
--- a/clang-tidy/utils/IncludeInserter.h
+++ b/clang-tidy/utils/IncludeInserter.h
@@ -1,9 +1,8 @@
 //===---------- IncludeInserter.h - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -32,11 +31,11 @@
 ///
 /// class MyCheck : public ClangTidyCheck {
 ///  public:
-///   void registerPPCallbacks(CompilerInstance& Compiler) override {
-///     Inserter = llvm::make_unique<IncludeInserter>(&Compiler.getSourceManager(),
-///                                                   &Compiler.getLangOpts());
-///     Compiler.getPreprocessor().addPPCallbacks(
-///         Inserter->CreatePPCallbacks());
+///   void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+///                            Preprocessor *ModuleExpanderPP) override {
+///     Inserter = llvm::make_unique<IncludeInserter>(
+///         SM, getLangOpts(), utils::IncludeSorter::IS_Google);
+///     PP->addPPCallbacks(Inserter->CreatePPCallbacks());
 ///   }
 ///
 ///   void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... }
diff --git a/clang-tidy/utils/IncludeSorter.cpp b/clang-tidy/utils/IncludeSorter.cpp
index 1502da7..9d79227 100644
--- a/clang-tidy/utils/IncludeSorter.cpp
+++ b/clang-tidy/utils/IncludeSorter.cpp
@@ -1,9 +1,8 @@
 //===---------- IncludeSorter.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/IncludeSorter.h b/clang-tidy/utils/IncludeSorter.h
index 07fa293..9c07274 100644
--- a/clang-tidy/utils/IncludeSorter.h
+++ b/clang-tidy/utils/IncludeSorter.h
@@ -1,9 +1,8 @@
 //===------------ IncludeSorter.h - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/LexerUtils.cpp b/clang-tidy/utils/LexerUtils.cpp
index edd4cd6..a6e361d 100644
--- a/clang-tidy/utils/LexerUtils.cpp
+++ b/clang-tidy/utils/LexerUtils.cpp
@@ -1,9 +1,8 @@
 //===--- LexerUtils.cpp - clang-tidy---------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/LexerUtils.h b/clang-tidy/utils/LexerUtils.h
index 55a8b85..06a03b6 100644
--- a/clang-tidy/utils/LexerUtils.h
+++ b/clang-tidy/utils/LexerUtils.h
@@ -1,9 +1,8 @@
 //===--- LexerUtils.h - clang-tidy-------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/Matchers.h b/clang-tidy/utils/Matchers.h
index 849b36f..dbb72c9 100644
--- a/clang-tidy/utils/Matchers.h
+++ b/clang-tidy/utils/Matchers.h
@@ -1,9 +1,8 @@
 //===--- Matchers.h - clang-tidy-------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/NamespaceAliaser.cpp b/clang-tidy/utils/NamespaceAliaser.cpp
index 2518230..fe99e68 100644
--- a/clang-tidy/utils/NamespaceAliaser.cpp
+++ b/clang-tidy/utils/NamespaceAliaser.cpp
@@ -1,9 +1,8 @@
 //===---------- NamespaceAliaser.cpp - clang-tidy -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/NamespaceAliaser.h b/clang-tidy/utils/NamespaceAliaser.h
index e56d69d..ab1b978 100644
--- a/clang-tidy/utils/NamespaceAliaser.h
+++ b/clang-tidy/utils/NamespaceAliaser.h
@@ -1,9 +1,8 @@
 //===---------- NamespaceAliaser.h - clang-tidy ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/OptionsUtils.cpp b/clang-tidy/utils/OptionsUtils.cpp
index 0b1d27d..36f4b6f 100644
--- a/clang-tidy/utils/OptionsUtils.cpp
+++ b/clang-tidy/utils/OptionsUtils.cpp
@@ -1,9 +1,8 @@
-//===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===//
+//===-- OptionsUtils.cpp - clang-tidy -------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/OptionsUtils.h b/clang-tidy/utils/OptionsUtils.h
index d822ac9..26b82e9 100644
--- a/clang-tidy/utils/OptionsUtils.h
+++ b/clang-tidy/utils/OptionsUtils.h
@@ -1,9 +1,8 @@
 //===--- DanglingHandleCheck.h - clang-tidy----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/TypeTraits.cpp b/clang-tidy/utils/TypeTraits.cpp
index 2cdc506..954a288 100644
--- a/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tidy/utils/TypeTraits.cpp
@@ -1,9 +1,8 @@
 //===--- TypeTraits.cpp - clang-tidy---------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/TypeTraits.h b/clang-tidy/utils/TypeTraits.h
index ae0b3f0..6102c28 100644
--- a/clang-tidy/utils/TypeTraits.h
+++ b/clang-tidy/utils/TypeTraits.h
@@ -1,9 +1,8 @@
 //===--- TypeTraits.h - clang-tidy-------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/UsingInserter.cpp b/clang-tidy/utils/UsingInserter.cpp
index e479d59..e852532 100644
--- a/clang-tidy/utils/UsingInserter.cpp
+++ b/clang-tidy/utils/UsingInserter.cpp
@@ -1,9 +1,8 @@
 //===---------- UsingInserter.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/UsingInserter.h b/clang-tidy/utils/UsingInserter.h
index 62108e4..9d3c60c 100644
--- a/clang-tidy/utils/UsingInserter.h
+++ b/clang-tidy/utils/UsingInserter.h
@@ -1,9 +1,8 @@
 //===---------- UsingInserter.h - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/zircon/TemporaryObjectsCheck.cpp b/clang-tidy/zircon/TemporaryObjectsCheck.cpp
index be2fb83..d3fac14 100644
--- a/clang-tidy/zircon/TemporaryObjectsCheck.cpp
+++ b/clang-tidy/zircon/TemporaryObjectsCheck.cpp
@@ -1,9 +1,8 @@
 //===--- TemporaryObjectsCheck.cpp - clang-tidy----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/zircon/TemporaryObjectsCheck.h b/clang-tidy/zircon/TemporaryObjectsCheck.h
index 302ef72..1243dad 100644
--- a/clang-tidy/zircon/TemporaryObjectsCheck.h
+++ b/clang-tidy/zircon/TemporaryObjectsCheck.h
@@ -1,16 +1,15 @@
 //===--- TemporaryObjectsCheck.h - clang-tidy------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ZIRCON_TEMPORARYOBJECTSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ZIRCON_TEMPORARYOBJECTSCHECK_H
 
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
 #include "../utils/OptionsUtils.h"
 
 namespace clang {
diff --git a/clang-tidy/zircon/ZirconTidyModule.cpp b/clang-tidy/zircon/ZirconTidyModule.cpp
index 3e53c23..94bbd27 100644
--- a/clang-tidy/zircon/ZirconTidyModule.cpp
+++ b/clang-tidy/zircon/ZirconTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- ZirconTidyModule.cpp - clang-tidy---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/AST.cpp b/clangd/AST.cpp
index a185a6d..113069a 100644
--- a/clangd/AST.cpp
+++ b/clangd/AST.cpp
@@ -1,9 +1,8 @@
 //===--- AST.cpp - Utility AST functions  -----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,15 +11,37 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TemplateBase.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
 
+namespace {
+llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>>
+getTemplateSpecializationArgLocs(const NamedDecl &ND) {
+  if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) {
+    if (const ASTTemplateArgumentListInfo *Args =
+            Func->getTemplateSpecializationArgsAsWritten())
+      return Args->arguments();
+  } else if (auto *Cls =
+                 llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
+    if (auto *Args = Cls->getTemplateArgsAsWritten())
+      return Args->arguments();
+  } else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
+    return Var->getTemplateArgsInfo().arguments();
+  // We return None for ClassTemplateSpecializationDecls because it does not
+  // contain TemplateArgumentLoc information.
+  return llvm::None;
+}
+} // namespace
+
 // Returns true if the complete name of decl \p D is spelled in the source code.
 // This is not the case for:
 //   * symbols formed via macro concatenation, the spelling location will
@@ -66,17 +87,6 @@
   return QName;
 }
 
-static const TemplateArgumentList *
-getTemplateSpecializationArgs(const NamedDecl &ND) {
-  if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND))
-    return Func->getTemplateSpecializationArgs();
-  if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND))
-    return &Cls->getTemplateInstantiationArgs();
-  if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
-    return &Var->getTemplateInstantiationArgs();
-  return nullptr;
-}
-
 std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
   std::string Name;
   llvm::raw_string_ostream Out(Name);
@@ -91,9 +101,7 @@
   }
   ND.getDeclName().print(Out, PP);
   if (!Out.str().empty()) {
-    // FIXME(ibiryukov): do not show args not explicitly written by the user.
-    if (auto *ArgList = getTemplateSpecializationArgs(ND))
-      printTemplateArgumentList(Out, ArgList->asArray(), PP);
+    Out << printTemplateSpecializationArgs(ND);
     return Out.str();
   }
   // The name was empty, so present an anonymous entity.
@@ -106,6 +114,35 @@
   return "(anonymous)";
 }
 
+std::string printTemplateSpecializationArgs(const NamedDecl &ND) {
+  std::string TemplateArgs;
+  llvm::raw_string_ostream OS(TemplateArgs);
+  PrintingPolicy Policy(ND.getASTContext().getLangOpts());
+  if (llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> Args =
+          getTemplateSpecializationArgLocs(ND)) {
+    printTemplateArgumentList(OS, *Args, Policy);
+  } else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
+    if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
+      // ClassTemplateSpecializationDecls do not contain
+      // TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we
+      // create a new argument location list from TypeSourceInfo.
+      auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
+      llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
+      ArgLocs.reserve(STL.getNumArgs());
+      for (unsigned I = 0; I < STL.getNumArgs(); ++I)
+        ArgLocs.push_back(STL.getArgLoc(I));
+      printTemplateArgumentList(OS, ArgLocs, Policy);
+    } else {
+      // FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
+      // e.g. friend decls. Currently we fallback to Template Arguments without
+      // location information.
+      printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
+    }
+  }
+  OS.flush();
+  return TemplateArgs;
+}
+
 std::string printNamespaceScope(const DeclContext &DC) {
   for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent())
     if (const auto *NS = dyn_cast<NamespaceDecl>(Ctx))
diff --git a/clangd/AST.h b/clangd/AST.h
index 85eb47c..e0e84a0 100644
--- a/clangd/AST.h
+++ b/clangd/AST.h
@@ -1,9 +1,8 @@
 //===--- AST.h - Utility AST functions  -------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,9 +13,10 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
 
-#include "index/Index.h"
+#include "index/SymbolID.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/MacroInfo.h"
 
 namespace clang {
 class SourceManager;
@@ -47,6 +47,12 @@
 /// "(anonymous struct)" or "(anonymous namespace)".
 std::string printName(const ASTContext &Ctx, const NamedDecl &ND);
 
+/// Prints template arguments of a decl as written in the source code, including
+/// enclosing '<' and '>', e.g for a partial specialization like: template
+/// <typename U> struct Foo<int, U> will return '<int, U>'. Returns an empty
+/// string if decl is not a template specialization.
+std::string printTemplateSpecializationArgs(const NamedDecl &ND);
+
 /// Gets the symbol ID for a declaration, if possible.
 llvm::Optional<SymbolID> getSymbolID(const Decl *D);
 
diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt
index 92f6200..1eb444e 100644
--- a/clangd/CMakeLists.txt
+++ b/clangd/CMakeLists.txt
@@ -1,6 +1,19 @@
 # Configure the Features.inc file.
-llvm_canonicalize_cmake_booleans(
-  CLANGD_BUILD_XPC)
+if (NOT DEFINED CLANGD_BUILD_XPC)
+  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    set(CLANGD_BUILD_XPC_DEFAULT ON)
+  else ()
+    set(CLANGD_BUILD_XPC_DEFAULT OFF)
+  endif ()
+
+  llvm_canonicalize_cmake_booleans(CLANGD_BUILD_XPC_DEFAULT)
+
+  set(CLANGD_BUILD_XPC ${CLANGD_BUILD_XPC_DEFAULT} CACHE BOOL "Build XPC Support For Clangd." FORCE)
+  unset(CLANGD_BUILD_XPC_DEFAULT)
+endif ()
+
+llvm_canonicalize_cmake_booleans(CLANGD_BUILD_XPC)
+
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/Features.inc.in
   ${CMAKE_CURRENT_BINARY_DIR}/Features.inc
@@ -40,11 +53,13 @@
   FuzzyMatch.cpp
   GlobalCompilationDatabase.cpp
   Headers.cpp
+  IncludeFixer.cpp
   JSONTransport.cpp
   Logger.cpp
   Protocol.cpp
   Quality.cpp
   RIFF.cpp
+  Selection.cpp
   SourceCode.cpp
   Threading.cpp
   Trace.cpp
@@ -60,9 +75,13 @@
   index/IndexAction.cpp
   index/MemIndex.cpp
   index/Merge.cpp
-  index/SymbolID.cpp
+  index/Ref.cpp
   index/Serialization.cpp
+  index/Symbol.cpp
   index/SymbolCollector.cpp
+  index/SymbolID.cpp
+  index/SymbolLocation.cpp
+  index/SymbolOrigin.cpp
   index/YAMLSerialization.cpp
 
   index/dex/Dex.cpp
@@ -70,6 +89,8 @@
   index/dex/PostingList.cpp
   index/dex/Trigram.cpp
 
+  refactor/Tweak.cpp
+
   LINK_LIBS
   clangAST
   clangASTMatchers
@@ -107,7 +128,9 @@
   ${CLANGD_ATOMIC_LIB}
   )
 
-if( LLVM_LIB_FUZZING_ENGINE OR LLVM_USE_SANITIZE_COVERAGE )
+add_subdirectory(refactor/tweaks)
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+  # FIXME: Make fuzzer not use linux-specific APIs, build it everywhere.
   add_subdirectory(fuzzer)
 endif()
 add_subdirectory(tool)
@@ -120,3 +143,8 @@
 if ( CLANGD_BUILD_XPC )
   add_subdirectory(xpc)
 endif ()
+
+if(CLANG_INCLUDE_TESTS)
+add_subdirectory(test)
+add_subdirectory(unittests)
+endif()
diff --git a/clangd/Cancellation.cpp b/clangd/Cancellation.cpp
index cc1c11c..6b0e21d 100644
--- a/clangd/Cancellation.cpp
+++ b/clangd/Cancellation.cpp
@@ -1,9 +1,8 @@
 //===--- Cancellation.cpp -----------------------------------------*-C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Cancellation.h b/clangd/Cancellation.h
index d6f2621..6872c44 100644
--- a/clangd/Cancellation.h
+++ b/clangd/Cancellation.h
@@ -1,9 +1,8 @@
 //===--- Cancellation.h -------------------------------------------*-C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // Cancellation mechanism for long-running tasks.
diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp
index 80792ed..44357df 100644
--- a/clangd/ClangdLSPServer.cpp
+++ b/clangd/ClangdLSPServer.cpp
@@ -1,19 +1,22 @@
 //===--- ClangdLSPServer.cpp - LSP server ------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "ClangdLSPServer.h"
 #include "Diagnostics.h"
+#include "Protocol.h"
 #include "SourceCode.h"
 #include "Trace.h"
 #include "URI.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ScopedPrinter.h"
@@ -31,6 +34,28 @@
   }
 };
 
+/// Transforms a tweak into a code action that would apply it if executed.
+/// EXPECTS: T.prepare() was called and returned true.
+CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File,
+                        Range Selection) {
+  CodeAction CA;
+  CA.title = T.Title;
+  CA.kind = CodeAction::REFACTOR_KIND;
+  // This tweak may have an expensive second stage, we only run it if the user
+  // actually chooses it in the UI. We reply with a command that would run the
+  // corresponding tweak.
+  // FIXME: for some tweaks, computing the edits is cheap and we could send them
+  //        directly.
+  CA.command.emplace();
+  CA.command->title = T.Title;
+  CA.command->command = Command::CLANGD_APPLY_TWEAK;
+  CA.command->tweakArgs.emplace();
+  CA.command->tweakArgs->file = File;
+  CA.command->tweakArgs->tweakID = T.ID;
+  CA.command->tweakArgs->selection = Selection;
+  return CA;
+}
+
 void adjustSymbolKinds(llvm::MutableArrayRef<DocumentSymbol> Syms,
                        SymbolKindBitset Kinds) {
   for (auto &S : Syms) {
@@ -69,6 +94,7 @@
   MessageHandler(ClangdLSPServer &Server) : Server(Server) {}
 
   bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override {
+    WithContext HandlerContext(handlerContext());
     log("<-- {0}", Method);
     if (Method == "exit")
       return false;
@@ -85,6 +111,7 @@
 
   bool onCall(llvm::StringRef Method, llvm::json::Value Params,
               llvm::json::Value ID) override {
+    WithContext HandlerContext(handlerContext());
     // Calls can be canceled by the client. Add cancellation context.
     WithContext WithCancel(cancelableRequestContext(ID));
     trace::Span Tracer(Method);
@@ -105,6 +132,7 @@
 
   bool onReply(llvm::json::Value ID,
                llvm::Expected<llvm::json::Value> Result) override {
+    WithContext HandlerContext(handlerContext());
     // We ignore replies, just log them.
     if (Result)
       log("<-- reply({0})", ID);
@@ -235,6 +263,13 @@
     if (It != RequestCancelers.end())
       It->second.first(); // Invoke the canceler.
   }
+
+  Context handlerContext() const {
+    return Context::current().derive(
+        kCurrentOffsetEncoding,
+        Server.NegotiatedOffsetEncoding.getValueOr(OffsetEncoding::UTF16));
+  }
+
   // We run cancelable requests in a context that does two things:
   //  - allows cancellation using RequestCancelers[ID]
   //  - cleans up the entry in RequestCancelers when it's no longer needed
@@ -278,6 +313,20 @@
 
 void ClangdLSPServer::onInitialize(const InitializeParams &Params,
                                    Callback<llvm::json::Value> Reply) {
+  // Determine character encoding first as it affects constructed ClangdServer.
+  if (Params.capabilities.offsetEncoding && !NegotiatedOffsetEncoding) {
+    NegotiatedOffsetEncoding = OffsetEncoding::UTF16; // fallback
+    for (OffsetEncoding Supported : *Params.capabilities.offsetEncoding)
+      if (Supported != OffsetEncoding::UnsupportedEncoding) {
+        NegotiatedOffsetEncoding = Supported;
+        break;
+      }
+  }
+  llvm::Optional<WithContextValue> WithOffsetEncoding;
+  if (NegotiatedOffsetEncoding)
+    WithOffsetEncoding.emplace(kCurrentOffsetEncoding,
+                               *NegotiatedOffsetEncoding);
+
   if (Params.rootUri && *Params.rootUri)
     ClangdServerOpts.WorkspaceRoot = Params.rootUri->file();
   else if (Params.rootPath && !Params.rootPath->empty())
@@ -290,7 +339,8 @@
   if (UseDirBasedCDB)
     BaseCDB = llvm::make_unique<DirectoryBasedGlobalCompilationDatabase>(
         CompileCommandsDir);
-  CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags);
+  CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags,
+              ClangdServerOpts.ResourceDir);
   Server.emplace(*CDB, FSProvider, static_cast<DiagnosticsConsumer &>(*this),
                  ClangdServerOpts);
   applyConfiguration(Params.initializationOptions.ConfigSettings);
@@ -298,6 +348,8 @@
   CCOpts.EnableSnippets = Params.capabilities.CompletionSnippets;
   DiagOpts.EmbedFixesInDiagnostics = Params.capabilities.DiagnosticFixes;
   DiagOpts.SendDiagnosticCategory = Params.capabilities.DiagnosticCategory;
+  DiagOpts.EmitRelatedLocations =
+      Params.capabilities.DiagnosticRelatedInformation;
   if (Params.capabilities.WorkspaceSymbolKinds)
     SupportedSymbolKinds |= *Params.capabilities.WorkspaceSymbolKinds;
   if (Params.capabilities.CompletionItemKinds)
@@ -306,7 +358,7 @@
   SupportsHierarchicalDocumentSymbol =
       Params.capabilities.HierarchicalDocumentSymbol;
   SupportFileStatus = Params.initializationOptions.FileStatus;
-  Reply(llvm::json::Object{
+  llvm::json::Object Result{
       {{"capabilities",
         llvm::json::Object{
             {"textDocumentSync", (int)TextDocumentSyncKind::Incremental},
@@ -329,6 +381,7 @@
              llvm::json::Object{
                  {"triggerCharacters", {"(", ","}},
              }},
+            {"declarationProvider", true},
             {"definitionProvider", true},
             {"documentHighlightProvider", true},
             {"hoverProvider", true},
@@ -338,9 +391,15 @@
             {"referencesProvider", true},
             {"executeCommandProvider",
              llvm::json::Object{
-                 {"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}},
+                 {"commands",
+                  {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND,
+                   ExecuteCommandParams::CLANGD_APPLY_TWEAK}},
              }},
-        }}}});
+            {"typeHierarchyProvider", true},
+        }}}};
+  if (NegotiatedOffsetEncoding)
+    Result["offsetEncoding"] = *NegotiatedOffsetEncoding;
+  Reply(std::move(Result));
 }
 
 void ClangdLSPServer::onShutdown(const ShutdownParams &Params,
@@ -400,7 +459,7 @@
 
 void ClangdLSPServer::onCommand(const ExecuteCommandParams &Params,
                                 Callback<llvm::json::Value> Reply) {
-  auto ApplyEdit = [&](WorkspaceEdit WE) {
+  auto ApplyEdit = [this](WorkspaceEdit WE) {
     ApplyWorkspaceEditParams Edit;
     Edit.edit = std::move(WE);
     // Ideally, we would wait for the response and if there is no error, we
@@ -420,6 +479,31 @@
 
     Reply("Fix applied.");
     ApplyEdit(*Params.workspaceEdit);
+  } else if (Params.command == ExecuteCommandParams::CLANGD_APPLY_TWEAK &&
+             Params.tweakArgs) {
+    auto Code = DraftMgr.getDraft(Params.tweakArgs->file.file());
+    if (!Code)
+      return Reply(llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "trying to apply a code action for a non-added file"));
+
+    auto Action = [ApplyEdit](decltype(Reply) Reply, URIForFile File,
+                              std::string Code,
+                              llvm::Expected<tooling::Replacements> R) {
+      if (!R)
+        return Reply(R.takeError());
+
+      WorkspaceEdit WE;
+      WE.changes.emplace();
+      (*WE.changes)[File.uri()] = replacementsToEdits(Code, *R);
+
+      Reply("Fix applied.");
+      ApplyEdit(std::move(WE));
+    };
+    Server->applyTweak(Params.tweakArgs->file.file(),
+                       Params.tweakArgs->selection, Params.tweakArgs->tweakID,
+                       Bind(Action, std::move(Reply), Params.tweakArgs->file,
+                            std::move(*Code)));
   } else {
     // We should not get here because ExecuteCommandParams would not have
     // parsed in the first place and this handler should not be called. But if
@@ -459,19 +543,13 @@
   Server->rename(
       File, Params.position, Params.newName,
       Bind(
-          [File, Code, Params](
-              decltype(Reply) Reply,
-              llvm::Expected<std::vector<tooling::Replacement>> Replacements) {
-            if (!Replacements)
-              return Reply(Replacements.takeError());
+          [File, Code, Params](decltype(Reply) Reply,
+                               llvm::Expected<std::vector<TextEdit>> Edits) {
+            if (!Edits)
+              return Reply(Edits.takeError());
 
-            // Turn the replacements into the format specified by the Language
-            // Server Protocol. Fuse them into one big JSON array.
-            std::vector<TextEdit> Edits;
-            for (const auto &R : *Replacements)
-              Edits.push_back(replacementToEdit(*Code, R));
             WorkspaceEdit WE;
-            WE.changes = {{Params.textDocument.uri.uri(), Edits}};
+            WE.changes = {{Params.textDocument.uri.uri(), *Edits}};
             Reply(WE);
           },
           std::move(Reply)));
@@ -482,6 +560,17 @@
   PathRef File = Params.textDocument.uri.file();
   DraftMgr.removeDraft(File);
   Server->removeDocument(File);
+
+  {
+    std::lock_guard<std::mutex> Lock(FixItsMutex);
+    FixItsMap.erase(File);
+  }
+  // clangd will not send updates for this file anymore, so we empty out the
+  // list of diagnostics shown on the client (e.g. in the "Problems" pane of
+  // VSCode). Note that this cannot race with actual diagnostics responses
+  // because removeDocument() guarantees no diagnostic callbacks will be
+  // executed after it returns.
+  publishDiagnostics(URIForFile::canonicalize(File, /*TUPath=*/File), {});
 }
 
 void ClangdLSPServer::onDocumentOnTypeFormatting(
@@ -601,28 +690,47 @@
 
 void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
                                    Callback<llvm::json::Value> Reply) {
-  auto Code = DraftMgr.getDraft(Params.textDocument.uri.file());
+  URIForFile File = Params.textDocument.uri;
+  auto Code = DraftMgr.getDraft(File.file());
   if (!Code)
     return Reply(llvm::make_error<LSPError>(
         "onCodeAction called for non-added file", ErrorCode::InvalidParams));
   // We provide a code action for Fixes on the specified diagnostics.
-  std::vector<CodeAction> Actions;
+  std::vector<CodeAction> FixIts;
   for (const Diagnostic &D : Params.context.diagnostics) {
-    for (auto &F : getFixes(Params.textDocument.uri.file(), D)) {
-      Actions.push_back(toCodeAction(F, Params.textDocument.uri));
-      Actions.back().diagnostics = {D};
+    for (auto &F : getFixes(File.file(), D)) {
+      FixIts.push_back(toCodeAction(F, Params.textDocument.uri));
+      FixIts.back().diagnostics = {D};
     }
   }
 
-  if (SupportsCodeAction)
-    Reply(llvm::json::Array(Actions));
-  else {
-    std::vector<Command> Commands;
-    for (const auto &Action : Actions)
-      if (auto Command = asCommand(Action))
-        Commands.push_back(std::move(*Command));
-    Reply(llvm::json::Array(Commands));
-  }
+  // Now enumerate the semantic code actions.
+  auto ConsumeActions =
+      [this](decltype(Reply) Reply, URIForFile File, std::string Code,
+             Range Selection, std::vector<CodeAction> FixIts,
+             llvm::Expected<std::vector<ClangdServer::TweakRef>> Tweaks) {
+        if (!Tweaks)
+          return Reply(Tweaks.takeError());
+
+        std::vector<CodeAction> Actions = std::move(FixIts);
+        Actions.reserve(Actions.size() + Tweaks->size());
+        for (const auto &T : *Tweaks)
+          Actions.push_back(toCodeAction(T, File, Selection));
+
+        if (SupportsCodeAction)
+          return Reply(llvm::json::Array(Actions));
+        std::vector<Command> Commands;
+        for (const auto &Action : Actions) {
+          if (auto Command = asCommand(Action))
+            Commands.push_back(std::move(*Command));
+        }
+        return Reply(llvm::json::Array(Commands));
+      };
+
+  Server->enumerateTweaks(File.file(), Params.range,
+                          Bind(ConsumeActions, std::move(Reply), File,
+                               std::move(*Code), Params.range,
+                               std::move(FixIts)));
 }
 
 void ClangdLSPServer::onCompletion(const CompletionParams &Params,
@@ -654,10 +762,65 @@
                         std::move(Reply));
 }
 
+// Go to definition has a toggle function: if def and decl are distinct, then
+// the first press gives you the def, the second gives you the matching def.
+// getToggle() returns the counterpart location that under the cursor.
+//
+// We return the toggled location alone (ignoring other symbols) to encourage
+// editors to "bounce" quickly between locations, without showing a menu.
+static Location *getToggle(const TextDocumentPositionParams &Point,
+                           LocatedSymbol &Sym) {
+  // Toggle only makes sense with two distinct locations.
+  if (!Sym.Definition || *Sym.Definition == Sym.PreferredDeclaration)
+    return nullptr;
+  if (Sym.Definition->uri.file() == Point.textDocument.uri.file() &&
+      Sym.Definition->range.contains(Point.position))
+    return &Sym.PreferredDeclaration;
+  if (Sym.PreferredDeclaration.uri.file() == Point.textDocument.uri.file() &&
+      Sym.PreferredDeclaration.range.contains(Point.position))
+    return &*Sym.Definition;
+  return nullptr;
+}
+
 void ClangdLSPServer::onGoToDefinition(const TextDocumentPositionParams &Params,
                                        Callback<std::vector<Location>> Reply) {
-  Server->findDefinitions(Params.textDocument.uri.file(), Params.position,
-                          std::move(Reply));
+  Server->locateSymbolAt(
+      Params.textDocument.uri.file(), Params.position,
+      Bind(
+          [&, Params](decltype(Reply) Reply,
+                      llvm::Expected<std::vector<LocatedSymbol>> Symbols) {
+            if (!Symbols)
+              return Reply(Symbols.takeError());
+            std::vector<Location> Defs;
+            for (auto &S : *Symbols) {
+              if (Location *Toggle = getToggle(Params, S))
+                return Reply(std::vector<Location>{std::move(*Toggle)});
+              Defs.push_back(S.Definition.getValueOr(S.PreferredDeclaration));
+            }
+            Reply(std::move(Defs));
+          },
+          std::move(Reply)));
+}
+
+void ClangdLSPServer::onGoToDeclaration(
+    const TextDocumentPositionParams &Params,
+    Callback<std::vector<Location>> Reply) {
+  Server->locateSymbolAt(
+      Params.textDocument.uri.file(), Params.position,
+      Bind(
+          [&, Params](decltype(Reply) Reply,
+                      llvm::Expected<std::vector<LocatedSymbol>> Symbols) {
+            if (!Symbols)
+              return Reply(Symbols.takeError());
+            std::vector<Location> Decls;
+            for (auto &S : *Symbols) {
+              if (Location *Toggle = getToggle(Params, S))
+                return Reply(std::vector<Location>{std::move(*Toggle)});
+              Decls.push_back(std::move(S.PreferredDeclaration));
+            }
+            Reply(std::move(Decls));
+          },
+          std::move(Reply)));
 }
 
 void ClangdLSPServer::onSwitchSourceHeader(const TextDocumentIdentifier &Params,
@@ -679,6 +842,13 @@
                     std::move(Reply));
 }
 
+void ClangdLSPServer::onTypeHierarchy(
+    const TypeHierarchyParams &Params,
+    Callback<Optional<TypeHierarchyItem>> Reply) {
+  Server->typeHierarchy(Params.textDocument.uri.file(), Params.position,
+                        Params.resolve, Params.direction, std::move(Reply));
+}
+
 void ClangdLSPServer::applyConfiguration(
     const ConfigurationSettings &Settings) {
   // Per-file update to the compilation database.
@@ -701,6 +871,16 @@
     reparseOpenedFiles();
 }
 
+void ClangdLSPServer::publishDiagnostics(
+    const URIForFile &File, std::vector<clangd::Diagnostic> Diagnostics) {
+  // Publish diagnostics.
+  notify("textDocument/publishDiagnostics",
+         llvm::json::Object{
+             {"uri", File},
+             {"diagnostics", std::move(Diagnostics)},
+         });
+}
+
 // FIXME: This function needs to be properly tested.
 void ClangdLSPServer::onChangeConfiguration(
     const DidChangeConfigurationParams &Params) {
@@ -719,17 +899,19 @@
                      std::move(Reply));
 }
 
-ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
-                                 const clangd::CodeCompleteOptions &CCOpts,
-                                 llvm::Optional<Path> CompileCommandsDir,
-                                 bool UseDirBasedCDB,
-                                 const ClangdServer::Options &Opts)
-    : Transp(Transp), MsgHandler(new MessageHandler(*this)), CCOpts(CCOpts),
+ClangdLSPServer::ClangdLSPServer(
+    class Transport &Transp, const FileSystemProvider &FSProvider,
+    const clangd::CodeCompleteOptions &CCOpts,
+    llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
+    llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
+    const ClangdServer::Options &Opts)
+    : Transp(Transp), MsgHandler(new MessageHandler(*this)),
+      FSProvider(FSProvider), CCOpts(CCOpts),
       SupportedSymbolKinds(defaultSymbolKinds()),
       SupportedCompletionItemKinds(defaultCompletionItemKinds()),
       UseDirBasedCDB(UseDirBasedCDB),
-      CompileCommandsDir(std::move(CompileCommandsDir)),
-      ClangdServerOpts(Opts) {
+      CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts),
+      NegotiatedOffsetEncoding(ForcedOffsetEncoding) {
   // clang-format off
   MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize);
   MsgHandler->bind("shutdown", &ClangdLSPServer::onShutdown);
@@ -741,6 +923,7 @@
   MsgHandler->bind("textDocument/completion", &ClangdLSPServer::onCompletion);
   MsgHandler->bind("textDocument/signatureHelp", &ClangdLSPServer::onSignatureHelp);
   MsgHandler->bind("textDocument/definition", &ClangdLSPServer::onGoToDefinition);
+  MsgHandler->bind("textDocument/declaration", &ClangdLSPServer::onGoToDeclaration);
   MsgHandler->bind("textDocument/references", &ClangdLSPServer::onReference);
   MsgHandler->bind("textDocument/switchSourceHeader", &ClangdLSPServer::onSwitchSourceHeader);
   MsgHandler->bind("textDocument/rename", &ClangdLSPServer::onRename);
@@ -755,6 +938,7 @@
   MsgHandler->bind("workspace/didChangeWatchedFiles", &ClangdLSPServer::onFileEvent);
   MsgHandler->bind("workspace/didChangeConfiguration", &ClangdLSPServer::onChangeConfiguration);
   MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
+  MsgHandler->bind("textDocument/typeHierarchy", &ClangdLSPServer::onTypeHierarchy);
   // clang-format on
 }
 
@@ -839,17 +1023,12 @@
 
   // Cache FixIts
   {
-    // FIXME(ibiryukov): should be deleted when documents are removed
     std::lock_guard<std::mutex> Lock(FixItsMutex);
     FixItsMap[File] = LocalFixIts;
   }
 
-  // Publish diagnostics.
-  notify("textDocument/publishDiagnostics",
-         llvm::json::Object{
-             {"uri", URI},
-             {"diagnostics", std::move(LSPDiagnostics)},
-         });
+  // Send a notification to the LSP client.
+  publishDiagnostics(URI, std::move(LSPDiagnostics));
 }
 
 void ClangdLSPServer::onFileUpdated(PathRef File, const TUStatus &Status) {
diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h
index 80052b4..171ba07 100644
--- a/clangd/ClangdLSPServer.h
+++ b/clangd/ClangdLSPServer.h
@@ -1,9 +1,8 @@
 //===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 
 #include "ClangdServer.h"
 #include "DraftStore.h"
+#include "Features.inc"
 #include "FindSymbols.h"
 #include "GlobalCompilationDatabase.h"
 #include "Path.h"
@@ -38,8 +38,10 @@
   /// for compile_commands.json in all parent directories of each file.
   /// If UseDirBasedCDB is false, compile commands are not read from disk.
   // FIXME: Clean up signature around CDBs.
-  ClangdLSPServer(Transport &Transp, const clangd::CodeCompleteOptions &CCOpts,
+  ClangdLSPServer(Transport &Transp, const FileSystemProvider &FSProvider,
+                  const clangd::CodeCompleteOptions &CCOpts,
                   llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
+                  llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
                   const ClangdServer::Options &Opts);
   ~ClangdLSPServer();
 
@@ -77,6 +79,8 @@
   void onCompletion(const CompletionParams &, Callback<CompletionList>);
   void onSignatureHelp(const TextDocumentPositionParams &,
                        Callback<SignatureHelp>);
+  void onGoToDeclaration(const TextDocumentPositionParams &,
+                         Callback<std::vector<Location>>);
   void onGoToDefinition(const TextDocumentPositionParams &,
                         Callback<std::vector<Location>>);
   void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
@@ -91,6 +95,8 @@
   void onRename(const RenameParams &, Callback<WorkspaceEdit>);
   void onHover(const TextDocumentPositionParams &,
                Callback<llvm::Optional<Hover>>);
+  void onTypeHierarchy(const TypeHierarchyParams &,
+                       Callback<llvm::Optional<TypeHierarchyItem>>);
   void onChangeConfiguration(const DidChangeConfigurationParams &);
   void onSymbolInfo(const TextDocumentPositionParams &,
                     Callback<std::vector<SymbolDetails>>);
@@ -109,6 +115,10 @@
   void reparseOpenedFiles();
   void applyConfiguration(const ConfigurationSettings &Settings);
 
+  /// Sends a "publishDiagnostics" notification to the LSP client.
+  void publishDiagnostics(const URIForFile &File,
+                          std::vector<clangd::Diagnostic> Diagnostics);
+
   /// Used to indicate that the 'shutdown' request was received from the
   /// Language Server client.
   bool ShutdownRequestReceived = false;
@@ -129,7 +139,7 @@
   void call(StringRef Method, llvm::json::Value Params);
   void notify(StringRef Method, llvm::json::Value Params);
 
-  RealFileSystemProvider FSProvider;
+  const FileSystemProvider &FSProvider;
   /// Options used for code completion
   clangd::CodeCompleteOptions CCOpts;
   /// Options used for diagnostics.
@@ -157,6 +167,7 @@
   // It is destroyed before run() returns, to ensure worker threads exit.
   ClangdServer::Options ClangdServerOpts;
   llvm::Optional<ClangdServer> Server;
+  llvm::Optional<OffsetEncoding> NegotiatedOffsetEncoding;
 };
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp
index 53a27bd..374ffc0 100644
--- a/clangd/ClangdServer.cpp
+++ b/clangd/ClangdServer.cpp
@@ -1,26 +1,30 @@
 //===--- ClangdServer.cpp - Main clangd server code --------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===-------------------------------------------------------------------===//
 
 #include "ClangdServer.h"
+#include "ClangdUnit.h"
 #include "CodeComplete.h"
 #include "FindSymbols.h"
 #include "Headers.h"
+#include "Protocol.h"
 #include "SourceCode.h"
+#include "TUScheduler.h"
 #include "Trace.h"
-#include "XRefs.h"
+#include "index/CanonicalIncludes.h"
 #include "index/FileIndex.h"
 #include "index/Merge.h"
+#include "refactor/Tweak.h"
 #include "clang/Format/Format.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Refactoring/RefactoringResultConsumer.h"
 #include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -28,19 +32,29 @@
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <future>
+#include <memory>
 #include <mutex>
 
 namespace clang {
 namespace clangd {
 namespace {
 
-std::string getStandardResourceDir() {
-  static int Dummy; // Just an address in this process.
-  return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy);
+// Expand a DiagnosticError to make it print-friendly (print the detailed
+// message, rather than "clang diagnostic").
+llvm::Error expandDiagnostics(llvm::Error Err, DiagnosticsEngine &DE) {
+  if (auto Diag = DiagnosticError::take(Err)) {
+    llvm::cantFail(std::move(Err));
+    SmallVector<char, 128> DiagMessage;
+    Diag->second.EmitToString(DE, DiagMessage);
+    return llvm::make_error<llvm::StringError>(DiagMessage,
+                                               llvm::inconvertibleErrorCode());
+  }
+  return Err;
 }
 
 class RefactoringResultCollector final
@@ -48,9 +62,6 @@
 public:
   void handleError(llvm::Error Err) override {
     assert(!Result.hasValue());
-    // FIXME: figure out a way to return better message for DiagnosticError.
-    // clangd uses llvm::toString to convert the Err to string, however, for
-    // DiagnosticError, only "clang diagnostic" will be generated.
     Result = std::move(Err);
   }
 
@@ -71,9 +82,10 @@
       : FIndex(FIndex), DiagConsumer(DiagConsumer) {}
 
   void onPreambleAST(PathRef Path, ASTContext &Ctx,
-                     std::shared_ptr<clang::Preprocessor> PP) override {
+                     std::shared_ptr<clang::Preprocessor> PP,
+                     const CanonicalIncludes &CanonIncludes) override {
     if (FIndex)
-      FIndex->updatePreamble(Path, Ctx, std::move(PP));
+      FIndex->updatePreamble(Path, Ctx, std::move(PP), CanonIncludes);
   }
 
   void onMainAST(PathRef Path, ParsedAST &AST) override {
@@ -107,20 +119,19 @@
                            const FileSystemProvider &FSProvider,
                            DiagnosticsConsumer &DiagConsumer,
                            const Options &Opts)
-    : CDB(CDB), FSProvider(FSProvider),
-      ResourceDir(Opts.ResourceDir ? *Opts.ResourceDir
-                                   : getStandardResourceDir()),
+    : FSProvider(FSProvider),
       DynamicIdx(Opts.BuildDynamicSymbolIndex
                      ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex)
                      : nullptr),
+      ClangTidyOptProvider(Opts.ClangTidyOptProvider),
+      SuggestMissingIncludes(Opts.SuggestMissingIncludes),
       WorkspaceRoot(Opts.WorkspaceRoot),
-      PCHs(std::make_shared<PCHContainerOperations>()),
       // Pass a callback into `WorkScheduler` to extract symbols from a newly
       // parsed file and rebuild the file index synchronously each time an AST
       // is parsed.
       // FIXME(ioeric): this can be slow and we may be able to index on less
       // critical paths.
-      WorkScheduler(Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
+      WorkScheduler(CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
                     llvm::make_unique<UpdateIndexCallbacks>(DynamicIdx.get(),
                                                             DiagConsumer),
                     Opts.UpdateDebounce, Opts.RetentionPolicy) {
@@ -137,7 +148,7 @@
     AddIndex(Opts.StaticIndex);
   if (Opts.BackgroundIndex) {
     BackgroundIdx = llvm::make_unique<BackgroundIndex>(
-        Context::current().clone(), ResourceDir, FSProvider, CDB,
+        Context::current().clone(), FSProvider, CDB,
         BackgroundIndexStorage::createDiskBackedStorageFactory(),
         Opts.BackgroundIndexRebuildPeriodMs);
     AddIndex(BackgroundIdx.get());
@@ -148,14 +159,19 @@
 
 void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
                                WantDiagnostics WantDiags) {
-  // FIXME: some build systems like Bazel will take time to preparing
-  // environment to build the file, it would be nice if we could emit a
-  // "PreparingBuild" status to inform users, it is non-trivial given the
-  // current implementation.
-  WorkScheduler.update(File,
-                       ParseInputs{getCompileCommand(File),
-                                   FSProvider.getFileSystem(), Contents.str()},
-                       WantDiags);
+  ParseOptions Opts;
+  Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults();
+  if (ClangTidyOptProvider)
+    Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File);
+  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
+
+  // Compile command is set asynchronously during update, as it can be slow.
+  ParseInputs Inputs;
+  Inputs.FS = FSProvider.getFileSystem();
+  Inputs.Contents = Contents;
+  Inputs.Opts = std::move(Opts);
+  Inputs.Index = Index;
+  WorkScheduler.update(File, Inputs, WantDiags);
 }
 
 void ClangdServer::removeDocument(PathRef File) { WorkScheduler.remove(File); }
@@ -168,11 +184,8 @@
   if (!CodeCompleteOpts.Index) // Respect overridden index.
     CodeCompleteOpts.Index = Index;
 
-  // Copy PCHs to avoid accessing this->PCHs concurrently
-  std::shared_ptr<PCHContainerOperations> PCHs = this->PCHs;
   auto FS = FSProvider.getFileSystem();
-
-  auto Task = [PCHs, Pos, FS, CodeCompleteOpts,
+  auto Task = [Pos, FS, CodeCompleteOpts,
                this](Path File, Callback<CodeCompleteResult> CB,
                      llvm::Expected<InputsAndPreamble> IP) {
     if (!IP)
@@ -181,18 +194,25 @@
       return CB(llvm::make_error<CancelledError>());
 
     llvm::Optional<SpeculativeFuzzyFind> SpecFuzzyFind;
-    if (CodeCompleteOpts.Index && CodeCompleteOpts.SpeculativeIndexRequest) {
-      SpecFuzzyFind.emplace();
-      {
-        std::lock_guard<std::mutex> Lock(CachedCompletionFuzzyFindRequestMutex);
-        SpecFuzzyFind->CachedReq = CachedCompletionFuzzyFindRequestByFile[File];
+    if (!IP->Preamble) {
+      // No speculation in Fallback mode, as it's supposed to be much faster
+      // without compiling.
+      vlog("Build for file {0} is not ready. Enter fallback mode.", File);
+    } else {
+      if (CodeCompleteOpts.Index && CodeCompleteOpts.SpeculativeIndexRequest) {
+        SpecFuzzyFind.emplace();
+        {
+          std::lock_guard<std::mutex> Lock(
+              CachedCompletionFuzzyFindRequestMutex);
+          SpecFuzzyFind->CachedReq =
+              CachedCompletionFuzzyFindRequestByFile[File];
+        }
       }
     }
-
     // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
     // both the old and the new version in case only one of them matches.
     CodeCompleteResult Result = clangd::codeComplete(
-        File, IP->Command, IP->Preamble, IP->Contents, Pos, FS, PCHs,
+        File, IP->Command, IP->Preamble, IP->Contents, Pos, FS,
         CodeCompleteOpts, SpecFuzzyFind ? SpecFuzzyFind.getPointer() : nullptr);
     {
       clang::clangd::trace::Span Tracer("Completion results callback");
@@ -210,24 +230,25 @@
   };
 
   // We use a potentially-stale preamble because latency is critical here.
-  WorkScheduler.runWithPreamble("CodeComplete", File, TUScheduler::Stale,
+  WorkScheduler.runWithPreamble("CodeComplete", File,
+                                Opts.AllowFallback ? TUScheduler::StaleOrAbsent
+                                                   : TUScheduler::Stale,
                                 Bind(Task, File.str(), std::move(CB)));
 }
 
 void ClangdServer::signatureHelp(PathRef File, Position Pos,
                                  Callback<SignatureHelp> CB) {
 
-  auto PCHs = this->PCHs;
   auto FS = FSProvider.getFileSystem();
   auto *Index = this->Index;
-  auto Action = [Pos, FS, PCHs, Index](Path File, Callback<SignatureHelp> CB,
-                                       llvm::Expected<InputsAndPreamble> IP) {
+  auto Action = [Pos, FS, Index](Path File, Callback<SignatureHelp> CB,
+                                 llvm::Expected<InputsAndPreamble> IP) {
     if (!IP)
       return CB(IP.takeError());
 
     auto PreambleData = IP->Preamble;
     CB(clangd::signatureHelp(File, IP->Command, PreambleData, IP->Contents, Pos,
-                             FS, PCHs, Index));
+                             FS, Index));
   };
 
   // Unlike code completion, we wait for an up-to-date preamble here.
@@ -272,9 +293,9 @@
 }
 
 void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
-                          Callback<std::vector<tooling::Replacement>> CB) {
+                          Callback<std::vector<TextEdit>> CB) {
   auto Action = [Pos](Path File, std::string NewName,
-                      Callback<std::vector<tooling::Replacement>> CB,
+                      Callback<std::vector<TextEdit>> CB,
                       llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
@@ -290,15 +311,17 @@
     auto Rename = clang::tooling::RenameOccurrences::initiate(
         Context, SourceRange(SourceLocationBeg), NewName);
     if (!Rename)
-      return CB(Rename.takeError());
+      return CB(expandDiagnostics(Rename.takeError(),
+                                  AST.getASTContext().getDiagnostics()));
 
     Rename->invoke(ResultCollector, Context);
 
     assert(ResultCollector.Result.hasValue());
     if (!ResultCollector.Result.getValue())
-      return CB(ResultCollector.Result->takeError());
+      return CB(expandDiagnostics(ResultCollector.Result->takeError(),
+                                  AST.getASTContext().getDiagnostics()));
 
-    std::vector<tooling::Replacement> Replacements;
+    std::vector<TextEdit> Replacements;
     for (const tooling::AtomicChange &Change : ResultCollector.Result->get()) {
       tooling::Replacements ChangeReps = Change.getReplacements();
       for (const auto &Rep : ChangeReps) {
@@ -312,7 +335,8 @@
         //   * rename globally in project
         //   * rename in open files
         if (Rep.getFilePath() == File)
-          Replacements.push_back(Rep);
+          Replacements.push_back(
+              replacementToEdit(InpAST->Inputs.Contents, Rep));
       }
     }
     return CB(std::move(Replacements));
@@ -322,6 +346,63 @@
       "Rename", File, Bind(Action, File.str(), NewName.str(), std::move(CB)));
 }
 
+static llvm::Expected<Tweak::Selection>
+tweakSelection(const Range &Sel, const InputsAndAST &AST) {
+  auto Begin = positionToOffset(AST.Inputs.Contents, Sel.start);
+  if (!Begin)
+    return Begin.takeError();
+  auto End = positionToOffset(AST.Inputs.Contents, Sel.end);
+  if (!End)
+    return End.takeError();
+  return Tweak::Selection(AST.AST, *Begin, *End);
+}
+
+void ClangdServer::enumerateTweaks(PathRef File, Range Sel,
+                                   Callback<std::vector<TweakRef>> CB) {
+  auto Action = [Sel](decltype(CB) CB, std::string File,
+                      Expected<InputsAndAST> InpAST) {
+    if (!InpAST)
+      return CB(InpAST.takeError());
+    auto Selection = tweakSelection(Sel, *InpAST);
+    if (!Selection)
+      return CB(Selection.takeError());
+    std::vector<TweakRef> Res;
+    for (auto &T : prepareTweaks(*Selection))
+      Res.push_back({T->id(), T->title()});
+    CB(std::move(Res));
+  };
+
+  WorkScheduler.runWithAST("EnumerateTweaks", File,
+                           Bind(Action, std::move(CB), File.str()));
+}
+
+void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
+                              Callback<tooling::Replacements> CB) {
+  auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID,
+                      Expected<InputsAndAST> InpAST) {
+    if (!InpAST)
+      return CB(InpAST.takeError());
+    auto Selection = tweakSelection(Sel, *InpAST);
+    if (!Selection)
+      return CB(Selection.takeError());
+    auto A = prepareTweak(TweakID, *Selection);
+    if (!A)
+      return CB(A.takeError());
+    auto RawReplacements = (*A)->apply(*Selection);
+    if (!RawReplacements)
+      return CB(RawReplacements.takeError());
+    // FIXME: this function has I/O operations (find .clang-format file), figure
+    // out a way to cache the format style.
+    auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
+                                       InpAST->Inputs.FS.get());
+    return CB(
+        cleanupAndFormat(InpAST->Inputs.Contents, *RawReplacements, Style));
+  };
+  WorkScheduler.runWithAST(
+      "ApplyTweak", File,
+      Bind(Action, std::move(CB), File.str(), TweakID.str()));
+}
+
 void ClangdServer::dumpAST(PathRef File,
                            llvm::unique_function<void(std::string)> Callback) {
   auto Action = [](decltype(Callback) Callback,
@@ -342,13 +423,13 @@
   WorkScheduler.runWithAST("DumpAST", File, Bind(Action, std::move(Callback)));
 }
 
-void ClangdServer::findDefinitions(PathRef File, Position Pos,
-                                   Callback<std::vector<Location>> CB) {
-  auto Action = [Pos, this](Callback<std::vector<Location>> CB,
+void ClangdServer::locateSymbolAt(PathRef File, Position Pos,
+                                  Callback<std::vector<LocatedSymbol>> CB) {
+  auto Action = [Pos, this](decltype(CB) CB,
                             llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
-    CB(clangd::findDefinitions(InpAST->AST, Pos, Index));
+    CB(clangd::locateSymbolAt(InpAST->AST, Pos, Index));
   };
 
   WorkScheduler.runWithAST("Definitions", File, Bind(Action, std::move(CB)));
@@ -415,20 +496,16 @@
 ClangdServer::formatCode(llvm::StringRef Code, PathRef File,
                          llvm::ArrayRef<tooling::Range> Ranges) {
   // Call clang-format.
-  auto FS = FSProvider.getFileSystem();
-  auto Style = format::getStyle(format::DefaultFormatStyle, File,
-                                format::DefaultFallbackStyle, Code, FS.get());
-  if (!Style)
-    return Style.takeError();
-
+  format::FormatStyle Style =
+      getFormatStyleForFile(File, Code, FSProvider.getFileSystem().get());
   tooling::Replacements IncludeReplaces =
-      format::sortIncludes(*Style, Code, Ranges, File);
+      format::sortIncludes(Style, Code, Ranges, File);
   auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
   if (!Changed)
     return Changed.takeError();
 
   return IncludeReplaces.merge(format::reformat(
-      Style.get(), *Changed,
+      Style, *Changed,
       tooling::calculateRangesAfterReplacements(IncludeReplaces, Ranges),
       File));
 }
@@ -457,16 +534,17 @@
   WorkScheduler.runWithAST("Hover", File, Bind(Action, std::move(CB)));
 }
 
-tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) {
-  trace::Span Span("GetCompileCommand");
-  llvm::Optional<tooling::CompileCommand> C = CDB.getCompileCommand(File);
-  if (!C) // FIXME: Suppress diagnostics? Let the user know?
-    C = CDB.getFallbackCommand(File);
+void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
+                                 TypeHierarchyDirection Direction,
+                                 Callback<Optional<TypeHierarchyItem>> CB) {
+  auto Action = [Pos, Resolve, Direction](decltype(CB) CB,
+                                          Expected<InputsAndAST> InpAST) {
+    if (!InpAST)
+      return CB(InpAST.takeError());
+    CB(clangd::getTypeHierarchy(InpAST->AST, Pos, Resolve, Direction));
+  };
 
-  // Inject the resource dir.
-  // FIXME: Don't overwrite it if it's already there.
-  C->CommandLine.push_back("-resource-dir=" + ResourceDir);
-  return std::move(*C);
+  WorkScheduler.runWithAST("Type Hierarchy", File, Bind(Action, std::move(CB)));
 }
 
 void ClangdServer::onFileEvent(const DidChangeWatchedFilesParams &Params) {
diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h
index 213f042..b5360a7 100644
--- a/clangd/ClangdServer.h
+++ b/clangd/ClangdServer.h
@@ -1,15 +1,15 @@
 //===--- ClangdServer.h - Main clangd server code ----------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
 
+#include "../clang-tidy/ClangTidyOptions.h"
 #include "Cancellation.h"
 #include "ClangdUnit.h"
 #include "CodeComplete.h"
@@ -18,11 +18,14 @@
 #include "GlobalCompilationDatabase.h"
 #include "Protocol.h"
 #include "TUScheduler.h"
+#include "XRefs.h"
 #include "index/Background.h"
 #include "index/FileIndex.h"
 #include "index/Index.h"
+#include "refactor/Tweak.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
@@ -33,8 +36,6 @@
 #include <utility>
 
 namespace clang {
-class PCHContainerOperations;
-
 namespace clangd {
 
 // FIXME: find a better name.
@@ -93,6 +94,13 @@
     /// If set, use this index to augment code completion results.
     SymbolIndex *StaticIndex = nullptr;
 
+    /// If set, enable clang-tidy in clangd, used to get clang-tidy
+    /// configurations for a particular file.
+    /// Clangd supports only a small subset of ClangTidyOptions, these options
+    /// (Checks, CheckOptions) are about which clang-tidy checks will be
+    /// enabled.
+    tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr;
+
     /// Clangd's workspace root. Relevant for "workspace" operations not bound
     /// to a particular file.
     /// FIXME: If not set, should use the current working directory.
@@ -107,6 +115,8 @@
     /// Time to wait after a new file version before computing diagnostics.
     std::chrono::steady_clock::duration UpdateDebounce =
         std::chrono::milliseconds(500);
+
+    bool SuggestMissingIncludes = false;
   };
   // Sensible default options for use in tests.
   // Features like indexing must be enabled if desired.
@@ -156,9 +166,9 @@
   /// called for tracked files.
   void signatureHelp(PathRef File, Position Pos, Callback<SignatureHelp> CB);
 
-  /// Get definition of symbol at a specified \p Line and \p Column in \p File.
-  void findDefinitions(PathRef File, Position Pos,
-                       Callback<std::vector<Location>> CB);
+  /// Find declaration/definition locations of symbol at a specified position.
+  void locateSymbolAt(PathRef File, Position Pos,
+                      Callback<std::vector<LocatedSymbol>> CB);
 
   /// Helper function that returns a path to the corresponding source file when
   /// given a header file and vice versa.
@@ -172,6 +182,11 @@
   void findHover(PathRef File, Position Pos,
                  Callback<llvm::Optional<Hover>> CB);
 
+  /// Get information about type hierarchy for a given position.
+  void typeHierarchy(PathRef File, Position Pos, int Resolve,
+                     TypeHierarchyDirection Direction,
+                     Callback<llvm::Optional<TypeHierarchyItem>> CB);
+
   /// Retrieve the top symbols from the workspace matching a query.
   void workspaceSymbols(StringRef Query, int Limit,
                         Callback<std::vector<SymbolInformation>> CB);
@@ -200,7 +215,19 @@
   /// Rename all occurrences of the symbol at the \p Pos in \p File to
   /// \p NewName.
   void rename(PathRef File, Position Pos, llvm::StringRef NewName,
-              Callback<std::vector<tooling::Replacement>> CB);
+              Callback<std::vector<TextEdit>> CB);
+
+  struct TweakRef {
+    std::string ID;    /// ID to pass for applyTweak.
+    std::string Title; /// A single-line message to show in the UI.
+  };
+  /// Enumerate the code tweaks available to the user at a specified point.
+  void enumerateTweaks(PathRef File, Range Sel,
+                       Callback<std::vector<TweakRef>> CB);
+
+  /// Apply the code tweak with a specified \p ID.
+  void applyTweak(PathRef File, Range Sel, StringRef ID,
+                  Callback<tooling::Replacements> CB);
 
   /// Only for testing purposes.
   /// Waits until all requests to worker thread are finished and dumps AST for
@@ -223,10 +250,6 @@
   /// FIXME: those metrics might be useful too, we should add them.
   std::vector<std::pair<Path, std::size_t>> getUsedBytesPerFile() const;
 
-  /// Returns the active dynamic index if one was built.
-  /// This can be useful for testing, debugging, or observing memory usage.
-  const SymbolIndex *dynamicIndex() const { return DynamicIdx.get(); }
-
   // Blocks the main thread until the server is idle. Only for use in tests.
   // Returns false if the timeout expires.
   LLVM_NODISCARD bool
@@ -239,9 +262,6 @@
   formatCode(llvm::StringRef Code, PathRef File,
              ArrayRef<tooling::Range> Ranges);
 
-  tooling::CompileCommand getCompileCommand(PathRef File);
-
-  const GlobalCompilationDatabase &CDB;
   const FileSystemProvider &FSProvider;
 
   Path ResourceDir;
@@ -258,13 +278,19 @@
   // Storage for merged views of the various indexes.
   std::vector<std::unique_ptr<SymbolIndex>> MergedIdx;
 
+  // The provider used to provide a clang-tidy option for a specific file.
+  tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr;
+
+  // If this is true, suggest include insertion fixes for diagnostic errors that
+  // can be caused by missing includes (e.g. member access in incomplete type).
+  bool SuggestMissingIncludes = false;
+
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
   llvm::StringMap<llvm::Optional<FuzzyFindRequest>>
       CachedCompletionFuzzyFindRequestByFile;
   mutable std::mutex CachedCompletionFuzzyFindRequestMutex;
 
   llvm::Optional<std::string> WorkspaceRoot;
-  std::shared_ptr<PCHContainerOperations> PCHs;
   // WorkScheduler has to be the last member, because its destructor has to be
   // called before all other members to stop the worker thread that references
   // ClangdServer.
diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp
index 5add117..c8c4133 100644
--- a/clangd/ClangdUnit.cpp
+++ b/clangd/ClangdUnit.cpp
@@ -1,9 +1,8 @@
 //===--- ClangdUnit.cpp ------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,11 +11,17 @@
 #include "../clang-tidy/ClangTidyModuleRegistry.h"
 #include "Compiler.h"
 #include "Diagnostics.h"
+#include "Headers.h"
+#include "IncludeFixer.h"
 #include "Logger.h"
 #include "SourceCode.h"
 #include "Trace.h"
+#include "index/CanonicalIncludes.h"
+#include "index/Index.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -29,12 +34,15 @@
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTWriter.h"
+#include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
+#include <memory>
 
 namespace clang {
 namespace clangd {
@@ -88,18 +96,55 @@
   std::vector<Decl *> TopLevelDecls;
 };
 
+class CollectMainFileMacros : public PPCallbacks {
+public:
+  explicit CollectMainFileMacros(const SourceManager &SM,
+                                 std::vector<std::string> *Out)
+      : SM(SM), Out(Out) {}
+
+  void FileChanged(SourceLocation Loc, FileChangeReason,
+                   SrcMgr::CharacteristicKind, FileID Prev) {
+    InMainFile = SM.isWrittenInMainFile(Loc);
+  }
+
+  void MacroDefined(const Token &MacroName, const MacroDirective *MD) {
+    if (InMainFile)
+      MainFileMacros.insert(MacroName.getIdentifierInfo()->getName());
+  }
+
+  void EndOfMainFile() {
+    for (const auto& Entry : MainFileMacros)
+      Out->push_back(Entry.getKey());
+    llvm::sort(*Out);
+  }
+
+ private:
+  const SourceManager &SM;
+  bool InMainFile = true;
+  llvm::StringSet<> MainFileMacros;
+  std::vector<std::string> *Out;
+};
+
 class CppFilePreambleCallbacks : public PreambleCallbacks {
 public:
   CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback)
-      : File(File), ParsedCallback(ParsedCallback) {}
+      : File(File), ParsedCallback(ParsedCallback) {
+    addSystemHeadersMapping(&CanonIncludes);
+  }
 
   IncludeStructure takeIncludes() { return std::move(Includes); }
 
+  std::vector<std::string> takeMainFileMacros() {
+    return std::move(MainFileMacros);
+  }
+
+  CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); }
+
   void AfterExecute(CompilerInstance &CI) override {
     if (!ParsedCallback)
       return;
     trace::Span Tracer("Running PreambleCallback");
-    ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr());
+    ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr(), CanonIncludes);
   }
 
   void BeforeExecute(CompilerInstance &CI) override {
@@ -108,13 +153,23 @@
 
   std::unique_ptr<PPCallbacks> createPPCallbacks() override {
     assert(SourceMgr && "SourceMgr must be set at this point");
-    return collectIncludeStructureCallback(*SourceMgr, &Includes);
+    return llvm::make_unique<PPChainedCallbacks>(
+        collectIncludeStructureCallback(*SourceMgr, &Includes),
+        llvm::make_unique<CollectMainFileMacros>(*SourceMgr, &MainFileMacros));
+  }
+
+  CommentHandler *getCommentHandler() override {
+    IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes);
+    return IWYUHandler.get();
   }
 
 private:
   PathRef File;
   PreambleParsedCallback ParsedCallback;
   IncludeStructure Includes;
+  CanonicalIncludes CanonIncludes;
+  std::vector<std::string> MainFileMacros;
+  std::unique_ptr<CommentHandler> IWYUHandler = nullptr;
   SourceManager *SourceMgr = nullptr;
 };
 
@@ -133,6 +188,9 @@
                      CompilerInstance &Clang) {
     auto &PP = Clang.getPreprocessor();
     auto *ExistingCallbacks = PP.getPPCallbacks();
+    // No need to replay events if nobody is listening.
+    if (!ExistingCallbacks)
+      return;
     PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
         new ReplayPreamble(Includes, ExistingCallbacks,
                            Clang.getSourceManager(), PP, Clang.getLangOpts())));
@@ -227,8 +285,8 @@
 ParsedAST::build(std::unique_ptr<CompilerInvocation> CI,
                  std::shared_ptr<const PreambleData> Preamble,
                  std::unique_ptr<llvm::MemoryBuffer> Buffer,
-                 std::shared_ptr<PCHContainerOperations> PCHs,
-                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
+                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
+                 const SymbolIndex *Index, const ParseOptions &Opts) {
   assert(CI);
   // Command-line parsing sets DisableFree to true by default, but we don't want
   // to leak memory in clangd.
@@ -237,9 +295,10 @@
       Preamble ? &Preamble->Preamble : nullptr;
 
   StoreDiags ASTDiags;
-  auto Clang =
-      prepareCompilerInstance(std::move(CI), PreamblePCH, std::move(Buffer),
-                              std::move(PCHs), std::move(VFS), ASTDiags);
+  std::string Content = Buffer->getBuffer();
+
+  auto Clang = prepareCompilerInstance(std::move(CI), PreamblePCH,
+                                       std::move(Buffer), VFS, ASTDiags);
   if (!Clang)
     return None;
 
@@ -262,30 +321,48 @@
   llvm::Optional<tidy::ClangTidyContext> CTContext;
   {
     trace::Span Tracer("ClangTidyInit");
+    dlog("ClangTidy configuration for file {0}: {1}", MainInput.getFile(),
+         tidy::configurationAsText(Opts.ClangTidyOpts));
     tidy::ClangTidyCheckFactories CTFactories;
     for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
       E.instantiate()->addCheckFactories(CTFactories);
-    auto CTOpts = tidy::ClangTidyOptions::getDefaults();
-    // FIXME: this needs to be configurable, and we need to support .clang-tidy
-    // files and other options providers.
-    // These checks exercise the matcher- and preprocessor-based hooks.
-    CTOpts.Checks = "bugprone-sizeof-expression,"
-                    "bugprone-macro-repeated-side-effects,"
-                    "modernize-deprecated-headers";
     CTContext.emplace(llvm::make_unique<tidy::DefaultOptionsProvider>(
-        tidy::ClangTidyGlobalOptions(), CTOpts));
+        tidy::ClangTidyGlobalOptions(), Opts.ClangTidyOpts));
     CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
     CTContext->setASTContext(&Clang->getASTContext());
     CTContext->setCurrentFile(MainInput.getFile());
     CTFactories.createChecks(CTContext.getPointer(), CTChecks);
+    Preprocessor *PP = &Clang->getPreprocessor();
     for (const auto &Check : CTChecks) {
       // FIXME: the PP callbacks skip the entire preamble.
       // Checks that want to see #includes in the main file do not see them.
-      Check->registerPPCallbacks(*Clang);
+      Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
       Check->registerMatchers(&CTFinder);
     }
   }
 
+  // Add IncludeFixer which can recorver diagnostics caused by missing includes
+  // (e.g. incomplete type) and attach include insertion fixes to diagnostics.
+  llvm::Optional<IncludeFixer> FixIncludes;
+  auto BuildDir = VFS->getCurrentWorkingDirectory();
+  if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) {
+    auto Style = getFormatStyleForFile(MainInput.getFile(), Content, VFS.get());
+    auto Inserter = std::make_shared<IncludeInserter>(
+        MainInput.getFile(), Content, Style, BuildDir.get(),
+        &Clang->getPreprocessor().getHeaderSearchInfo());
+    if (Preamble) {
+      for (const auto &Inc : Preamble->Includes.MainFileIncludes)
+        Inserter->addExisting(Inc);
+    }
+    FixIncludes.emplace(MainInput.getFile(), Inserter, *Index,
+                        /*IndexRequestLimit=*/5);
+    ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
+                                            const clang::Diagnostic &Info) {
+      return FixIncludes->fix(DiagLevl, Info);
+    });
+    Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
+  }
+
   // Copy over the includes from the preamble, then combine with the
   // non-preamble includes below.
   auto Includes = Preamble ? Preamble->Includes : IncludeStructure{};
@@ -298,6 +375,17 @@
   Clang->getPreprocessor().addPPCallbacks(
       collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
 
+  // Copy over the includes from the preamble, then combine with the
+  // non-preamble includes below.
+  CanonicalIncludes CanonIncludes;
+  if (Preamble)
+    CanonIncludes = Preamble->CanonIncludes;
+  else
+    addSystemHeadersMapping(&CanonIncludes);
+  std::unique_ptr<CommentHandler> IWYUHandler =
+      collectIWYUHeaderMaps(&CanonIncludes);
+  Clang->getPreprocessor().addCommentHandler(IWYUHandler.get());
+
   if (!Action->Execute())
     log("Execute() failed when building AST for {0}", MainInput.getFile());
 
@@ -321,13 +409,13 @@
   // So just inform the preprocessor of EOF, while keeping everything alive.
   Clang->getPreprocessor().EndSourceFile();
 
-  std::vector<Diag> Diags = ASTDiags.take();
+  std::vector<Diag> Diags = ASTDiags.take(CTContext.getPointer());
   // Add diagnostics from the preamble, if any.
   if (Preamble)
     Diags.insert(Diags.begin(), Preamble->Diags.begin(), Preamble->Diags.end());
   return ParsedAST(std::move(Preamble), std::move(Clang), std::move(Action),
                    std::move(ParsedDecls), std::move(Diags),
-                   std::move(Includes));
+                   std::move(Includes), std::move(CanonIncludes));
 }
 
 ParsedAST::ParsedAST(ParsedAST &&Other) = default;
@@ -403,59 +491,39 @@
   return Includes;
 }
 
+const CanonicalIncludes &ParsedAST::getCanonicalIncludes() const {
+  return CanonIncludes;
+}
+
 PreambleData::PreambleData(PrecompiledPreamble Preamble,
                            std::vector<Diag> Diags, IncludeStructure Includes,
-                           std::unique_ptr<PreambleFileStatusCache> StatCache)
+                           std::vector<std::string> MainFileMacros,
+                           std::unique_ptr<PreambleFileStatusCache> StatCache,
+                           CanonicalIncludes CanonIncludes)
     : Preamble(std::move(Preamble)), Diags(std::move(Diags)),
-      Includes(std::move(Includes)), StatCache(std::move(StatCache)) {}
+      Includes(std::move(Includes)), MainFileMacros(std::move(MainFileMacros)),
+      StatCache(std::move(StatCache)), CanonIncludes(std::move(CanonIncludes)) {
+}
 
 ParsedAST::ParsedAST(std::shared_ptr<const PreambleData> Preamble,
                      std::unique_ptr<CompilerInstance> Clang,
                      std::unique_ptr<FrontendAction> Action,
                      std::vector<Decl *> LocalTopLevelDecls,
-                     std::vector<Diag> Diags, IncludeStructure Includes)
+                     std::vector<Diag> Diags, IncludeStructure Includes,
+                     CanonicalIncludes CanonIncludes)
     : Preamble(std::move(Preamble)), Clang(std::move(Clang)),
       Action(std::move(Action)), Diags(std::move(Diags)),
       LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
-      Includes(std::move(Includes)) {
+      Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) {
   assert(this->Clang);
   assert(this->Action);
 }
 
-std::unique_ptr<CompilerInvocation>
-buildCompilerInvocation(const ParseInputs &Inputs) {
-  std::vector<const char *> ArgStrs;
-  for (const auto &S : Inputs.CompileCommand.CommandLine)
-    ArgStrs.push_back(S.c_str());
-
-  if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
-    log("Couldn't set working directory when creating compiler invocation.");
-    // We proceed anyway, our lit-tests rely on results for non-existing working
-    // dirs.
-  }
-
-  // FIXME(ibiryukov): store diagnostics from CommandLine when we start
-  // reporting them.
-  IgnoreDiagnostics IgnoreDiagnostics;
-  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
-      CompilerInstance::createDiagnostics(new DiagnosticOptions,
-                                          &IgnoreDiagnostics, false);
-  std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine(
-      ArgStrs, CommandLineDiagsEngine, Inputs.FS);
-  if (!CI)
-    return nullptr;
-  // createInvocationFromCommandLine sets DisableFree.
-  CI->getFrontendOpts().DisableFree = false;
-  CI->getLangOpts()->CommentOpts.ParseAllComments = true;
-  return CI;
-}
-
 std::shared_ptr<const PreambleData>
 buildPreamble(PathRef FileName, CompilerInvocation &CI,
               std::shared_ptr<const PreambleData> OldPreamble,
               const tooling::CompileCommand &OldCompileCommand,
-              const ParseInputs &Inputs,
-              std::shared_ptr<PCHContainerOperations> PCHs, bool StoreInMemory,
+              const ParseInputs &Inputs, bool StoreInMemory,
               PreambleParsedCallback PreambleCallback) {
   // Note that we don't need to copy the input contents, preamble can live
   // without those.
@@ -500,7 +568,8 @@
   auto StatCache = llvm::make_unique<PreambleFileStatusCache>(AbsFileName);
   auto BuiltPreamble = PrecompiledPreamble::Build(
       CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine,
-      StatCache->getProducingFS(Inputs.FS), PCHs, StoreInMemory,
+      StatCache->getProducingFS(Inputs.FS),
+      std::make_shared<PCHContainerOperations>(), StoreInMemory,
       SerializedDeclsCollector);
 
   // When building the AST for the main file, we do want the function
@@ -510,9 +579,12 @@
   if (BuiltPreamble) {
     vlog("Built preamble of size {0} for file {1}", BuiltPreamble->getSize(),
          FileName);
+    std::vector<Diag> Diags = PreambleDiagnostics.take();
     return std::make_shared<PreambleData>(
-        std::move(*BuiltPreamble), PreambleDiagnostics.take(),
-        SerializedDeclsCollector.takeIncludes(), std::move(StatCache));
+        std::move(*BuiltPreamble), std::move(Diags),
+        SerializedDeclsCollector.takeIncludes(),
+        SerializedDeclsCollector.takeMainFileMacros(), std::move(StatCache),
+        SerializedDeclsCollector.takeCanonicalIncludes());
   } else {
     elog("Could not build a preamble for file {0}", FileName);
     return nullptr;
@@ -522,8 +594,7 @@
 llvm::Optional<ParsedAST>
 buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
          const ParseInputs &Inputs,
-         std::shared_ptr<const PreambleData> Preamble,
-         std::shared_ptr<PCHContainerOperations> PCHs) {
+         std::shared_ptr<const PreambleData> Preamble) {
   trace::Span Tracer("BuildAST");
   SPAN_ATTACH(Tracer, "File", FileName);
 
@@ -539,7 +610,7 @@
   return ParsedAST::build(llvm::make_unique<CompilerInvocation>(*Invocation),
                           Preamble,
                           llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents),
-                          PCHs, std::move(VFS));
+                          std::move(VFS), Inputs.Index, Inputs.Opts);
 }
 
 SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos,
diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h
index 15bf998..d5d2998 100644
--- a/clangd/ClangdUnit.h
+++ b/clangd/ClangdUnit.h
@@ -1,21 +1,23 @@
 //===--- ClangdUnit.h --------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 
+#include "Compiler.h"
 #include "Diagnostics.h"
 #include "FS.h"
 #include "Function.h"
 #include "Headers.h"
 #include "Path.h"
 #include "Protocol.h"
+#include "index/CanonicalIncludes.h"
+#include "index/Index.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/PrecompiledPreamble.h"
 #include "clang/Lex/Preprocessor.h"
@@ -31,15 +33,14 @@
 
 namespace vfs {
 class FileSystem;
-}
+} // namespace vfs
 } // namespace llvm
 
 namespace clang {
-class PCHContainerOperations;
 
 namespace tooling {
 struct CompileCommand;
-}
+} // namespace tooling
 
 namespace clangd {
 
@@ -47,7 +48,9 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble, std::vector<Diag> Diags,
                IncludeStructure Includes,
-               std::unique_ptr<PreambleFileStatusCache> StatCache);
+               std::vector<std::string> MainFileMacros,
+               std::unique_ptr<PreambleFileStatusCache> StatCache,
+               CanonicalIncludes CanonIncludes);
 
   tooling::CompileCommand CompileCommand;
   PrecompiledPreamble Preamble;
@@ -55,16 +58,14 @@
   // Processes like code completions and go-to-definitions will need #include
   // information, and their compile action skips preamble range.
   IncludeStructure Includes;
+  // Macros defined in the preamble section of the main file.
+  // Users care about headers vs main-file, not preamble vs non-preamble.
+  // These should be treated as main-file entities e.g. for code completion.
+  std::vector<std::string> MainFileMacros;
   // Cache of FS operations performed when building the preamble.
   // When reusing a preamble, this cache can be consumed to save IO.
   std::unique_ptr<PreambleFileStatusCache> StatCache;
-};
-
-/// Information required to run clang, e.g. to parse AST or do code completion.
-struct ParseInputs {
-  tooling::CompileCommand CompileCommand;
-  IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
-  std::string Contents;
+  CanonicalIncludes CanonIncludes;
 };
 
 /// Stores and provides access to parsed AST.
@@ -76,8 +77,8 @@
   build(std::unique_ptr<clang::CompilerInvocation> CI,
         std::shared_ptr<const PreambleData> Preamble,
         std::unique_ptr<llvm::MemoryBuffer> Buffer,
-        std::shared_ptr<PCHContainerOperations> PCHs,
-        IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
+        IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const SymbolIndex *Index,
+        const ParseOptions &Opts);
 
   ParsedAST(ParsedAST &&Other);
   ParsedAST &operator=(ParsedAST &&Other);
@@ -105,13 +106,14 @@
   /// bytes. Does not include the size of the preamble.
   std::size_t getUsedBytes() const;
   const IncludeStructure &getIncludeStructure() const;
+  const CanonicalIncludes &getCanonicalIncludes() const;
 
 private:
   ParsedAST(std::shared_ptr<const PreambleData> Preamble,
             std::unique_ptr<CompilerInstance> Clang,
             std::unique_ptr<FrontendAction> Action,
             std::vector<Decl *> LocalTopLevelDecls, std::vector<Diag> Diags,
-            IncludeStructure Includes);
+            IncludeStructure Includes, CanonicalIncludes CanonIncludes);
 
   // In-memory preambles must outlive the AST, it is important that this member
   // goes before Clang and Action.
@@ -130,14 +132,12 @@
   // top-level decls from the preamble.
   std::vector<Decl *> LocalTopLevelDecls;
   IncludeStructure Includes;
+  CanonicalIncludes CanonIncludes;
 };
 
 using PreambleParsedCallback =
-    std::function<void(ASTContext &, std::shared_ptr<clang::Preprocessor>)>;
-
-/// Builds compiler invocation that could be used to build AST or preamble.
-std::unique_ptr<CompilerInvocation>
-buildCompilerInvocation(const ParseInputs &Inputs);
+    std::function<void(ASTContext &, std::shared_ptr<clang::Preprocessor>,
+                       const CanonicalIncludes &)>;
 
 /// Rebuild the preamble for the new inputs unless the old one can be reused.
 /// If \p OldPreamble can be reused, it is returned unchanged.
@@ -149,8 +149,7 @@
 buildPreamble(PathRef FileName, CompilerInvocation &CI,
               std::shared_ptr<const PreambleData> OldPreamble,
               const tooling::CompileCommand &OldCompileCommand,
-              const ParseInputs &Inputs,
-              std::shared_ptr<PCHContainerOperations> PCHs, bool StoreInMemory,
+              const ParseInputs &Inputs, bool StoreInMemory,
               PreambleParsedCallback PreambleCallback);
 
 /// Build an AST from provided user inputs. This function does not check if
@@ -159,8 +158,7 @@
 llvm::Optional<ParsedAST>
 buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
          const ParseInputs &Inputs,
-         std::shared_ptr<const PreambleData> Preamble,
-         std::shared_ptr<PCHContainerOperations> PCHs);
+         std::shared_ptr<const PreambleData> Preamble);
 
 /// Get the beginning SourceLocation at a specified \p Pos.
 /// May be invalid if Pos is, or if there's no identifier.
diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp
index 7642ea9..4789a80 100644
--- a/clangd/CodeComplete.cpp
+++ b/clangd/CodeComplete.cpp
@@ -1,9 +1,8 @@
 //===--- CodeComplete.cpp ----------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -35,20 +34,29 @@
 #include "Trace.h"
 #include "URI.h"
 #include "index/Index.h"
+#include "index/Symbol.h"
+#include "index/SymbolOrigin.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/Basic/CharInfo.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Format/Format.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -178,27 +186,11 @@
   return Result;
 }
 
-/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal
-/// include.
-static llvm::Expected<HeaderFile> toHeaderFile(llvm::StringRef Header,
-                                               llvm::StringRef HintPath) {
-  if (isLiteralInclude(Header))
-    return HeaderFile{Header.str(), /*Verbatim=*/true};
-  auto U = URI::parse(Header);
-  if (!U)
-    return U.takeError();
-
-  auto IncludePath = URI::includeSpelling(*U);
-  if (!IncludePath)
-    return IncludePath.takeError();
-  if (!IncludePath->empty())
-    return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true};
-
-  auto Resolved = URI::resolve(*U, HintPath);
-  if (!Resolved)
-    return Resolved.takeError();
-  return HeaderFile{std::move(*Resolved), /*Verbatim=*/false};
-}
+// Identifier code completion result.
+struct RawIdentifier {
+  llvm::StringRef Name;
+  unsigned References; // # of usages in file.
+};
 
 /// A code completion result, in clang-native form.
 /// It may be promoted to a CompletionItem if it's among the top-ranked results.
@@ -207,11 +199,14 @@
   // We may have a result from Sema, from the index, or both.
   const CodeCompletionResult *SemaResult = nullptr;
   const Symbol *IndexResult = nullptr;
+  const RawIdentifier *IdentifierResult = nullptr;
   llvm::SmallVector<llvm::StringRef, 1> RankedIncludeHeaders;
 
   // Returns a token identifying the overload set this is part of.
   // 0 indicates it's not part of any overload set.
-  size_t overloadSet() const {
+  size_t overloadSet(const CodeCompleteOptions &Opts) const {
+    if (!Opts.BundleOverloads)
+      return 0;
     llvm::SmallString<256> Scratch;
     if (IndexResult) {
       switch (IndexResult->SymInfo.Kind) {
@@ -228,27 +223,32 @@
         // This could break #include insertion.
         return llvm::hash_combine(
             (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
-            headerToInsertIfAllowed().getValueOr(""));
+            headerToInsertIfAllowed(Opts).getValueOr(""));
       default:
         return 0;
       }
     }
-    assert(SemaResult);
-    // We need to make sure we're consistent with the IndexResult case!
-    const NamedDecl *D = SemaResult->Declaration;
-    if (!D || !D->isFunctionOrFunctionTemplate())
-      return 0;
-    {
-      llvm::raw_svector_ostream OS(Scratch);
-      D->printQualifiedName(OS);
+    if (SemaResult) {
+      // We need to make sure we're consistent with the IndexResult case!
+      const NamedDecl *D = SemaResult->Declaration;
+      if (!D || !D->isFunctionOrFunctionTemplate())
+        return 0;
+      {
+        llvm::raw_svector_ostream OS(Scratch);
+        D->printQualifiedName(OS);
+      }
+      return llvm::hash_combine(Scratch,
+                                headerToInsertIfAllowed(Opts).getValueOr(""));
     }
-    return llvm::hash_combine(Scratch,
-                              headerToInsertIfAllowed().getValueOr(""));
+    assert(IdentifierResult);
+    return 0;
   }
 
   // The best header to include if include insertion is allowed.
-  llvm::Optional<llvm::StringRef> headerToInsertIfAllowed() const {
-    if (RankedIncludeHeaders.empty())
+  llvm::Optional<llvm::StringRef>
+  headerToInsertIfAllowed(const CodeCompleteOptions &Opts) const {
+    if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
+        RankedIncludeHeaders.empty())
       return None;
     if (SemaResult && SemaResult->Declaration) {
       // Avoid inserting new #include if the declaration is found in the current
@@ -282,7 +282,7 @@
 // computed from the first candidate, in the constructor.
 // Others vary per candidate, so add() must be called for remaining candidates.
 struct CodeCompletionBuilder {
-  CodeCompletionBuilder(ASTContext &ASTCtx, const CompletionCandidate &C,
+  CodeCompletionBuilder(ASTContext *ASTCtx, const CompletionCandidate &C,
                         CodeCompletionString *SemaCCS,
                         llvm::ArrayRef<std::string> QueryScopes,
                         const IncludeInserter &Includes,
@@ -293,6 +293,7 @@
         EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets) {
     add(C, SemaCCS);
     if (C.SemaResult) {
+      assert(ASTCtx);
       Completion.Origin |= SymbolOrigin::AST;
       Completion.Name = llvm::StringRef(SemaCCS->getTypedText());
       if (Completion.Scope.empty()) {
@@ -311,8 +312,8 @@
           Completion.Name.back() == '/')
         Completion.Kind = CompletionItemKind::Folder;
       for (const auto &FixIt : C.SemaResult->FixIts) {
-        Completion.FixIts.push_back(
-            toTextEdit(FixIt, ASTCtx.getSourceManager(), ASTCtx.getLangOpts()));
+        Completion.FixIts.push_back(toTextEdit(
+            FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
       }
       llvm::sort(Completion.FixIts, [](const TextEdit &X, const TextEdit &Y) {
         return std::tie(X.range.start.line, X.range.start.character) <
@@ -343,22 +344,30 @@
       }
       Completion.Deprecated |= (C.IndexResult->Flags & Symbol::Deprecated);
     }
+    if (C.IdentifierResult) {
+      Completion.Origin |= SymbolOrigin::Identifier;
+      Completion.Kind = CompletionItemKind::Text;
+      Completion.Name = C.IdentifierResult->Name;
+    }
 
     // Turn absolute path into a literal string that can be #included.
     auto Inserted = [&](llvm::StringRef Header)
         -> llvm::Expected<std::pair<std::string, bool>> {
-      auto ResolvedDeclaring =
-          toHeaderFile(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
+      auto DeclaringURI =
+          URI::parse(C.IndexResult->CanonicalDeclaration.FileURI);
+      if (!DeclaringURI)
+        return DeclaringURI.takeError();
+      auto ResolvedDeclaring = URI::resolve(*DeclaringURI, FileName);
       if (!ResolvedDeclaring)
         return ResolvedDeclaring.takeError();
       auto ResolvedInserted = toHeaderFile(Header, FileName);
       if (!ResolvedInserted)
         return ResolvedInserted.takeError();
       return std::make_pair(
-          Includes.calculateIncludePath(*ResolvedDeclaring, *ResolvedInserted),
+          Includes.calculateIncludePath(*ResolvedInserted),
           Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
     };
-    bool ShouldInsert = C.headerToInsertIfAllowed().hasValue();
+    bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue();
     // Calculate include paths and edits for all possible headers.
     for (const auto &Inc : C.RankedIncludeHeaders) {
       if (auto ToInclude = Inserted(Inc)) {
@@ -397,7 +406,7 @@
       if (C.IndexResult)
         Completion.Documentation = C.IndexResult->Documentation;
       else if (C.SemaResult)
-        Completion.Documentation = getDocComment(ASTCtx, *C.SemaResult,
+        Completion.Documentation = getDocComment(*ASTCtx, *C.SemaResult,
                                                  /*CommentsFromHeader=*/false);
     }
   }
@@ -492,7 +501,8 @@
     return "(…)";
   }
 
-  ASTContext &ASTCtx;
+  // ASTCtx can be nullptr if not run with sema.
+  ASTContext *ASTCtx;
   CodeCompletion Completion;
   llvm::SmallVector<BundledEntry, 1> Bundled;
   bool ExtractDocumentation;
@@ -549,7 +559,7 @@
     std::set<std::string> Results;
     for (llvm::StringRef AS : AccessibleScopes)
       Results.insert(
-          ((UnresolvedQualifier ? *UnresolvedQualifier : "") + AS).str());
+          (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str());
     return {Results.begin(), Results.end()};
   }
 };
@@ -559,55 +569,59 @@
 // (e.g. enclosing namespace).
 std::pair<std::vector<std::string>, bool>
 getQueryScopes(CodeCompletionContext &CCContext, const Sema &CCSema,
+               const CompletionPrefix &HeuristicPrefix,
                const CodeCompleteOptions &Opts) {
-  auto GetAllAccessibleScopes = [](CodeCompletionContext &CCContext) {
-    SpecifiedScope Info;
-    for (auto *Context : CCContext.getVisitedContexts()) {
-      if (isa<TranslationUnitDecl>(Context))
-        Info.AccessibleScopes.push_back(""); // global namespace
-      else if (isa<NamespaceDecl>(Context))
-        Info.AccessibleScopes.push_back(printNamespaceScope(*Context));
+  SpecifiedScope Scopes;
+  for (auto *Context : CCContext.getVisitedContexts()) {
+    if (isa<TranslationUnitDecl>(Context))
+      Scopes.AccessibleScopes.push_back(""); // global namespace
+    else if (isa<NamespaceDecl>(Context))
+      Scopes.AccessibleScopes.push_back(printNamespaceScope(*Context));
+  }
+
+  const CXXScopeSpec *SemaSpecifier =
+      CCContext.getCXXScopeSpecifier().getValueOr(nullptr);
+  // Case 1: unqualified completion.
+  if (!SemaSpecifier) {
+    // Case 2 (exception): sema saw no qualifier, but there appears to be one!
+    // This can happen e.g. in incomplete macro expansions. Use heuristics.
+    if (!HeuristicPrefix.Qualifier.empty()) {
+      vlog("Sema said no scope specifier, but we saw {0} in the source code",
+           HeuristicPrefix.Qualifier);
+      StringRef SpelledSpecifier = HeuristicPrefix.Qualifier;
+      if (SpelledSpecifier.consume_front("::"))
+        Scopes.AccessibleScopes = {""};
+      Scopes.UnresolvedQualifier = SpelledSpecifier;
+      return {Scopes.scopesForIndexQuery(), false};
     }
-    return Info;
-  };
-
-  auto SS = CCContext.getCXXScopeSpecifier();
-
-  // Unqualified completion (e.g. "vec^").
-  if (!SS) {
-    std::vector<std::string> Scopes;
+    // The enclosing namespace must be first, it gets a quality boost.
+    std::vector<std::string> EnclosingAtFront;
     std::string EnclosingScope = printNamespaceScope(*CCSema.CurContext);
-    Scopes.push_back(EnclosingScope);
-    for (auto &S : GetAllAccessibleScopes(CCContext).scopesForIndexQuery()) {
+    EnclosingAtFront.push_back(EnclosingScope);
+    for (auto &S : Scopes.scopesForIndexQuery()) {
       if (EnclosingScope != S)
-        Scopes.push_back(std::move(S));
+        EnclosingAtFront.push_back(std::move(S));
     }
-    // Allow AllScopes completion only for there is no explicit scope qualifier.
-    return {Scopes, Opts.AllScopes};
+    // Allow AllScopes completion as there is no explicit scope qualifier.
+    return {EnclosingAtFront, Opts.AllScopes};
   }
+  // Case 3: sema saw and resolved a scope qualifier.
+  if (SemaSpecifier && SemaSpecifier->isValid())
+    return {Scopes.scopesForIndexQuery(), false};
 
-  // Qualified completion ("std::vec^"), we have two cases depending on whether
-  // the qualifier can be resolved by Sema.
-  if ((*SS)->isValid()) { // Resolved qualifier.
-    return {GetAllAccessibleScopes(CCContext).scopesForIndexQuery(), false};
-  }
-
-  // Unresolved qualifier.
-  // FIXME: When Sema can resolve part of a scope chain (e.g.
-  // "known::unknown::id"), we should expand the known part ("known::") rather
-  // than treating the whole thing as unknown.
-  SpecifiedScope Info;
-  Info.AccessibleScopes.push_back(""); // global namespace
-
-  Info.UnresolvedQualifier =
-      Lexer::getSourceText(CharSourceRange::getCharRange((*SS)->getRange()),
-                           CCSema.SourceMgr, clang::LangOptions())
-          .ltrim("::");
+  // Case 4: There was a qualifier, and Sema didn't resolve it.
+  Scopes.AccessibleScopes.push_back(""); // Make sure global scope is included.
+  llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
+      CharSourceRange::getCharRange(SemaSpecifier->getRange()),
+      CCSema.SourceMgr, clang::LangOptions());
+  if (SpelledSpecifier.consume_front("::"))
+    Scopes.AccessibleScopes = {""};
+  Scopes.UnresolvedQualifier = SpelledSpecifier;
   // Sema excludes the trailing "::".
-  if (!Info.UnresolvedQualifier->empty())
-    *Info.UnresolvedQualifier += "::";
+  if (!Scopes.UnresolvedQualifier->empty())
+    *Scopes.UnresolvedQualifier += "::";
 
-  return {Info.scopesForIndexQuery(), false};
+  return {Scopes.scopesForIndexQuery(), false};
 }
 
 // Should we perform index-based completion in a context of the specified kind?
@@ -691,8 +705,7 @@
 struct CompletionRecorder : public CodeCompleteConsumer {
   CompletionRecorder(const CodeCompleteOptions &Opts,
                      llvm::unique_function<void()> ResultsCallback)
-      : CodeCompleteConsumer(Opts.getClangCompleteOpts(),
-                             /*OutputIsBinary=*/false),
+      : CodeCompleteConsumer(Opts.getClangCompleteOpts()),
         CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
         CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
         CCTUInfo(CCAllocator), ResultsCallback(std::move(ResultsCallback)) {
@@ -813,8 +826,7 @@
 public:
   SignatureHelpCollector(const clang::CodeCompleteOptions &CodeCompleteOpts,
                          const SymbolIndex *Index, SignatureHelp &SigHelp)
-      : CodeCompleteConsumer(CodeCompleteOpts,
-                             /*OutputIsBinary=*/false),
+      : CodeCompleteConsumer(CodeCompleteOpts),
         SigHelp(SigHelp),
         Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
         CCTUInfo(Allocator), Index(Index) {}
@@ -1005,11 +1017,28 @@
   const tooling::CompileCommand &Command;
   const PreambleData *Preamble;
   llvm::StringRef Contents;
-  Position Pos;
+  size_t Offset;
   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
-  std::shared_ptr<PCHContainerOperations> PCHs;
 };
 
+void loadMainFilePreambleMacros(const Preprocessor &PP,
+                                const PreambleData &Preamble) {
+  // The ExternalPreprocessorSource has our macros, if we know where to look.
+  // We can read all the macros using PreambleMacros->ReadDefinedMacros(),
+  // but this includes transitively included files, so may deserialize a lot.
+  ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource();
+  // As we have the names of the macros, we can look up their IdentifierInfo
+  // and then use this to load just the macros we want.
+  IdentifierInfoLookup *PreambleIdentifiers =
+      PP.getIdentifierTable().getExternalIdentifierLookup();
+  if (!PreambleIdentifiers || !PreambleMacros)
+    return;
+  for (const auto& MacroName : Preamble.MainFileMacros)
+    if (auto *II = PreambleIdentifiers->get(MacroName))
+      if (II->isOutOfDate())
+        PreambleMacros->updateOutOfDateIdentifier(*II);
+}
+
 // Invokes Sema code completion on a file.
 // If \p Includes is set, it will be updated based on the compiler invocation.
 bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
@@ -1017,46 +1046,29 @@
                       const SemaCompleteInput &Input,
                       IncludeStructure *Includes = nullptr) {
   trace::Span Tracer("Sema completion");
-  std::vector<const char *> ArgStrs;
-  for (const auto &S : Input.Command.CommandLine)
-    ArgStrs.push_back(S.c_str());
-
-  if (Input.VFS->setCurrentWorkingDirectory(Input.Command.Directory)) {
-    log("Couldn't set working directory");
-    // We run parsing anyway, our lit-tests rely on results for non-existing
-    // working dirs.
-  }
-
   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = Input.VFS;
   if (Input.Preamble && Input.Preamble->StatCache)
     VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS));
-  IgnoreDiagnostics DummyDiagsConsumer;
-  auto CI = createInvocationFromCommandLine(
-      ArgStrs,
-      CompilerInstance::createDiagnostics(new DiagnosticOptions,
-                                          &DummyDiagsConsumer, false),
-      VFS);
+  ParseInputs ParseInput;
+  ParseInput.CompileCommand = Input.Command;
+  ParseInput.FS = VFS;
+  ParseInput.Contents = Input.Contents;
+  ParseInput.Opts = ParseOptions();
+  auto CI = buildCompilerInvocation(ParseInput);
   if (!CI) {
     elog("Couldn't create CompilerInvocation");
     return false;
   }
   auto &FrontendOpts = CI->getFrontendOpts();
-  FrontendOpts.DisableFree = false;
   FrontendOpts.SkipFunctionBodies = true;
-  CI->getLangOpts()->CommentOpts.ParseAllComments = true;
   // Disable typo correction in Sema.
   CI->getLangOpts()->SpellChecking = false;
   // Setup code completion.
   FrontendOpts.CodeCompleteOpts = Options;
   FrontendOpts.CodeCompletionAt.FileName = Input.FileName;
-  auto Offset = positionToOffset(Input.Contents, Input.Pos);
-  if (!Offset) {
-    elog("Code completion position was invalid {0}", Offset.takeError());
-    return false;
-  }
   std::tie(FrontendOpts.CodeCompletionAt.Line,
            FrontendOpts.CodeCompletionAt.Column) =
-      offsetToClangLineColumn(Input.Contents, *Offset);
+      offsetToClangLineColumn(Input.Contents, Input.Offset);
 
   std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
       llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
@@ -1068,17 +1080,17 @@
   // However, if we're completing *inside* the preamble section of the draft,
   // overriding the preamble will break sema completion. Fortunately we can just
   // skip all includes in this case; these completions are really simple.
-  bool CompletingInPreamble =
-      ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0).Size >
-      *Offset;
+  PreambleBounds PreambleRegion =
+      ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0);
+  bool CompletingInPreamble = PreambleRegion.Size > Input.Offset;
   // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
   // the remapped buffers do not get freed.
+  IgnoreDiagnostics DummyDiagsConsumer;
   auto Clang = prepareCompilerInstance(
       std::move(CI),
       (Input.Preamble && !CompletingInPreamble) ? &Input.Preamble->Preamble
                                                 : nullptr,
-      std::move(ContentsBuffer), std::move(Input.PCHs), std::move(VFS),
-      DummyDiagsConsumer);
+      std::move(ContentsBuffer), std::move(VFS), DummyDiagsConsumer);
   Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
   Clang->setCodeCompletionConsumer(Consumer.release());
 
@@ -1088,6 +1100,14 @@
         Input.FileName);
     return false;
   }
+  // Macros can be defined within the preamble region of the main file.
+  // They don't fall nicely into our index/Sema dichotomy:
+  //  - they're not indexed for completion (they're not available across files)
+  //  - but Sema code complete won't see them: as part of the preamble, they're
+  //    deserialized only when mentioned.
+  // Force them to be deserialized so SemaCodeComplete sees them.
+  if (Input.Preamble)
+    loadMainFilePreambleMacros(Clang->getPreprocessor(), *Input.Preamble);
   if (Includes)
     Clang->getPreprocessor().addPPCallbacks(
         collectIncludeStructureCallback(Clang->getSourceManager(), Includes));
@@ -1141,39 +1161,12 @@
 // Creates a `FuzzyFindRequest` based on the cached index request from the
 // last completion, if any, and the speculated completion filter text in the
 // source code.
-llvm::Optional<FuzzyFindRequest>
-speculativeFuzzyFindRequestForCompletion(FuzzyFindRequest CachedReq,
-                                         PathRef File, llvm::StringRef Content,
-                                         Position Pos) {
-  auto Filter = speculateCompletionFilter(Content, Pos);
-  if (!Filter) {
-    elog("Failed to speculate filter text for code completion at Pos "
-         "{0}:{1}: {2}",
-         Pos.line, Pos.character, Filter.takeError());
-    return None;
-  }
-  CachedReq.Query = *Filter;
+FuzzyFindRequest speculativeFuzzyFindRequestForCompletion(
+    FuzzyFindRequest CachedReq, const CompletionPrefix &HeuristicPrefix) {
+  CachedReq.Query = HeuristicPrefix.Name;
   return CachedReq;
 }
 
-// Returns the most popular include header for \p Sym. If two headers are
-// equally popular, prefer the shorter one. Returns empty string if \p Sym has
-// no include header.
-llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym) {
-  auto Includes = Sym.IncludeHeaders;
-  // Sort in descending order by reference count and header length.
-  llvm::sort(Includes, [](const Symbol::IncludeHeaderWithReferences &LHS,
-                          const Symbol::IncludeHeaderWithReferences &RHS) {
-    if (LHS.References == RHS.References)
-      return LHS.IncludeHeader.size() < RHS.IncludeHeader.size();
-    return LHS.References > RHS.References;
-  });
-  llvm::SmallVector<llvm::StringRef, 1> Headers;
-  for (const auto &Include : Includes)
-    Headers.push_back(Include.IncludeHeader);
-  return Headers;
-}
-
 // Runs Sema-based (AST) and Index-based completion, returns merged results.
 //
 // There are a few tricky considerations:
@@ -1211,15 +1204,20 @@
 
   // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
   CompletionRecorder *Recorder = nullptr;
-  int NSema = 0, NIndex = 0, NBoth = 0; // Counters for logging.
-  bool Incomplete = false;       // Would more be available with a higher limit?
+  CodeCompletionContext::Kind CCContextKind = CodeCompletionContext::CCC_Other;
+  // Counters for logging.
+  int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
+  bool Incomplete = false; // Would more be available with a higher limit?
+  CompletionPrefix HeuristicPrefix;
   llvm::Optional<FuzzyMatcher> Filter;  // Initialized once Sema runs.
+  Range ReplacedRange;
   std::vector<std::string> QueryScopes; // Initialized once Sema runs.
   // Initialized once QueryScopes is initialized, if there are scopes.
   llvm::Optional<ScopeDistance> ScopeProximity;
   llvm::Optional<OpaqueType> PreferredType; // Initialized once Sema runs.
   // Whether to query symbols from any scope. Initialized once Sema runs.
   bool AllScopes = false;
+  llvm::StringSet<> ContextWords;
   // Include-insertion and proximity scoring rely on the include structure.
   // This is available after Sema has run.
   llvm::Optional<IncludeInserter> Inserter;  // Available during runWithSema.
@@ -1240,12 +1238,14 @@
 
   CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
     trace::Span Tracer("CodeCompleteFlow");
+    HeuristicPrefix =
+        guessCompletionPrefix(SemaCCInput.Contents, SemaCCInput.Offset);
+    populateContextWords(SemaCCInput.Contents);
     if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) {
       assert(!SpecFuzzyFind->Result.valid());
-      if ((SpecReq = speculativeFuzzyFindRequestForCompletion(
-               *SpecFuzzyFind->CachedReq, SemaCCInput.FileName,
-               SemaCCInput.Contents, SemaCCInput.Pos)))
-        SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
+      SpecReq = speculativeFuzzyFindRequestForCompletion(
+          *SpecFuzzyFind->CachedReq, HeuristicPrefix);
+      SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
     }
 
     // We run Sema code completion first. It builds an AST and calculates:
@@ -1254,21 +1254,15 @@
     CodeCompleteResult Output;
     auto RecorderOwner = llvm::make_unique<CompletionRecorder>(Opts, [&]() {
       assert(Recorder && "Recorder is not set");
-      auto Style =
-          format::getStyle(format::DefaultFormatStyle, SemaCCInput.FileName,
-                           format::DefaultFallbackStyle, SemaCCInput.Contents,
-                           SemaCCInput.VFS.get());
-      if (!Style) {
-        log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.",
-            SemaCCInput.FileName, Style.takeError());
-        Style = format::getLLVMStyle();
-      }
+      CCContextKind = Recorder->CCContext.getKind();
+      auto Style = getFormatStyleForFile(
+          SemaCCInput.FileName, SemaCCInput.Contents, SemaCCInput.VFS.get());
       // If preprocessor was run, inclusions from preprocessor callback should
       // already be added to Includes.
       Inserter.emplace(
-          SemaCCInput.FileName, SemaCCInput.Contents, *Style,
+          SemaCCInput.FileName, SemaCCInput.Contents, Style,
           SemaCCInput.Command.Directory,
-          Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
+          &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
       for (const auto &Inc : Includes.MainFileIncludes)
         Inserter->addExisting(Inc);
 
@@ -1294,10 +1288,10 @@
       Output = runWithSema();
       Inserter.reset(); // Make sure this doesn't out-live Clang.
       SPAN_ATTACH(Tracer, "sema_completion_kind",
-                  getCompletionKindString(Recorder->CCContext.getKind()));
+                  getCompletionKindString(CCContextKind));
       log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), "
           "expected type {3}",
-          getCompletionKindString(Recorder->CCContext.getKind()),
+          getCompletionKindString(CCContextKind),
           llvm::join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
           PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
                         : "<none>");
@@ -1307,47 +1301,132 @@
 
     semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
                      SemaCCInput, &Includes);
+    logResults(Output, Tracer);
+    return Output;
+  }
 
+  void logResults(const CodeCompleteResult &Output, const trace::Span &Tracer) {
     SPAN_ATTACH(Tracer, "sema_results", NSema);
     SPAN_ATTACH(Tracer, "index_results", NIndex);
-    SPAN_ATTACH(Tracer, "merged_results", NBoth);
+    SPAN_ATTACH(Tracer, "merged_results", NSemaAndIndex);
+    SPAN_ATTACH(Tracer, "identifier_results", NIdent);
     SPAN_ATTACH(Tracer, "returned_results", int64_t(Output.Completions.size()));
     SPAN_ATTACH(Tracer, "incomplete", Output.HasMore);
     log("Code complete: {0} results from Sema, {1} from Index, "
-        "{2} matched, {3} returned{4}.",
-        NSema, NIndex, NBoth, Output.Completions.size(),
+        "{2} matched, {3} from identifiers, {4} returned{5}.",
+        NSema, NIndex, NSemaAndIndex, NIdent, Output.Completions.size(),
         Output.HasMore ? " (incomplete)" : "");
     assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit);
     // We don't assert that isIncomplete means we hit a limit.
     // Indexes may choose to impose their own limits even if we don't have one.
+  }
+
+  CodeCompleteResult
+  runWithoutSema(llvm::StringRef Content, size_t Offset,
+                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) && {
+    trace::Span Tracer("CodeCompleteWithoutSema");
+    // Fill in fields normally set by runWithSema()
+    HeuristicPrefix = guessCompletionPrefix(Content, Offset);
+    populateContextWords(Content);
+    CCContextKind = CodeCompletionContext::CCC_Recovery;
+    Filter = FuzzyMatcher(HeuristicPrefix.Name);
+    auto Pos = offsetToPosition(Content, Offset);
+    ReplacedRange.start = ReplacedRange.end = Pos;
+    ReplacedRange.start.character -= HeuristicPrefix.Name.size();
+
+    llvm::StringMap<SourceParams> ProxSources;
+    ProxSources[FileName].Cost = 0;
+    FileProximity.emplace(ProxSources);
+
+    auto Style = getFormatStyleForFile(FileName, Content, VFS.get());
+    // This will only insert verbatim headers.
+    Inserter.emplace(FileName, Content, Style,
+                     /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
+
+    auto Identifiers = collectIdentifiers(Content, Style);
+    std::vector<RawIdentifier> IdentifierResults;
+    for (const auto &IDAndCount : Identifiers) {
+      RawIdentifier ID;
+      ID.Name = IDAndCount.first();
+      ID.References = IDAndCount.second;
+      // Avoid treating typed filter as an identifier.
+      if (ID.Name == HeuristicPrefix.Name)
+        --ID.References;
+      if (ID.References > 0)
+        IdentifierResults.push_back(std::move(ID));
+    }
+
+    // Simplified version of getQueryScopes():
+    //  - accessible scopes are determined heuristically.
+    //  - all-scopes query if no qualifier was typed (and it's allowed).
+    SpecifiedScope Scopes;
+    Scopes.AccessibleScopes =
+        visibleNamespaces(Content.take_front(Offset), Style);
+    for (std::string &S : Scopes.AccessibleScopes)
+      if (!S.empty())
+        S.append("::"); // visibleNamespaces doesn't include trailing ::.
+    if (HeuristicPrefix.Qualifier.empty())
+      AllScopes = Opts.AllScopes;
+    else if (HeuristicPrefix.Qualifier.startswith("::")) {
+      Scopes.AccessibleScopes = {""};
+      Scopes.UnresolvedQualifier = HeuristicPrefix.Qualifier.drop_front(2);
+    } else
+      Scopes.UnresolvedQualifier = HeuristicPrefix.Qualifier;
+    // First scope is the (modified) enclosing scope.
+    QueryScopes = Scopes.scopesForIndexQuery();
+    ScopeProximity.emplace(QueryScopes);
+
+    SymbolSlab IndexResults = Opts.Index ? queryIndex() : SymbolSlab();
+
+    CodeCompleteResult Output = toCodeCompleteResult(mergeResults(
+        /*SemaResults=*/{}, IndexResults, IdentifierResults));
+    Output.RanParser = false;
+    logResults(Output, Tracer);
     return Output;
   }
 
 private:
+  void populateContextWords(llvm::StringRef Content) {
+    // Take last 3 lines before the completion point.
+    unsigned RangeEnd = HeuristicPrefix.Qualifier.begin() - Content.data(),
+             RangeBegin = RangeEnd;
+    for (size_t I = 0; I < 3 && RangeBegin > 0; ++I) {
+      auto PrevNL = Content.rfind('\n', RangeBegin - 1);
+      if (PrevNL == StringRef::npos) {
+        RangeBegin = 0;
+        break;
+      }
+      RangeBegin = PrevNL + 1;
+    }
+
+    ContextWords = collectWords(Content.slice(RangeBegin, RangeEnd));
+    dlog("Completion context words: {0}",
+         llvm::join(ContextWords.keys(), ", "));
+  }
+
   // This is called by run() once Sema code completion is done, but before the
   // Sema data structures are torn down. It does all the real work.
   CodeCompleteResult runWithSema() {
     const auto &CodeCompletionRange = CharSourceRange::getCharRange(
         Recorder->CCSema->getPreprocessor().getCodeCompletionTokenRange());
-    Range TextEditRange;
     // When we are getting completions with an empty identifier, for example
     //    std::vector<int> asdf;
     //    asdf.^;
     // Then the range will be invalid and we will be doing insertion, use
     // current cursor position in such cases as range.
     if (CodeCompletionRange.isValid()) {
-      TextEditRange = halfOpenToRange(Recorder->CCSema->getSourceManager(),
+      ReplacedRange = halfOpenToRange(Recorder->CCSema->getSourceManager(),
                                       CodeCompletionRange);
     } else {
       const auto &Pos = sourceLocToPosition(
           Recorder->CCSema->getSourceManager(),
           Recorder->CCSema->getPreprocessor().getCodeCompletionLoc());
-      TextEditRange.start = TextEditRange.end = Pos;
+      ReplacedRange.start = ReplacedRange.end = Pos;
     }
     Filter = FuzzyMatcher(
         Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
-    std::tie(QueryScopes, AllScopes) =
-        getQueryScopes(Recorder->CCContext, *Recorder->CCSema, Opts);
+    std::tie(QueryScopes, AllScopes) = getQueryScopes(
+        Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts);
     if (!QueryScopes.empty())
       ScopeProximity.emplace(QueryScopes);
     PreferredType =
@@ -1363,18 +1442,23 @@
                             : SymbolSlab();
     trace::Span Tracer("Populate CodeCompleteResult");
     // Merge Sema and Index results, score them, and pick the winners.
-    auto Top = mergeResults(Recorder->Results, IndexResults);
+    auto Top =
+        mergeResults(Recorder->Results, IndexResults, /*Identifiers*/ {});
+    return toCodeCompleteResult(Top);
+  }
+
+  CodeCompleteResult
+  toCodeCompleteResult(const std::vector<ScoredBundle> &Scored) {
     CodeCompleteResult Output;
 
     // Convert the results to final form, assembling the expensive strings.
-    for (auto &C : Top) {
+    for (auto &C : Scored) {
       Output.Completions.push_back(toCodeCompletion(C.first));
       Output.Completions.back().Score = C.second;
-      Output.Completions.back().CompletionTokenRange = TextEditRange;
+      Output.Completions.back().CompletionTokenRange = ReplacedRange;
     }
     Output.HasMore = Incomplete;
-    Output.Context = Recorder->CCContext.getKind();
-
+    Output.Context = CCContextKind;
     return Output;
   }
 
@@ -1392,6 +1476,8 @@
     Req.AnyScope = AllScopes;
     // FIXME: we should send multiple weighted paths here.
     Req.ProximityPaths.push_back(FileName);
+    if (PreferredType)
+      Req.PreferredTypes.push_back(PreferredType->raw());
     vlog("Code complete: fuzzyFind({0:2})", toJSON(Req));
 
     if (SpecFuzzyFind)
@@ -1416,23 +1502,34 @@
   }
 
   // Merges Sema and Index results where possible, to form CompletionCandidates.
+  // \p Identifiers is raw idenfiers that can also be completion condidates.
+  // Identifiers are not merged with results from index or sema.
   // Groups overloads if desired, to form CompletionCandidate::Bundles. The
   // bundles are scored and top results are returned, best to worst.
   std::vector<ScoredBundle>
   mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
-               const SymbolSlab &IndexResults) {
+               const SymbolSlab &IndexResults,
+               const std::vector<RawIdentifier> &IdentifierResults) {
     trace::Span Tracer("Merge and score results");
     std::vector<CompletionCandidate::Bundle> Bundles;
     llvm::DenseMap<size_t, size_t> BundleLookup;
     auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
-                            const Symbol *IndexResult) {
+                            const Symbol *IndexResult,
+                            const RawIdentifier *IdentifierResult) {
       CompletionCandidate C;
       C.SemaResult = SemaResult;
       C.IndexResult = IndexResult;
-      if (C.IndexResult)
+      C.IdentifierResult = IdentifierResult;
+      if (C.IndexResult) {
+        C.Name = IndexResult->Name;
         C.RankedIncludeHeaders = getRankedIncludes(*C.IndexResult);
-      C.Name = IndexResult ? IndexResult->Name : Recorder->getName(*SemaResult);
-      if (auto OverloadSet = Opts.BundleOverloads ? C.overloadSet() : 0) {
+      } else if (C.SemaResult) {
+        C.Name = Recorder->getName(*SemaResult);
+      } else {
+        assert(IdentifierResult);
+        C.Name = IdentifierResult->Name;
+      }
+      if (auto OverloadSet = C.overloadSet(Opts)) {
         auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
         if (Ret.second)
           Bundles.emplace_back();
@@ -1456,14 +1553,17 @@
       return nullptr;
     };
     // Emit all Sema results, merging them with Index results if possible.
-    for (auto &SemaResult : Recorder->Results)
-      AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult));
+    for (auto &SemaResult : SemaResults)
+      AddToBundles(&SemaResult, CorrespondingIndexResult(SemaResult), nullptr);
     // Now emit any Index-only results.
     for (const auto &IndexResult : IndexResults) {
       if (UsedIndexResults.count(&IndexResult))
         continue;
-      AddToBundles(/*SemaResult=*/nullptr, &IndexResult);
+      AddToBundles(/*SemaResult=*/nullptr, &IndexResult, nullptr);
     }
+    // Emit identifier results.
+    for (const auto &Ident : IdentifierResults)
+      AddToBundles(/*SemaResult=*/nullptr, /*IndexResult=*/nullptr, &Ident);
     // We only keep the best N results at any time, in "native" format.
     TopN<ScoredBundle, ScoredBundleGreater> Top(
         Opts.Limit == 0 ? std::numeric_limits<size_t>::max() : Opts.Limit);
@@ -1486,13 +1586,15 @@
                     CompletionCandidate::Bundle Bundle) {
     SymbolQualitySignals Quality;
     SymbolRelevanceSignals Relevance;
-    Relevance.Context = Recorder->CCContext.getKind();
+    Relevance.Context = CCContextKind;
+    Relevance.Name = Bundle.front().Name;
     Relevance.Query = SymbolRelevanceSignals::CodeComplete;
     Relevance.FileProximityMatch = FileProximity.getPointer();
     if (ScopeProximity)
       Relevance.ScopeProximityMatch = ScopeProximity.getPointer();
     if (PreferredType)
       Relevance.HadContextType = true;
+    Relevance.ContextWords = &ContextWords;
 
     auto &First = Bundle.front();
     if (auto FuzzyScore = fuzzyScore(First))
@@ -1527,6 +1629,11 @@
         }
         Origin |= SymbolOrigin::AST;
       }
+      if (Candidate.IdentifierResult) {
+        Quality.References = Candidate.IdentifierResult->References;
+        Relevance.Scope = SymbolRelevanceSignals::FileScope;
+        Origin |= SymbolOrigin::Identifier;
+      }
     }
 
     CodeCompletion::Scores Scores;
@@ -1544,7 +1651,8 @@
 
     NSema += bool(Origin & SymbolOrigin::AST);
     NIndex += FromIndex;
-    NBoth += bool(Origin & SymbolOrigin::AST) && FromIndex;
+    NSemaAndIndex += bool(Origin & SymbolOrigin::AST) && FromIndex;
+    NIdent += bool(Origin & SymbolOrigin::Identifier);
     if (Candidates.push({std::move(Bundle), Scores}))
       Incomplete = true;
   }
@@ -1556,9 +1664,9 @@
           Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
                           : nullptr;
       if (!Builder)
-        Builder.emplace(Recorder->CCSema->getASTContext(), Item, SemaCCS,
-                        QueryScopes, *Inserter, FileName,
-                        Recorder->CCContext.getKind(), Opts);
+        Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr,
+                        Item, SemaCCS, QueryScopes, *Inserter, FileName,
+                        CCContextKind, Opts);
       else
         Builder->add(Item, SemaCCS);
     }
@@ -1566,6 +1674,13 @@
   }
 };
 
+template <class T> bool isExplicitTemplateSpecialization(const NamedDecl &ND) {
+  if (const auto *TD = dyn_cast<T>(&ND))
+    if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+      return true;
+  return false;
+}
+
 } // namespace
 
 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
@@ -1588,41 +1703,44 @@
   return Result;
 }
 
-llvm::Expected<llvm::StringRef>
-speculateCompletionFilter(llvm::StringRef Content, Position Pos) {
-  auto Offset = positionToOffset(Content, Pos);
-  if (!Offset)
-    return llvm::make_error<llvm::StringError>(
-        "Failed to convert position to offset in content.",
-        llvm::inconvertibleErrorCode());
-  if (*Offset == 0)
-    return "";
+CompletionPrefix
+guessCompletionPrefix(llvm::StringRef Content, unsigned Offset) {
+  assert(Offset <= Content.size());
+  StringRef Rest = Content.take_front(Offset);
+  CompletionPrefix Result;
 
-  // Start from the character before the cursor.
-  int St = *Offset - 1;
-  // FIXME(ioeric): consider UTF characters?
-  auto IsValidIdentifierChar = [](char c) {
-    return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
-            (c >= '0' && c <= '9') || (c == '_'));
-  };
-  size_t Len = 0;
-  for (; (St >= 0) && IsValidIdentifierChar(Content[St]); --St, ++Len) {
-  }
-  if (Len > 0)
-    St++; // Shift to the first valid character.
-  return Content.substr(St, Len);
+  // Consume the unqualified name. We only handle ASCII characters.
+  // isIdentifierBody will let us match "0invalid", but we don't mind.
+  while (!Rest.empty() && isIdentifierBody(Rest.back()))
+    Rest = Rest.drop_back();
+  Result.Name = Content.slice(Rest.size(), Offset);
+
+  // Consume qualifiers.
+  while (Rest.consume_back("::") && !Rest.endswith(":")) // reject ::::
+    while (!Rest.empty() && isIdentifierBody(Rest.back()))
+      Rest = Rest.drop_back();
+  Result.Qualifier =
+      Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
+
+  return Result;
 }
 
 CodeCompleteResult
 codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
              const PreambleData *Preamble, llvm::StringRef Contents,
              Position Pos, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-             std::shared_ptr<PCHContainerOperations> PCHs,
              CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind) {
-  return CodeCompleteFlow(FileName,
-                          Preamble ? Preamble->Includes : IncludeStructure(),
-                          SpecFuzzyFind, Opts)
-      .run({FileName, Command, Preamble, Contents, Pos, VFS, PCHs});
+  auto Offset = positionToOffset(Contents, Pos);
+  if (!Offset) {
+    elog("Code completion position was invalid {0}", Offset.takeError());
+    return CodeCompleteResult();
+  }
+  auto Flow = CodeCompleteFlow(
+      FileName, Preamble ? Preamble->Includes : IncludeStructure(),
+      SpecFuzzyFind, Opts);
+  return Preamble ? std::move(Flow).run(
+                        {FileName, Command, Preamble, Contents, *Offset, VFS})
+                  : std::move(Flow).runWithoutSema(Contents, *Offset, VFS);
 }
 
 SignatureHelp signatureHelp(PathRef FileName,
@@ -1630,8 +1748,12 @@
                             const PreambleData *Preamble,
                             llvm::StringRef Contents, Position Pos,
                             llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-                            std::shared_ptr<PCHContainerOperations> PCHs,
                             const SymbolIndex *Index) {
+  auto Offset = positionToOffset(Contents, Pos);
+  if (!Offset) {
+    elog("Code completion position was invalid {0}", Offset.takeError());
+    return SignatureHelp();
+  }
   SignatureHelp Result;
   clang::CodeCompleteOptions Options;
   Options.IncludeGlobals = false;
@@ -1642,8 +1764,7 @@
   semaCodeComplete(
       llvm::make_unique<SignatureHelpCollector>(Options, Index, Result),
       Options,
-      {FileName, Command, Preamble, Contents, Pos, std::move(VFS),
-       std::move(PCHs)});
+      {FileName, Command, Preamble, Contents, *Offset, std::move(VFS)});
   return Result;
 }
 
@@ -1659,6 +1780,13 @@
     };
     return false;
   };
+  // We only complete symbol's name, which is the same as the name of the
+  // *primary* template in case of template specializations.
+  if (isExplicitTemplateSpecialization<FunctionDecl>(ND) ||
+      isExplicitTemplateSpecialization<CXXRecordDecl>(ND) ||
+      isExplicitTemplateSpecialization<VarDecl>(ND))
+    return false;
+
   if (InTopLevelScope(ND))
     return true;
 
@@ -1695,7 +1823,7 @@
   // is mainly to help LSP clients again, so that changes do not effect each
   // other.
   for (const auto &FixIt : FixIts) {
-    if (IsRangeConsecutive(FixIt.range, LSP.textEdit->range)) {
+    if (isRangeConsecutive(FixIt.range, LSP.textEdit->range)) {
       LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText;
       LSP.textEdit->range.start = FixIt.range.start;
     } else {
diff --git a/clangd/CodeComplete.h b/clangd/CodeComplete.h
index 4d32414..2dc7f22 100644
--- a/clangd/CodeComplete.h
+++ b/clangd/CodeComplete.h
@@ -1,9 +1,8 @@
 //===--- CodeComplete.h ------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -22,6 +21,8 @@
 #include "Path.h"
 #include "Protocol.h"
 #include "index/Index.h"
+#include "index/Symbol.h"
+#include "index/SymbolOrigin.h"
 #include "clang/Frontend/PrecompiledPreamble.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/CodeCompleteOptions.h"
@@ -34,7 +35,6 @@
 
 namespace clang {
 class NamedDecl;
-class PCHContainerOperations;
 namespace clangd {
 
 struct CodeCompleteOptions {
@@ -68,6 +68,11 @@
   /// If more results are available, we set CompletionList.isIncomplete.
   size_t Limit = 0;
 
+  enum IncludeInsertion {
+    IWYU,
+    NeverInsert,
+  } InsertIncludes = IncludeInsertion::IWYU;
+
   /// A visual indicator to prepend to the completion label to indicate whether
   /// completion result would trigger an #include insertion or not.
   struct IncludeInsertionIndicator {
@@ -109,6 +114,12 @@
   ///
   /// Such completions can insert scope qualifiers.
   bool AllScopes = false;
+
+  /// Whether to allow falling back to code completion without compiling files
+  /// (using identifiers in the current file and symbol indexes), when file
+  /// cannot be built (e.g. missing compile command), or the build is not ready
+  /// (e.g. preamble is still being built).
+  bool AllowFallback = false;
 };
 
 // Semi-structured representation of a code-complete suggestion for our C++ API.
@@ -196,6 +207,9 @@
   std::vector<CodeCompletion> Completions;
   bool HasMore = false;
   CodeCompletionContext::Kind Context = CodeCompletionContext::CCC_Other;
+  // Usually the source will be parsed with a real C++ parser.
+  // But heuristics may be used instead if e.g. the preamble is not ready.
+  bool RanParser = true;
 };
 raw_ostream &operator<<(raw_ostream &, const CodeCompleteResult &);
 
@@ -214,7 +228,11 @@
   std::future<SymbolSlab> Result;
 };
 
-/// Get code completions at a specified \p Pos in \p FileName.
+/// Gets code completions at a specified \p Pos in \p FileName.
+///
+/// If \p Preamble is nullptr, this runs code completion without compiling the
+/// code.
+///
 /// If \p SpecFuzzyFind is set, a speculative and asynchronous fuzzy find index
 /// request (based on cached request) will be run before parsing sema. In case
 /// the speculative result is used by code completion (e.g. speculation failed),
@@ -225,7 +243,6 @@
                                 const PreambleData *Preamble,
                                 StringRef Contents, Position Pos,
                                 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-                                std::shared_ptr<PCHContainerOperations> PCHs,
                                 CodeCompleteOptions Opts,
                                 SpeculativeFuzzyFind *SpecFuzzyFind = nullptr);
 
@@ -235,7 +252,6 @@
                             const PreambleData *Preamble, StringRef Contents,
                             Position Pos,
                             IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-                            std::shared_ptr<PCHContainerOperations> PCHs,
                             const SymbolIndex *Index);
 
 // For index-based completion, we only consider:
@@ -250,10 +266,21 @@
 // completion.
 bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx);
 
-/// Retrives a speculative code completion filter text before the cursor.
-/// Exposed for testing only.
-llvm::Expected<llvm::StringRef>
-speculateCompletionFilter(llvm::StringRef Content, Position Pos);
+// Text immediately before the completion point that should be completed.
+// This is heuristically derived from the source code, and is used when:
+//   - semantic analysis fails
+//   - semantic analysis may be slow, and we speculatively query the index
+struct CompletionPrefix {
+  // The unqualified partial name.
+  // If there is none, begin() == end() == completion position.
+  llvm::StringRef Name;
+  // The spelled scope qualifier, such as Foo::.
+  // If there is none, begin() == end() == Name.begin().
+  llvm::StringRef Qualifier;
+};
+// Heuristically parses before Offset to determine what should be completed.
+CompletionPrefix guessCompletionPrefix(llvm::StringRef Content,
+                                       unsigned Offset);
 
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/CodeCompletionStrings.cpp b/clangd/CodeCompletionStrings.cpp
index 42a8693..586be67 100644
--- a/clangd/CodeCompletionStrings.cpp
+++ b/clangd/CodeCompletionStrings.cpp
@@ -1,9 +1,8 @@
 //===--- CodeCompletionStrings.cpp -------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/CodeCompletionStrings.h b/clangd/CodeCompletionStrings.h
index bf44cbd..153e0af 100644
--- a/clangd/CodeCompletionStrings.h
+++ b/clangd/CodeCompletionStrings.h
@@ -1,9 +1,8 @@
 //===--- CodeCompletionStrings.h ---------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/Compiler.cpp b/clangd/Compiler.cpp
index c94ef75..7758e03 100644
--- a/clangd/Compiler.cpp
+++ b/clangd/Compiler.cpp
@@ -1,9 +1,8 @@
 //===--- Compiler.cpp --------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,6 +10,7 @@
 #include "Logger.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Serialization/PCHContainerOperations.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
 
@@ -40,11 +40,38 @@
   IgnoreDiagnostics::log(DiagLevel, Info);
 }
 
+std::unique_ptr<CompilerInvocation>
+buildCompilerInvocation(const ParseInputs &Inputs) {
+  std::vector<const char *> ArgStrs;
+  for (const auto &S : Inputs.CompileCommand.CommandLine)
+    ArgStrs.push_back(S.c_str());
+
+  if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
+    log("Couldn't set working directory when creating compiler invocation.");
+    // We proceed anyway, our lit-tests rely on results for non-existing working
+    // dirs.
+  }
+
+  // FIXME(ibiryukov): store diagnostics from CommandLine when we start
+  // reporting them.
+  IgnoreDiagnostics IgnoreDiagnostics;
+  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions,
+                                          &IgnoreDiagnostics, false);
+  std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine(
+      ArgStrs, CommandLineDiagsEngine, Inputs.FS);
+  if (!CI)
+    return nullptr;
+  // createInvocationFromCommandLine sets DisableFree.
+  CI->getFrontendOpts().DisableFree = false;
+  CI->getLangOpts()->CommentOpts.ParseAllComments = true;
+  return CI;
+}
+
 std::unique_ptr<CompilerInstance>
 prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI,
                         const PrecompiledPreamble *Preamble,
                         std::unique_ptr<llvm::MemoryBuffer> Buffer,
-                        std::shared_ptr<PCHContainerOperations> PCHs,
                         llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
                         DiagnosticConsumer &DiagsClient) {
   assert(VFS && "VFS is null");
@@ -61,14 +88,15 @@
         CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get());
   }
 
-  auto Clang = llvm::make_unique<CompilerInstance>(PCHs);
+  auto Clang = llvm::make_unique<CompilerInstance>(
+      std::make_shared<PCHContainerOperations>());
   Clang->setInvocation(std::move(CI));
   Clang->createDiagnostics(&DiagsClient, false);
 
   if (auto VFSWithRemapping = createVFSFromCompilerInvocation(
           Clang->getInvocation(), Clang->getDiagnostics(), VFS))
     VFS = VFSWithRemapping;
-  Clang->setVirtualFileSystem(VFS);
+  Clang->createFileManager(VFS);
 
   Clang->setTarget(TargetInfo::CreateTargetInfo(
       Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
diff --git a/clangd/Compiler.h b/clangd/Compiler.h
index 7a3c43d..c24ea35 100644
--- a/clangd/Compiler.h
+++ b/clangd/Compiler.h
@@ -1,9 +1,8 @@
 //===--- Compiler.h ----------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -16,9 +15,12 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H
 
+#include "../clang-tidy/ClangTidyOptions.h"
+#include "GlobalCompilationDatabase.h"
+#include "index/Index.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/PrecompiledPreamble.h"
+#include "clang/Tooling/CompilationDatabase.h"
 
 namespace clang {
 namespace clangd {
@@ -32,6 +34,26 @@
                         const clang::Diagnostic &Info) override;
 };
 
+// Options to run clang e.g. when parsing AST.
+struct ParseOptions {
+  tidy::ClangTidyOptions ClangTidyOpts;
+  bool SuggestMissingIncludes = false;
+};
+
+/// Information required to run clang, e.g. to parse AST or do code completion.
+struct ParseInputs {
+  tooling::CompileCommand CompileCommand;
+  IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
+  std::string Contents;
+  // Used to recover from diagnostics (e.g. find missing includes for symbol).
+  const SymbolIndex *Index = nullptr;
+  ParseOptions Opts;
+};
+
+/// Builds compiler invocation that could be used to build AST or preamble.
+std::unique_ptr<CompilerInvocation>
+buildCompilerInvocation(const ParseInputs &Inputs);
+
 /// Creates a compiler instance, configured so that:
 ///   - Contents of the parsed file are remapped to \p MainFile.
 ///   - Preamble is overriden to use PCH passed to this function. It means the
@@ -45,7 +67,6 @@
 std::unique_ptr<CompilerInstance> prepareCompilerInstance(
     std::unique_ptr<clang::CompilerInvocation>, const PrecompiledPreamble *,
     std::unique_ptr<llvm::MemoryBuffer> MainFile,
-    std::shared_ptr<PCHContainerOperations>,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem>, DiagnosticConsumer &);
 
 } // namespace clangd
diff --git a/clangd/Context.cpp b/clangd/Context.cpp
index 66654c4..8e8bba6 100644
--- a/clangd/Context.cpp
+++ b/clangd/Context.cpp
@@ -1,9 +1,8 @@
 //===--- Context.cpp ---------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Context.h b/clangd/Context.h
index 7e14f86..0bb4cbd 100644
--- a/clangd/Context.h
+++ b/clangd/Context.h
@@ -1,9 +1,8 @@
 //===--- Context.h - Mechanism for passing implicit data --------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp
index 1cd52ad..c004fa3 100644
--- a/clangd/Diagnostics.cpp
+++ b/clangd/Diagnostics.cpp
@@ -1,27 +1,59 @@
 //===--- Diagnostics.cpp -----------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "Diagnostics.h"
+#include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
 #include "Compiler.h"
 #include "Logger.h"
+#include "Protocol.h"
 #include "SourceCode.h"
+#include "clang/Basic/AllDiagnostics.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Capacity.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/Signals.h"
 #include <algorithm>
 
 namespace clang {
 namespace clangd {
-
 namespace {
 
+const char *getDiagnosticCode(unsigned ID) {
+  switch (ID) {
+#define DIAG(ENUM, CLASS, DEFAULT_MAPPING, DESC, GROPU, SFINAE, NOWERROR,      \
+             SHOWINSYSHEADER, CATEGORY)                                        \
+  case clang::diag::ENUM:                                                      \
+    return #ENUM;
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#include "clang/Basic/DiagnosticCommentKinds.inc"
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#include "clang/Basic/DiagnosticRefactoringKinds.inc"
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#include "clang/Basic/DiagnosticSerializationKinds.inc"
+#undef DIAG
+  default:
+    return nullptr;
+  }
+}
+
 bool mentionsMainFile(const Diag &D) {
   if (D.InsideMainFile)
     return true;
@@ -77,6 +109,39 @@
   return halfOpenToRange(M, R);
 }
 
+void adjustDiagFromHeader(Diag &D, const clang::Diagnostic &Info,
+                          const LangOptions &LangOpts) {
+  const SourceLocation &DiagLoc = Info.getLocation();
+  const SourceManager &SM = Info.getSourceManager();
+  SourceLocation IncludeInMainFile;
+  auto GetIncludeLoc = [&SM](SourceLocation SLoc) {
+    return SM.getIncludeLoc(SM.getFileID(SLoc));
+  };
+  for (auto IncludeLocation = GetIncludeLoc(DiagLoc); IncludeLocation.isValid();
+       IncludeLocation = GetIncludeLoc(IncludeLocation))
+    IncludeInMainFile = IncludeLocation;
+  if (IncludeInMainFile.isInvalid())
+    return;
+
+  // Update diag to point at include inside main file.
+  D.File = SM.getFileEntryForID(SM.getMainFileID())->getName().str();
+  D.Range.start = sourceLocToPosition(SM, IncludeInMainFile);
+  D.Range.end = sourceLocToPosition(
+      SM, Lexer::getLocForEndOfToken(IncludeInMainFile, 0, SM, LangOpts));
+
+  // Add a note that will point to real diagnostic.
+  const auto *FE = SM.getFileEntryForID(SM.getFileID(DiagLoc));
+  D.Notes.emplace_back();
+  Note &N = D.Notes.back();
+  N.AbsFile = FE->tryGetRealPathName();
+  N.File = FE->getName();
+  N.Message = "error occurred here";
+  N.Range = diagnosticRange(Info, LangOpts);
+
+  // Update message to mention original file.
+  D.Message = llvm::Twine("in included file: ", D.Message).str();
+}
+
 bool isInsideMainFile(const SourceLocation Loc, const SourceManager &M) {
   return Loc.isValid() && M.isWrittenInMainFile(M.getFileLoc(Loc));
 }
@@ -151,9 +216,7 @@
 }
 
 /// Returns a message sent to LSP for the main diagnostic in \p D.
-/// The message includes all the notes with their corresponding locations.
-/// However, notes with fix-its are excluded as those usually only contain a
-/// fix-it message and just add noise if included in the message for diagnostic.
+/// This message may include notes, if they're not emited in some other way.
 /// Example output:
 ///
 ///     no matching function for call to 'foo'
@@ -162,27 +225,34 @@
 ///
 ///     dir1/dir2/dir3/../../dir4/header.h:12:23
 ///     note: candidate function not viable: requires 3 arguments
-std::string mainMessage(const Diag &D) {
+std::string mainMessage(const Diag &D, const ClangdDiagnosticOptions &Opts) {
   std::string Result;
   llvm::raw_string_ostream OS(Result);
   OS << D.Message;
-  for (auto &Note : D.Notes) {
-    OS << "\n\n";
-    printDiag(OS, Note);
-  }
+  if (Opts.DisplayFixesCount && !D.Fixes.empty())
+    OS << " (" << (D.Fixes.size() > 1 ? "fixes" : "fix") << " available)";
+  // If notes aren't emitted as structured info, add them to the message.
+  if (!Opts.EmitRelatedLocations)
+    for (auto &Note : D.Notes) {
+      OS << "\n\n";
+      printDiag(OS, Note);
+    }
   OS.flush();
   return capitalize(std::move(Result));
 }
 
 /// Returns a message sent to LSP for the note of the main diagnostic.
-/// The message includes the main diagnostic to provide the necessary context
-/// for the user to understand the note.
-std::string noteMessage(const Diag &Main, const DiagBase &Note) {
+std::string noteMessage(const Diag &Main, const DiagBase &Note,
+                        const ClangdDiagnosticOptions &Opts) {
   std::string Result;
   llvm::raw_string_ostream OS(Result);
   OS << Note.Message;
-  OS << "\n\n";
-  printDiag(OS, Main);
+  // If the client doesn't support structured links between the note and the
+  // original diagnostic, then emit the main diagnostic to give context.
+  if (!Opts.EmitRelatedLocations) {
+    OS << "\n\n";
+    printDiag(OS, Main);
+  }
   OS.flush();
   return capitalize(std::move(Result));
 }
@@ -249,27 +319,54 @@
     return Res;
   };
 
-  {
-    clangd::Diagnostic Main = FillBasicFields(D);
-    Main.message = mainMessage(D);
-    if (Opts.EmbedFixesInDiagnostics) {
-      Main.codeActions.emplace();
-      for (const auto &Fix : D.Fixes)
-        Main.codeActions->push_back(toCodeAction(Fix, File));
+  clangd::Diagnostic Main = FillBasicFields(D);
+  Main.code = D.Name;
+  switch (D.Source) {
+  case Diag::Clang:
+    Main.source = "clang";
+    break;
+  case Diag::ClangTidy:
+    Main.source = "clang-tidy";
+    break;
+  case Diag::Unknown:
+    break;
+  }
+  if (Opts.EmbedFixesInDiagnostics) {
+    Main.codeActions.emplace();
+    for (const auto &Fix : D.Fixes)
+      Main.codeActions->push_back(toCodeAction(Fix, File));
+  }
+  if (Opts.SendDiagnosticCategory && !D.Category.empty())
+    Main.category = D.Category;
+
+  Main.message = mainMessage(D, Opts);
+  if (Opts.EmitRelatedLocations) {
+    Main.relatedInformation.emplace();
+    for (auto &Note : D.Notes) {
+      if (!Note.AbsFile) {
+        vlog("Dropping note from unknown file: {0}", Note);
+        continue;
+      }
+      DiagnosticRelatedInformation RelInfo;
+      RelInfo.location.range = Note.Range;
+      RelInfo.location.uri =
+          URIForFile::canonicalize(*Note.AbsFile, File.file());
+      RelInfo.message = noteMessage(D, Note, Opts);
+      Main.relatedInformation->push_back(std::move(RelInfo));
     }
-    if (Opts.SendDiagnosticCategory && !D.Category.empty())
-      Main.category = D.Category;
-
-    OutFn(std::move(Main), D.Fixes);
   }
+  OutFn(std::move(Main), D.Fixes);
 
-  for (auto &Note : D.Notes) {
-    if (!Note.InsideMainFile)
-      continue;
-    clangd::Diagnostic Res = FillBasicFields(Note);
-    Res.message = noteMessage(D, Note);
-    OutFn(std::move(Res), llvm::ArrayRef<Fix>());
-  }
+  // If we didn't emit the notes as relatedLocations, emit separate diagnostics
+  // so the user can find the locations easily.
+  if (!Opts.EmitRelatedLocations)
+    for (auto &Note : D.Notes) {
+      if (!Note.InsideMainFile)
+        continue;
+      clangd::Diagnostic Res = FillBasicFields(Note);
+      Res.message = noteMessage(D, Note, Opts);
+      OutFn(std::move(Res), llvm::ArrayRef<Fix>());
+    }
 }
 
 int getSeverity(DiagnosticsEngine::Level L) {
@@ -289,7 +386,46 @@
   llvm_unreachable("Unknown diagnostic level!");
 }
 
-std::vector<Diag> StoreDiags::take() { return std::move(Output); }
+std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) {
+  // Fill in name/source now that we have all the context needed to map them.
+  for (auto &Diag : Output) {
+    if (const char *ClangDiag = getDiagnosticCode(Diag.ID)) {
+      // Warnings controlled by -Wfoo are better recognized by that name.
+      StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(Diag.ID);
+      if (!Warning.empty()) {
+        Diag.Name = ("-W" + Warning).str();
+      } else {
+        StringRef Name(ClangDiag);
+        // Almost always an error, with a name like err_enum_class_reference.
+        // Drop the err_ prefix for brevity.
+        Name.consume_front("err_");
+        Diag.Name = Name;
+      }
+      Diag.Source = Diag::Clang;
+      continue;
+    }
+    if (Tidy != nullptr) {
+      std::string TidyDiag = Tidy->getCheckName(Diag.ID);
+      if (!TidyDiag.empty()) {
+        Diag.Name = std::move(TidyDiag);
+        Diag.Source = Diag::ClangTidy;
+        // clang-tidy bakes the name into diagnostic messages. Strip it out.
+        // It would be much nicer to make clang-tidy not do this.
+        auto CleanMessage = [&](std::string &Msg) {
+          StringRef Rest(Msg);
+          if (Rest.consume_back("]") && Rest.consume_back(Diag.Name) &&
+              Rest.consume_back(" ["))
+            Msg.resize(Rest.size());
+        };
+        CleanMessage(Diag.Message);
+        for (auto &Note : Diag.Notes)
+          CleanMessage(Note.Message);
+        continue;
+      }
+    }
+  }
+  return std::move(Output);
+}
 
 void StoreDiags::BeginSourceFile(const LangOptions &Opts,
                                  const Preprocessor *) {
@@ -319,6 +455,9 @@
     D.Message = Message.str();
     D.InsideMainFile = InsideMainFile;
     D.File = Info.getSourceManager().getFilename(Info.getLocation());
+    auto &SM = Info.getSourceManager();
+    D.AbsFile = getCanonicalPath(
+        SM.getFileEntryForID(SM.getFileID(Info.getLocation())), SM);
     D.Severity = DiagLevel;
     D.Category = DiagnosticIDs::getCategoryNameFromID(
                      DiagnosticIDs::getCategoryNumberForDiag(Info.getID()))
@@ -334,6 +473,11 @@
 
     llvm::SmallVector<TextEdit, 1> Edits;
     for (auto &FixIt : Info.getFixItHints()) {
+      // Follow clang's behavior, don't apply FixIt to the code in macros,
+      // we are less certain it is the right fix.
+      if (FixIt.RemoveRange.getBegin().isMacroID() ||
+          FixIt.RemoveRange.getEnd().isMacroID())
+        return false;
       if (!isInsideMainFile(FixIt.RemoveRange.getBegin(),
                             Info.getSourceManager()))
         return false;
@@ -371,10 +515,17 @@
     flushLastDiag();
 
     LastDiag = Diag();
+    LastDiag->ID = Info.getID();
     FillDiagBase(*LastDiag);
+    adjustDiagFromHeader(*LastDiag, Info, *LangOpts);
 
     if (!Info.getFixItHints().empty())
       AddFix(true /* try to invent a message instead of repeating the diag */);
+    if (Fixer) {
+      auto ExtraFixes = Fixer(DiagLevel, Info);
+      LastDiag->Fixes.insert(LastDiag->Fixes.end(), ExtraFixes.begin(),
+                             ExtraFixes.end());
+    }
   } else {
     // Handle a note to an existing diagnostic.
     if (!LastDiag) {
@@ -401,11 +552,15 @@
 void StoreDiags::flushLastDiag() {
   if (!LastDiag)
     return;
-  if (mentionsMainFile(*LastDiag))
+  // Only keeps diagnostics inside main file or the first one coming from a
+  // header.
+  if (mentionsMainFile(*LastDiag) ||
+      (LastDiag->Severity >= DiagnosticsEngine::Level::Error &&
+       IncludeLinesWithErrors.insert(LastDiag->Range.start.line).second)) {
     Output.push_back(std::move(*LastDiag));
-  else
-    log("Dropped diagnostic outside main file: {0}: {1}", LastDiag->File,
-        LastDiag->Message);
+  } else {
+    vlog("Dropped diagnostic: {0}: {1}", LastDiag->File, LastDiag->Message);
+  }
   LastDiag.reset();
 }
 
diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h
index 6318e88..a0ab7c6 100644
--- a/clangd/Diagnostics.h
+++ b/clangd/Diagnostics.h
@@ -1,9 +1,8 @@
 //===--- Diagnostics.h -------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,12 +14,18 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSet.h"
 #include <cassert>
 #include <string>
 
 namespace clang {
+namespace tidy {
+class ClangTidyContext;
+} // namespace tidy
 namespace clangd {
 
 struct ClangdDiagnosticOptions {
@@ -28,11 +33,20 @@
   /// diagnostics that are sent to the client.
   bool EmbedFixesInDiagnostics = false;
 
+  /// If true, Clangd uses the relatedInformation field to include other
+  /// locations (in particular attached notes).
+  /// Otherwise, these are flattened into the diagnostic message.
+  bool EmitRelatedLocations = false;
+
   /// If true, Clangd uses an LSP extension to send the diagnostic's
   /// category to the client. The category typically describes the compilation
   /// stage during which the issue was produced, e.g. "Semantic Issue" or "Parse
   /// Issue".
   bool SendDiagnosticCategory = false;
+
+  /// If true, Clangd will add a number of available fixes to the diagnostic's
+  /// message.
+  bool DisplayFixesCount = true;
 };
 
 /// Contains basic information about a diagnostic.
@@ -41,6 +55,9 @@
   // Intended to be used only in error messages.
   // May be relative, absolute or even artifically constructed.
   std::string File;
+  // Absolute path to containing file, if available.
+  llvm::Optional<std::string> AbsFile;
+
   clangd::Range Range;
   DiagnosticsEngine::Level Severity = DiagnosticsEngine::Note;
   std::string Category;
@@ -65,6 +82,14 @@
 
 /// A top-level diagnostic that may have Notes and Fixes.
 struct Diag : DiagBase {
+  unsigned ID;      // e.g. member of clang::diag, or clang-tidy assigned ID.
+  std::string Name; // if ID was recognized.
+  // The source of this diagnostic.
+  enum {
+    Unknown,
+    Clang,
+    ClangTidy,
+  } Source = Unknown;
   /// Elaborate on the problem, usually pointing to a related piece of code.
   std::vector<Note> Notes;
   /// *Alternative* fixes for this diagnostic, one should be chosen.
@@ -93,19 +118,27 @@
 /// the diag itself nor its notes are in the main file).
 class StoreDiags : public DiagnosticConsumer {
 public:
-  std::vector<Diag> take();
+  // The ClangTidyContext populates Source and Name for clang-tidy diagnostics.
+  std::vector<Diag> take(const clang::tidy::ClangTidyContext *Tidy = nullptr);
 
   void BeginSourceFile(const LangOptions &Opts, const Preprocessor *) override;
   void EndSourceFile() override;
   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                         const clang::Diagnostic &Info) override;
 
+  using DiagFixer = std::function<std::vector<Fix>(DiagnosticsEngine::Level,
+                                                   const clang::Diagnostic &)>;
+  /// If set, possibly adds fixes for diagnostics using \p Fixer.
+  void contributeFixes(DiagFixer Fixer) { this->Fixer = Fixer; }
+
 private:
   void flushLastDiag();
 
+  DiagFixer Fixer = nullptr;
   std::vector<Diag> Output;
   llvm::Optional<LangOptions> LangOpts;
   llvm::Optional<Diag> LastDiag;
+  llvm::DenseSet<int> IncludeLinesWithErrors;
 };
 
 } // namespace clangd
diff --git a/clangd/DraftStore.cpp b/clangd/DraftStore.cpp
index 9b6c1fc..16d7dde 100644
--- a/clangd/DraftStore.cpp
+++ b/clangd/DraftStore.cpp
@@ -1,9 +1,8 @@
 //===--- DraftStore.cpp - File contents container ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/DraftStore.h b/clangd/DraftStore.h
index 90a2d2c..1578ce9 100644
--- a/clangd/DraftStore.h
+++ b/clangd/DraftStore.h
@@ -1,9 +1,8 @@
 //===--- DraftStore.h - File contents container -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/ExpectedTypes.cpp b/clangd/ExpectedTypes.cpp
index 4bbf065..886b5db 100644
--- a/clangd/ExpectedTypes.cpp
+++ b/clangd/ExpectedTypes.cpp
@@ -1,3 +1,11 @@
+//===--- ExpectedTypes.cpp ---------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
 #include "ExpectedTypes.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Type.h"
@@ -35,8 +43,10 @@
 typeOfCompletion(const CodeCompletionResult &R) {
   auto *VD = dyn_cast_or_null<ValueDecl>(R.Declaration);
   if (!VD)
-    return None; // We handle only variables and functions below.
+    return llvm::None; // We handle only variables and functions below.
   auto T = VD->getType();
+  if (T.isNull())
+    return llvm::None;
   if (auto FuncT = T->getAs<FunctionType>()) {
     // Functions are a special case. They are completed as 'foo()' and we want
     // to match their return type rather than the function type itself.
diff --git a/clangd/ExpectedTypes.h b/clangd/ExpectedTypes.h
index 2f23128..36b7cce 100644
--- a/clangd/ExpectedTypes.h
+++ b/clangd/ExpectedTypes.h
@@ -1,9 +1,8 @@
 //===--- ExpectedTypes.h - Simplified C++ types -----------------*- C++-*--===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // A simplified model of C++ types that can be used to check whether they are
diff --git a/clangd/FS.cpp b/clangd/FS.cpp
index 5d690c8..aae15b5 100644
--- a/clangd/FS.cpp
+++ b/clangd/FS.cpp
@@ -1,9 +1,8 @@
 //===--- FS.cpp - File system related utils ----------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/FS.h b/clangd/FS.h
index d400304..e23b3ff 100644
--- a/clangd/FS.h
+++ b/clangd/FS.h
@@ -1,9 +1,8 @@
 //===--- FS.h - File system related utils ------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/FSProvider.cpp b/clangd/FSProvider.cpp
index 81a1ada..5d1434b 100644
--- a/clangd/FSProvider.cpp
+++ b/clangd/FSProvider.cpp
@@ -1,9 +1,8 @@
 //===--- FSProvider.cpp - VFS provider for ClangdServer -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -75,9 +74,10 @@
 // FIXME: Try to use a similar approach in Sema instead of relying on
 //        propagation of the 'isVolatile' flag through all layers.
 #ifdef _WIN32
-  return new VolatileFileSystem(llvm::vfs::getRealFileSystem());
+  return new VolatileFileSystem(
+      llvm::vfs::createPhysicalFileSystem().release());
 #else
-  return llvm::vfs::getRealFileSystem();
+  return llvm::vfs::createPhysicalFileSystem().release();
 #endif
 }
 } // namespace clangd
diff --git a/clangd/FSProvider.h b/clangd/FSProvider.h
index 67d2ec1..2295789 100644
--- a/clangd/FSProvider.h
+++ b/clangd/FSProvider.h
@@ -1,9 +1,8 @@
 //===--- FSProvider.h - VFS provider for ClangdServer ------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/FileDistance.cpp b/clangd/FileDistance.cpp
index 7bac251..a6a65ab 100644
--- a/clangd/FileDistance.cpp
+++ b/clangd/FileDistance.cpp
@@ -1,9 +1,8 @@
 //===--- FileDistance.cpp - File contents container -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/FileDistance.h b/clangd/FileDistance.h
index 2623ce7..e7174bc 100644
--- a/clangd/FileDistance.h
+++ b/clangd/FileDistance.h
@@ -1,9 +1,8 @@
 //===--- FileDistance.h - File proximity scoring -----------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/FindSymbols.cpp b/clangd/FindSymbols.cpp
index 208e78c..b2bd166 100644
--- a/clangd/FindSymbols.cpp
+++ b/clangd/FindSymbols.cpp
@@ -1,9 +1,8 @@
 //===--- FindSymbols.cpp ------------------------------------*- C++-*------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "FindSymbols.h"
@@ -27,67 +26,8 @@
 
 namespace clang {
 namespace clangd {
+
 namespace {
-
-// Convert a index::SymbolKind to clangd::SymbolKind (LSP)
-// Note, some are not perfect matches and should be improved when this LSP
-// issue is addressed:
-// https://github.com/Microsoft/language-server-protocol/issues/344
-SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) {
-  switch (Kind) {
-  case index::SymbolKind::Unknown:
-    return SymbolKind::Variable;
-  case index::SymbolKind::Module:
-    return SymbolKind::Module;
-  case index::SymbolKind::Namespace:
-    return SymbolKind::Namespace;
-  case index::SymbolKind::NamespaceAlias:
-    return SymbolKind::Namespace;
-  case index::SymbolKind::Macro:
-    return SymbolKind::String;
-  case index::SymbolKind::Enum:
-    return SymbolKind::Enum;
-  case index::SymbolKind::Struct:
-    return SymbolKind::Struct;
-  case index::SymbolKind::Class:
-    return SymbolKind::Class;
-  case index::SymbolKind::Protocol:
-    return SymbolKind::Interface;
-  case index::SymbolKind::Extension:
-    return SymbolKind::Interface;
-  case index::SymbolKind::Union:
-    return SymbolKind::Class;
-  case index::SymbolKind::TypeAlias:
-    return SymbolKind::Class;
-  case index::SymbolKind::Function:
-    return SymbolKind::Function;
-  case index::SymbolKind::Variable:
-    return SymbolKind::Variable;
-  case index::SymbolKind::Field:
-    return SymbolKind::Field;
-  case index::SymbolKind::EnumConstant:
-    return SymbolKind::EnumMember;
-  case index::SymbolKind::InstanceMethod:
-  case index::SymbolKind::ClassMethod:
-  case index::SymbolKind::StaticMethod:
-    return SymbolKind::Method;
-  case index::SymbolKind::InstanceProperty:
-  case index::SymbolKind::ClassProperty:
-  case index::SymbolKind::StaticProperty:
-    return SymbolKind::Property;
-  case index::SymbolKind::Constructor:
-  case index::SymbolKind::Destructor:
-    return SymbolKind::Method;
-  case index::SymbolKind::ConversionFunction:
-    return SymbolKind::Function;
-  case index::SymbolKind::Parameter:
-    return SymbolKind::Variable;
-  case index::SymbolKind::Using:
-    return SymbolKind::Namespace;
-  }
-  llvm_unreachable("invalid symbol kind");
-}
-
 using ScoredSymbolInfo = std::pair<float, SymbolInformation>;
 struct ScoredSymbolGreater {
   bool operator()(const ScoredSymbolInfo &L, const ScoredSymbolInfo &R) {
@@ -154,11 +94,13 @@
     std::string Scope = Sym.Scope;
     llvm::StringRef ScopeRef = Scope;
     ScopeRef.consume_back("::");
-    SymbolInformation Info = {Sym.Name, SK, L, ScopeRef};
+    SymbolInformation Info = {(Sym.Name + Sym.TemplateSpecializationArgs).str(),
+                              SK, L, ScopeRef};
 
     SymbolQualitySignals Quality;
     Quality.merge(Sym);
     SymbolRelevanceSignals Relevance;
+    Relevance.Name = Sym.Name;
     Relevance.Query = SymbolRelevanceSignals::Generic;
     if (auto NameMatch = Filter.match(Sym.Name))
       Relevance.NameMatch = *NameMatch;
diff --git a/clangd/FindSymbols.h b/clangd/FindSymbols.h
index a9c8c99..e4980c9 100644
--- a/clangd/FindSymbols.h
+++ b/clangd/FindSymbols.h
@@ -1,9 +1,8 @@
 //===--- FindSymbols.h --------------------------------------*- C++-*------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -22,9 +21,10 @@
 class SymbolIndex;
 
 /// Searches for the symbols matching \p Query. The syntax of \p Query can be
-/// the non-qualified name or fully qualified of a symbol. For example, "vector"
-/// will match the symbol std::vector and "std::vector" would also match it.
-/// Direct children of scopes (namepaces, etc) can be listed with a trailing
+/// the non-qualified name or fully qualified of a symbol. For example,
+/// "vector" will match the symbol std::vector and "std::vector" would also
+/// match it. Direct children of scopes (namepaces, etc) can be listed with a
+/// trailing
 /// "::". For example, "std::" will list all children of the std namespace and
 /// "::" alone will list all children of the global namespace.
 /// \p Limit limits the number of results returned (0 means no limit).
diff --git a/clangd/Function.h b/clangd/Function.h
index c91b9cb..6d91136 100644
--- a/clangd/Function.h
+++ b/clangd/Function.h
@@ -1,9 +1,8 @@
 //===--- Function.h - Utility callable wrappers  -----------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/FuzzyMatch.cpp b/clangd/FuzzyMatch.cpp
index 433242e..57f9554 100644
--- a/clangd/FuzzyMatch.cpp
+++ b/clangd/FuzzyMatch.cpp
@@ -1,9 +1,8 @@
 //===--- FuzzyMatch.h - Approximate identifier matching  ---------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -72,7 +71,7 @@
 // Score field is 15 bits wide, min value is -2^14, we use half of that.
 static constexpr int AwfulScore = -(1 << 13);
 static bool isAwful(int S) { return S < AwfulScore / 2; }
-static constexpr int PerfectBonus = 3; // Perfect per-pattern-char score.
+static constexpr int PerfectBonus = 4; // Perfect per-pattern-char score.
 
 FuzzyMatcher::FuzzyMatcher(llvm::StringRef Pattern)
     : PatN(std::min<int>(MaxPat, Pattern.size())),
@@ -268,24 +267,31 @@
 }
 
 int FuzzyMatcher::skipPenalty(int W, Action Last) const {
-  int S = 0;
+  if (W == 0) // Skipping the first character.
+    return 3;
   if (WordRole[W] == Head) // Skipping a segment.
-    S += 1;
-  if (Last == Match) // Non-consecutive match.
-    S += 2;          // We'd rather skip a segment than split our match.
-  return S;
+    return 1; // We want to keep this lower than a consecutive match bonus.
+  // Instead of penalizing non-consecutive matches, we give a bonus to a
+  // consecutive match in matchBonus. This produces a better score distribution
+  // than penalties in case of small patterns, e.g. 'up' for 'unique_ptr'.
+  return 0;
 }
 
 int FuzzyMatcher::matchBonus(int P, int W, Action Last) const {
   assert(LowPat[P] == LowWord[W]);
   int S = 1;
-  // Bonus: pattern so far is a (case-insensitive) prefix of the word.
-  if (P == W) // We can't skip pattern characters, so we must have matched all.
-    ++S;
+  bool IsPatSingleCase =
+      (PatTypeSet == 1 << Lower) || (PatTypeSet == 1 << Upper);
   // Bonus: case matches, or a Head in the pattern aligns with one in the word.
-  if ((Pat[P] == Word[W] && ((PatTypeSet & 1 << Upper) || P == W)) ||
-      (PatRole[P] == Head && WordRole[W] == Head))
+  // Single-case patterns lack segmentation signals and we assume any character
+  // can be a head of a segment.
+  if (Pat[P] == Word[W] ||
+      (WordRole[W] == Head && (IsPatSingleCase || PatRole[P] == Head)))
     ++S;
+  // Bonus: a consecutive match. First character match also gets a bonus to
+  // ensure prefix final match score normalizes to 1.0.
+  if (W == 0 || Last == Match)
+    S += 2;
   // Penalty: matching inside a segment (and previous char wasn't matched).
   if (WordRole[W] == Tail && P && Last == Miss)
     S -= 3;
diff --git a/clangd/FuzzyMatch.h b/clangd/FuzzyMatch.h
index f0c7e72..81c2edb 100644
--- a/clangd/FuzzyMatch.h
+++ b/clangd/FuzzyMatch.h
@@ -1,9 +1,8 @@
 //===--- FuzzyMatch.h - Approximate identifier matching  ---------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/GlobalCompilationDatabase.cpp b/clangd/GlobalCompilationDatabase.cpp
index c2fff7b..50f5408 100644
--- a/clangd/GlobalCompilationDatabase.cpp
+++ b/clangd/GlobalCompilationDatabase.cpp
@@ -1,20 +1,49 @@
 //===--- GlobalCompilationDatabase.cpp ---------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "GlobalCompilationDatabase.h"
 #include "Logger.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
 namespace clang {
 namespace clangd {
+namespace {
+
+void adjustArguments(tooling::CompileCommand &Cmd,
+                     llvm::StringRef ResourceDir) {
+  tooling::ArgumentsAdjuster ArgsAdjuster = tooling::combineAdjusters(
+      // clangd should not write files to disk, including dependency files
+      // requested on the command line.
+      tooling::getClangStripDependencyFileAdjuster(),
+      // Strip plugin related command line arguments. Clangd does
+      // not support plugins currently. Therefore it breaks if
+      // compiler tries to load plugins.
+      tooling::combineAdjusters(tooling::getStripPluginsAdjuster(),
+                                tooling::getClangSyntaxOnlyAdjuster()));
+
+  Cmd.CommandLine = ArgsAdjuster(Cmd.CommandLine, Cmd.Filename);
+  // Inject the resource dir.
+  // FIXME: Don't overwrite it if it's already there.
+  if (!ResourceDir.empty())
+    Cmd.CommandLine.push_back(("-resource-dir=" + ResourceDir).str());
+}
+
+std::string getStandardResourceDir() {
+  static int Dummy; // Just an address in this process.
+  return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy);
+}
+
+} // namespace
 
 static std::string getFallbackClangPath() {
   static int Dummy;
@@ -34,10 +63,11 @@
   if (llvm::sys::path::extension(File) == ".h")
     Argv.push_back("-xobjective-c++-header");
   Argv.push_back(File);
-  return tooling::CompileCommand(llvm::sys::path::parent_path(File),
-                                 llvm::sys::path::filename(File),
-                                 std::move(Argv),
-                                 /*Output=*/"");
+  tooling::CompileCommand Cmd(llvm::sys::path::parent_path(File),
+                              llvm::sys::path::filename(File), std::move(Argv),
+                              /*Output=*/"");
+  Cmd.Heuristic = "clangd fallback";
+  return Cmd;
 }
 
 DirectoryBasedGlobalCompilationDatabase::
@@ -106,8 +136,11 @@
 }
 
 OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
-                       std::vector<std::string> FallbackFlags)
-    : Base(Base), FallbackFlags(std::move(FallbackFlags)) {
+                       std::vector<std::string> FallbackFlags,
+                       llvm::Optional<std::string> ResourceDir)
+    : Base(Base), ResourceDir(ResourceDir ? std::move(*ResourceDir)
+                                          : getStandardResourceDir()),
+      FallbackFlags(std::move(FallbackFlags)) {
   if (Base)
     BaseChanged = Base->watch([this](const std::vector<std::string> Changes) {
       OnCommandChanged.broadcast(Changes);
@@ -116,16 +149,22 @@
 
 llvm::Optional<tooling::CompileCommand>
 OverlayCDB::getCompileCommand(PathRef File, ProjectInfo *Project) const {
+  llvm::Optional<tooling::CompileCommand> Cmd;
   {
     std::lock_guard<std::mutex> Lock(Mutex);
     auto It = Commands.find(File);
     if (It != Commands.end()) {
       if (Project)
         Project->SourceRoot = "";
-      return It->second;
+      Cmd = It->second;
     }
   }
-  return Base ? Base->getCompileCommand(File, Project) : None;
+  if (!Cmd && Base)
+    Cmd = Base->getCompileCommand(File, Project);
+  if (!Cmd)
+    return llvm::None;
+  adjustArguments(*Cmd, ResourceDir);
+  return Cmd;
 }
 
 tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
diff --git a/clangd/GlobalCompilationDatabase.h b/clangd/GlobalCompilationDatabase.h
index 181b178..0a97a30 100644
--- a/clangd/GlobalCompilationDatabase.h
+++ b/clangd/GlobalCompilationDatabase.h
@@ -1,9 +1,8 @@
 //===--- GlobalCompilationDatabase.h -----------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 
 #include "Function.h"
 #include "Path.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
 #include <memory>
 #include <mutex>
@@ -98,7 +98,8 @@
   // Base may be null, in which case no entries are inherited.
   // FallbackFlags are added to the fallback compile command.
   OverlayCDB(const GlobalCompilationDatabase *Base,
-             std::vector<std::string> FallbackFlags = {});
+             std::vector<std::string> FallbackFlags = {},
+             llvm::Optional<std::string> ResourceDir = llvm::None);
 
   llvm::Optional<tooling::CompileCommand>
   getCompileCommand(PathRef File, ProjectInfo * = nullptr) const override;
@@ -113,6 +114,7 @@
   mutable std::mutex Mutex;
   llvm::StringMap<tooling::CompileCommand> Commands; /* GUARDED_BY(Mut) */
   const GlobalCompilationDatabase *Base;
+  std::string ResourceDir;
   std::vector<std::string> FallbackFlags;
   CommandChanged::Subscription BaseChanged;
 };
diff --git a/clangd/Headers.cpp b/clangd/Headers.cpp
index 06f822b..8d20971 100644
--- a/clangd/Headers.cpp
+++ b/clangd/Headers.cpp
@@ -1,9 +1,8 @@
 //===--- Headers.cpp - Include headers ---------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -74,6 +73,41 @@
          (!Verbatim && llvm::sys::path::is_absolute(File));
 }
 
+llvm::Expected<HeaderFile> toHeaderFile(llvm::StringRef Header,
+                                        llvm::StringRef HintPath) {
+  if (isLiteralInclude(Header))
+    return HeaderFile{Header.str(), /*Verbatim=*/true};
+  auto U = URI::parse(Header);
+  if (!U)
+    return U.takeError();
+
+  auto IncludePath = URI::includeSpelling(*U);
+  if (!IncludePath)
+    return IncludePath.takeError();
+  if (!IncludePath->empty())
+    return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true};
+
+  auto Resolved = URI::resolve(*U, HintPath);
+  if (!Resolved)
+    return Resolved.takeError();
+  return HeaderFile{std::move(*Resolved), /*Verbatim=*/false};
+}
+
+llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym) {
+  auto Includes = Sym.IncludeHeaders;
+  // Sort in descending order by reference count and header length.
+  llvm::sort(Includes, [](const Symbol::IncludeHeaderWithReferences &LHS,
+                          const Symbol::IncludeHeaderWithReferences &RHS) {
+    if (LHS.References == RHS.References)
+      return LHS.IncludeHeader.size() < RHS.IncludeHeader.size();
+    return LHS.References > RHS.References;
+  });
+  llvm::SmallVector<llvm::StringRef, 1> Headers;
+  for (const auto &Include : Includes)
+    Headers.push_back(Include.IncludeHeader);
+  return Headers;
+}
+
 std::unique_ptr<PPCallbacks>
 collectIncludeStructureCallback(const SourceManager &SM,
                                 IncludeStructure *Out) {
@@ -139,24 +173,27 @@
 /// FIXME(ioeric): we might not want to insert an absolute include path if the
 /// path is not shortened.
 bool IncludeInserter::shouldInsertInclude(
-    const HeaderFile &DeclaringHeader, const HeaderFile &InsertedHeader) const {
-  assert(DeclaringHeader.valid() && InsertedHeader.valid());
-  if (FileName == DeclaringHeader.File || FileName == InsertedHeader.File)
+    PathRef DeclaringHeader, const HeaderFile &InsertedHeader) const {
+  assert(InsertedHeader.valid());
+  if (!HeaderSearchInfo && !InsertedHeader.Verbatim)
+    return false;
+  if (FileName == DeclaringHeader || FileName == InsertedHeader.File)
     return false;
   auto Included = [&](llvm::StringRef Header) {
     return IncludedHeaders.find(Header) != IncludedHeaders.end();
   };
-  return !Included(DeclaringHeader.File) && !Included(InsertedHeader.File);
+  return !Included(DeclaringHeader) && !Included(InsertedHeader.File);
 }
 
 std::string
-IncludeInserter::calculateIncludePath(const HeaderFile &DeclaringHeader,
-                                      const HeaderFile &InsertedHeader) const {
-  assert(DeclaringHeader.valid() && InsertedHeader.valid());
+IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader) const {
+  assert(InsertedHeader.valid());
   if (InsertedHeader.Verbatim)
     return InsertedHeader.File;
   bool IsSystem = false;
-  std::string Suggested = HeaderSearchInfo.suggestPathToFileForDiagnostics(
+  if (!HeaderSearchInfo)
+    return "\"" + InsertedHeader.File + "\"";
+  std::string Suggested = HeaderSearchInfo->suggestPathToFileForDiagnostics(
       InsertedHeader.File, BuildDir, &IsSystem);
   if (IsSystem)
     Suggested = "<" + Suggested + ">";
diff --git a/clangd/Headers.h b/clangd/Headers.h
index 6f0eb80..f2eaf08 100644
--- a/clangd/Headers.h
+++ b/clangd/Headers.h
@@ -1,9 +1,8 @@
 //===--- Headers.h - Include headers -----------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,10 +12,12 @@
 #include "Path.h"
 #include "Protocol.h"
 #include "SourceCode.h"
+#include "index/Symbol.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Tooling/Inclusions/HeaderIncludes.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
@@ -38,6 +39,15 @@
   bool valid() const;
 };
 
+/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal
+/// include.
+llvm::Expected<HeaderFile> toHeaderFile(llvm::StringRef Header,
+                                        llvm::StringRef HintPath);
+
+// Returns include headers for \p Sym sorted by popularity. If two headers are
+// equally popular, prefer the shorter one.
+llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym);
+
 // An #include directive that we found in the main file.
 struct Inclusion {
   Range R;             // Inclusion range.
@@ -109,9 +119,12 @@
 // Calculates insertion edit for including a new header in a file.
 class IncludeInserter {
 public:
+  // If \p HeaderSearchInfo is nullptr (e.g. when compile command is
+  // infeasible), this will only try to insert verbatim headers, and
+  // include path of non-verbatim header will not be shortened.
   IncludeInserter(StringRef FileName, StringRef Code,
                   const format::FormatStyle &Style, StringRef BuildDir,
-                  HeaderSearch &HeaderSearchInfo)
+                  HeaderSearch *HeaderSearchInfo)
       : FileName(FileName), Code(Code), BuildDir(BuildDir),
         HeaderSearchInfo(HeaderSearchInfo),
         Inserter(FileName, Code, Style.IncludeStyle) {}
@@ -124,25 +137,22 @@
   ///   in \p Inclusions (including those included via different paths).
   ///   - \p DeclaringHeader or \p InsertedHeader is the same as \p File.
   ///
-  /// \param DeclaringHeader is the original header corresponding to \p
+  /// \param DeclaringHeader is path of the original header corresponding to \p
   /// InsertedHeader e.g. the header that declares a symbol.
   /// \param InsertedHeader The preferred header to be inserted. This could be
   /// the same as DeclaringHeader but must be provided.
-  bool shouldInsertInclude(const HeaderFile &DeclaringHeader,
+  bool shouldInsertInclude(PathRef DeclaringHeader,
                            const HeaderFile &InsertedHeader) const;
 
   /// Determines the preferred way to #include a file, taking into account the
   /// search path. Usually this will prefer a shorter representation like
   /// 'Foo/Bar.h' over a longer one like 'Baz/include/Foo/Bar.h'.
   ///
-  /// \param DeclaringHeader is the original header corresponding to \p
-  /// InsertedHeader e.g. the header that declares a symbol.
   /// \param InsertedHeader The preferred header to be inserted. This could be
   /// the same as DeclaringHeader but must be provided.
   ///
   /// \return A quoted "path" or <path> to be included.
-  std::string calculateIncludePath(const HeaderFile &DeclaringHeader,
-                                   const HeaderFile &InsertedHeader) const;
+  std::string calculateIncludePath(const HeaderFile &InsertedHeader) const;
 
   /// Calculates an edit that inserts \p VerbatimHeader into code. If the header
   /// is already included, this returns None.
@@ -152,7 +162,7 @@
   StringRef FileName;
   StringRef Code;
   StringRef BuildDir;
-  HeaderSearch &HeaderSearchInfo;
+  HeaderSearch *HeaderSearchInfo = nullptr;
   llvm::StringSet<> IncludedHeaders; // Both written and resolved.
   tooling::HeaderIncludes Inserter;  // Computers insertion replacement.
 };
diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp
new file mode 100644
index 0000000..f58ddba
--- /dev/null
+++ b/clangd/IncludeFixer.cpp
@@ -0,0 +1,454 @@
+//===--- IncludeFixer.cpp ----------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "IncludeFixer.h"
+#include "AST.h"
+#include "Diagnostics.h"
+#include "Logger.h"
+#include "SourceCode.h"
+#include "Trace.h"
+#include "index/Index.h"
+#include "index/Symbol.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/TypoCorrection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+#include <vector>
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+// Collects contexts visited during a Sema name lookup.
+class VisitedContextCollector : public VisibleDeclConsumer {
+public:
+  void EnteredContext(DeclContext *Ctx) override { Visited.push_back(Ctx); }
+
+  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+                 bool InBaseClass) override {}
+
+  std::vector<DeclContext *> takeVisitedContexts() {
+    return std::move(Visited);
+  }
+
+private:
+  std::vector<DeclContext *> Visited;
+};
+
+} // namespace
+
+std::vector<Fix> IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel,
+                                   const clang::Diagnostic &Info) const {
+  switch (Info.getID()) {
+  case diag::err_incomplete_type:
+  case diag::err_incomplete_member_access:
+  case diag::err_incomplete_base_class:
+  case diag::err_incomplete_nested_name_spec:
+    // Incomplete type diagnostics should have a QualType argument for the
+    // incomplete type.
+    for (unsigned Idx = 0; Idx < Info.getNumArgs(); ++Idx) {
+      if (Info.getArgKind(Idx) == DiagnosticsEngine::ak_qualtype) {
+        auto QT = QualType::getFromOpaquePtr((void *)Info.getRawArg(Idx));
+        if (const Type *T = QT.getTypePtrOrNull())
+          if (T->isIncompleteType())
+            return fixIncompleteType(*T);
+      }
+    }
+    break;
+  case diag::err_unknown_typename:
+  case diag::err_unknown_typename_suggest:
+  case diag::err_typename_nested_not_found:
+  case diag::err_no_template:
+  case diag::err_no_template_suggest:
+  case diag::err_undeclared_use:
+  case diag::err_undeclared_use_suggest:
+  case diag::err_undeclared_var_use:
+  case diag::err_undeclared_var_use_suggest:
+  case diag::err_no_member: // Could be no member in namespace.
+  case diag::err_no_member_suggest:
+    if (LastUnresolvedName) {
+      // Try to fix unresolved name caused by missing declaraion.
+      // E.g.
+      //   clang::SourceManager SM;
+      //          ~~~~~~~~~~~~~
+      //          UnresolvedName
+      //   or
+      //   namespace clang {  SourceManager SM; }
+      //                      ~~~~~~~~~~~~~
+      //                      UnresolvedName
+      // We only attempt to recover a diagnostic if it has the same location as
+      // the last seen unresolved name.
+      if (DiagLevel >= DiagnosticsEngine::Error &&
+          LastUnresolvedName->Loc == Info.getLocation())
+        return fixUnresolvedName();
+    }
+  }
+  return {};
+}
+
+std::vector<Fix> IncludeFixer::fixIncompleteType(const Type &T) const {
+  // Only handle incomplete TagDecl type.
+  const TagDecl *TD = T.getAsTagDecl();
+  if (!TD)
+    return {};
+  std::string TypeName = printQualifiedName(*TD);
+  trace::Span Tracer("Fix include for incomplete type");
+  SPAN_ATTACH(Tracer, "type", TypeName);
+  vlog("Trying to fix include for incomplete type {0}", TypeName);
+
+  auto ID = getSymbolID(TD);
+  if (!ID)
+    return {};
+  llvm::Optional<const SymbolSlab *> Symbols = lookupCached(*ID);
+  if (!Symbols)
+    return {};
+  const SymbolSlab &Syms = **Symbols;
+  std::vector<Fix> Fixes;
+  if (!Syms.empty()) {
+    auto &Matched = *Syms.begin();
+    if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
+        Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
+      Fixes = fixesForSymbols(Syms);
+  }
+  return Fixes;
+}
+
+std::vector<Fix> IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const {
+  auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header)
+      -> llvm::Expected<std::pair<std::string, bool>> {
+    auto DeclaringURI = URI::parse(Sym.CanonicalDeclaration.FileURI);
+    if (!DeclaringURI)
+      return DeclaringURI.takeError();
+    auto ResolvedDeclaring = URI::resolve(*DeclaringURI, File);
+    if (!ResolvedDeclaring)
+      return ResolvedDeclaring.takeError();
+    auto ResolvedInserted = toHeaderFile(Header, File);
+    if (!ResolvedInserted)
+      return ResolvedInserted.takeError();
+    return std::make_pair(
+        Inserter->calculateIncludePath(*ResolvedInserted),
+        Inserter->shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
+  };
+
+  std::vector<Fix> Fixes;
+  // Deduplicate fixes by include headers. This doesn't distiguish symbols in
+  // different scopes from the same header, but this case should be rare and is
+  // thus ignored.
+  llvm::StringSet<> InsertedHeaders;
+  for (const auto &Sym : Syms) {
+    for (const auto &Inc : getRankedIncludes(Sym)) {
+      if (auto ToInclude = Inserted(Sym, Inc)) {
+        if (ToInclude->second) {
+          auto I = InsertedHeaders.try_emplace(ToInclude->first);
+          if (!I.second)
+            continue;
+          if (auto Edit = Inserter->insert(ToInclude->first))
+            Fixes.push_back(
+                Fix{llvm::formatv("Add include {0} for symbol {1}{2}",
+                                  ToInclude->first, Sym.Scope, Sym.Name),
+                    {std::move(*Edit)}});
+        }
+      } else {
+        vlog("Failed to calculate include insertion for {0} into {1}: {2}", Inc,
+             File, ToInclude.takeError());
+      }
+    }
+  }
+  return Fixes;
+}
+
+// Returns the identifiers qualified by an unresolved name. \p Loc is the
+// start location of the unresolved name. For the example below, this returns
+// "::X::Y" that is qualified by unresolved name "clangd":
+//     clang::clangd::X::Y
+//            ~
+llvm::Optional<std::string> qualifiedByUnresolved(const SourceManager &SM,
+                                                  SourceLocation Loc,
+                                                  const LangOptions &LangOpts) {
+  std::string Result;
+
+  SourceLocation NextLoc = Loc;
+  while (auto CCTok = Lexer::findNextToken(NextLoc, SM, LangOpts)) {
+    if (!CCTok->is(tok::coloncolon))
+      break;
+    auto IDTok = Lexer::findNextToken(CCTok->getLocation(), SM, LangOpts);
+    if (!IDTok || !IDTok->is(tok::raw_identifier))
+      break;
+    Result.append(("::" + IDTok->getRawIdentifier()).str());
+    NextLoc = IDTok->getLocation();
+  }
+  if (Result.empty())
+    return llvm::None;
+  return Result;
+}
+
+// An unresolved name and its scope information that can be extracted cheaply.
+struct CheapUnresolvedName {
+  std::string Name;
+  // This is the part of what was typed that was resolved, and it's in its
+  // resolved form not its typed form (think `namespace clang { clangd::x }` -->
+  // `clang::clangd::`).
+  llvm::Optional<std::string> ResolvedScope;
+
+  // Unresolved part of the scope. When the unresolved name is a specifier, we
+  // use the name that comes after it as the alternative name to resolve and use
+  // the specifier as the extra scope in the accessible scopes.
+  llvm::Optional<std::string> UnresolvedScope;
+};
+
+// Extracts unresolved name and scope information around \p Unresolved.
+// FIXME: try to merge this with the scope-wrangling code in CodeComplete.
+llvm::Optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
+    const SourceManager &SM, const DeclarationNameInfo &Unresolved,
+    CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
+  bool Invalid = false;
+  llvm::StringRef Code = SM.getBufferData(
+      SM.getDecomposedLoc(Unresolved.getBeginLoc()).first, &Invalid);
+  if (Invalid)
+    return llvm::None;
+  CheapUnresolvedName Result;
+  Result.Name = Unresolved.getAsString();
+  if (SS && SS->isNotEmpty()) { // "::" or "ns::"
+    if (auto *Nested = SS->getScopeRep()) {
+      if (Nested->getKind() == NestedNameSpecifier::Global)
+        Result.ResolvedScope = "";
+      else if (const auto *NS = Nested->getAsNamespace()) {
+        auto SpecifiedNS = printNamespaceScope(*NS);
+
+        // Check the specifier spelled in the source.
+        // If the resolved scope doesn't end with the spelled scope. The
+        // resolved scope can come from a sema typo correction. For example,
+        // sema assumes that "clangd::" is a typo of "clang::" and uses
+        // "clang::" as the specified scope in:
+        //     namespace clang { clangd::X; }
+        // In this case, we use the "typo" specifier as extra scope instead
+        // of using the scope assumed by sema.
+        auto B = SM.getFileOffset(SS->getBeginLoc());
+        auto E = SM.getFileOffset(SS->getEndLoc());
+        std::string Spelling = (Code.substr(B, E - B) + "::").str();
+        if (llvm::StringRef(SpecifiedNS).endswith(Spelling))
+          Result.ResolvedScope = SpecifiedNS;
+        else
+          Result.UnresolvedScope = Spelling;
+      } else if (const auto *ANS = Nested->getAsNamespaceAlias()) {
+        Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace());
+      } else {
+        // We don't fix symbols in scopes that are not top-level e.g. class
+        // members, as we don't collect includes for them.
+        return llvm::None;
+      }
+    }
+  }
+
+  if (UnresolvedIsSpecifier) {
+    // If the unresolved name is a specifier e.g.
+    //      clang::clangd::X
+    //             ~~~~~~
+    // We try to resolve clang::clangd::X instead of clang::clangd.
+    // FIXME: We won't be able to fix include if the specifier is what we
+    // should resolve (e.g. it's a class scope specifier). Collecting include
+    // headers for nested types could make this work.
+
+    // Not using the end location as it doesn't always point to the end of
+    // identifier.
+    if (auto QualifiedByUnresolved =
+            qualifiedByUnresolved(SM, Unresolved.getBeginLoc(), LangOpts)) {
+      auto Split = splitQualifiedName(*QualifiedByUnresolved);
+      if (!Result.UnresolvedScope)
+        Result.UnresolvedScope.emplace();
+      // If UnresolvedSpecifiedScope is already set, we simply append the
+      // extra scope. Suppose the unresolved name is "index" in the following
+      // example:
+      //   namespace clang {  clangd::index::X; }
+      //                      ~~~~~~  ~~~~~
+      // "clangd::" is assumed to be clang:: by Sema, and we would have used
+      // it as extra scope. With "index" being a specifier, we append "index::"
+      // to the extra scope.
+      Result.UnresolvedScope->append((Result.Name + Split.first).str());
+      Result.Name = Split.second;
+    }
+  }
+  return Result;
+}
+
+class IncludeFixer::UnresolvedNameRecorder : public ExternalSemaSource {
+public:
+  UnresolvedNameRecorder(llvm::Optional<UnresolvedName> &LastUnresolvedName)
+      : LastUnresolvedName(LastUnresolvedName) {}
+
+  void InitializeSema(Sema &S) override { this->SemaPtr = &S; }
+
+  // Captures the latest typo and treat it as an unresolved name that can
+  // potentially be fixed by adding #includes.
+  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind,
+                             Scope *S, CXXScopeSpec *SS,
+                             CorrectionCandidateCallback &CCC,
+                             DeclContext *MemberContext, bool EnteringContext,
+                             const ObjCObjectPointerType *OPT) override {
+    assert(SemaPtr && "Sema must have been set.");
+    if (SemaPtr->isSFINAEContext())
+      return TypoCorrection();
+    if (!SemaPtr->SourceMgr.isWrittenInMainFile(Typo.getLoc()))
+      return clang::TypoCorrection();
+
+    // This is not done lazily because `SS` can get out of scope and it's
+    // relatively cheap.
+    auto Extracted = extractUnresolvedNameCheaply(
+        SemaPtr->SourceMgr, Typo, SS, SemaPtr->LangOpts,
+        static_cast<Sema::LookupNameKind>(LookupKind) ==
+            Sema::LookupNameKind::LookupNestedNameSpecifierName);
+    if (!Extracted)
+      return TypoCorrection();
+    auto CheapUnresolved = std::move(*Extracted);
+    UnresolvedName Unresolved;
+    Unresolved.Name = CheapUnresolved.Name;
+    Unresolved.Loc = Typo.getBeginLoc();
+
+    if (!CheapUnresolved.ResolvedScope && !S) // Give up if no scope available.
+      return TypoCorrection();
+
+    auto *Sem = SemaPtr; // Avoid capturing `this`.
+    Unresolved.GetScopes = [Sem, CheapUnresolved, S, LookupKind]() {
+      std::vector<std::string> Scopes;
+      if (CheapUnresolved.ResolvedScope) {
+        Scopes.push_back(*CheapUnresolved.ResolvedScope);
+      } else {
+        assert(S);
+        // No scope specifier is specified. Collect all accessible scopes in the
+        // context.
+        VisitedContextCollector Collector;
+        Sem->LookupVisibleDecls(
+            S, static_cast<Sema::LookupNameKind>(LookupKind), Collector,
+            /*IncludeGlobalScope=*/false,
+            /*LoadExternal=*/false);
+
+        Scopes.push_back("");
+        for (const auto *Ctx : Collector.takeVisitedContexts())
+          if (isa<NamespaceDecl>(Ctx))
+            Scopes.push_back(printNamespaceScope(*Ctx));
+      }
+
+      if (CheapUnresolved.UnresolvedScope)
+        for (auto &Scope : Scopes)
+          Scope.append(*CheapUnresolved.UnresolvedScope);
+      return Scopes;
+    };
+    LastUnresolvedName = std::move(Unresolved);
+
+    // Never return a valid correction to try to recover. Our suggested fixes
+    // always require a rebuild.
+    return TypoCorrection();
+  }
+
+private:
+  Sema *SemaPtr = nullptr;
+
+  llvm::Optional<UnresolvedName> &LastUnresolvedName;
+};
+
+llvm::IntrusiveRefCntPtr<ExternalSemaSource>
+IncludeFixer::unresolvedNameRecorder() {
+  return new UnresolvedNameRecorder(LastUnresolvedName);
+}
+
+std::vector<Fix> IncludeFixer::fixUnresolvedName() const {
+  assert(LastUnresolvedName.hasValue());
+  auto &Unresolved = *LastUnresolvedName;
+  std::vector<std::string> Scopes = Unresolved.GetScopes();
+  vlog("Trying to fix unresolved name \"{0}\" in scopes: [{1}]",
+       Unresolved.Name, llvm::join(Scopes.begin(), Scopes.end(), ", "));
+
+  FuzzyFindRequest Req;
+  Req.AnyScope = false;
+  Req.Query = Unresolved.Name;
+  Req.Scopes = Scopes;
+  Req.RestrictForCodeCompletion = true;
+  Req.Limit = 100;
+
+  if (llvm::Optional<const SymbolSlab *> Syms = fuzzyFindCached(Req))
+    return fixesForSymbols(**Syms);
+
+  return {};
+}
+
+
+llvm::Optional<const SymbolSlab *>
+IncludeFixer::fuzzyFindCached(const FuzzyFindRequest &Req) const {
+  auto ReqStr = llvm::formatv("{0}", toJSON(Req)).str();
+  auto I = FuzzyFindCache.find(ReqStr);
+  if (I != FuzzyFindCache.end())
+    return &I->second;
+
+  if (IndexRequestCount >= IndexRequestLimit)
+    return llvm::None;
+  IndexRequestCount++;
+
+  SymbolSlab::Builder Matches;
+  Index.fuzzyFind(Req, [&](const Symbol &Sym) {
+    if (Sym.Name != Req.Query)
+      return;
+    if (!Sym.IncludeHeaders.empty())
+      Matches.insert(Sym);
+  });
+  auto Syms = std::move(Matches).build();
+  auto E = FuzzyFindCache.try_emplace(ReqStr, std::move(Syms));
+  return &E.first->second;
+}
+
+llvm::Optional<const SymbolSlab *>
+IncludeFixer::lookupCached(const SymbolID &ID) const {
+  LookupRequest Req;
+  Req.IDs.insert(ID);
+
+  auto I = LookupCache.find(ID);
+  if (I != LookupCache.end())
+    return &I->second;
+
+  if (IndexRequestCount >= IndexRequestLimit)
+    return llvm::None;
+  IndexRequestCount++;
+
+  // FIXME: consider batching the requests for all diagnostics.
+  SymbolSlab::Builder Matches;
+  Index.lookup(Req, [&](const Symbol &Sym) { Matches.insert(Sym); });
+  auto Syms = std::move(Matches).build();
+
+  std::vector<Fix> Fixes;
+  if (!Syms.empty()) {
+    auto &Matched = *Syms.begin();
+    if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
+        Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
+      Fixes = fixesForSymbols(Syms);
+  }
+  auto E = LookupCache.try_emplace(ID, std::move(Syms));
+  return &E.first->second;
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h
new file mode 100644
index 0000000..aafb384
--- /dev/null
+++ b/clangd/IncludeFixer.h
@@ -0,0 +1,100 @@
+//===--- IncludeFixer.h ------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H
+
+#include "Diagnostics.h"
+#include "Headers.h"
+#include "index/Index.h"
+#include "index/Symbol.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+namespace clang {
+namespace clangd {
+
+/// Attempts to recover from error diagnostics by suggesting include insertion
+/// fixes. For example, member access into incomplete type can be fixes by
+/// include headers with the definition.
+class IncludeFixer {
+public:
+  IncludeFixer(llvm::StringRef File, std::shared_ptr<IncludeInserter> Inserter,
+               const SymbolIndex &Index, unsigned IndexRequestLimit)
+      : File(File), Inserter(std::move(Inserter)), Index(Index),
+        IndexRequestLimit(IndexRequestLimit) {}
+
+  /// Returns include insertions that can potentially recover the diagnostic.
+  std::vector<Fix> fix(DiagnosticsEngine::Level DiagLevel,
+                       const clang::Diagnostic &Info) const;
+
+  /// Returns an ExternalSemaSource that records failed name lookups in Sema.
+  /// This allows IncludeFixer to suggest inserting headers that define those
+  /// names.
+  llvm::IntrusiveRefCntPtr<ExternalSemaSource> unresolvedNameRecorder();
+
+private:
+  /// Attempts to recover diagnostic caused by an incomplete type \p T.
+  std::vector<Fix> fixIncompleteType(const Type &T) const;
+
+  /// Generates header insertion fixes for all symbols. Fixes are deduplicated.
+  std::vector<Fix> fixesForSymbols(const SymbolSlab &Syms) const;
+
+  struct UnresolvedName {
+    std::string Name;   // E.g. "X" in foo::X.
+    SourceLocation Loc; // Start location of the unresolved name.
+    // Lazily get the possible scopes of the unresolved name. `Sema` must be
+    // alive when this is called.
+    std::function<std::vector<std::string>()> GetScopes;
+  };
+
+  /// Records the last unresolved name seen by Sema.
+  class UnresolvedNameRecorder;
+
+  /// Attempts to fix the unresolved name associated with the current
+  /// diagnostic. We assume a diagnostic is caused by a unresolved name when
+  /// they have the same source location and the unresolved name is the last
+  /// one we've seen during the Sema run.
+  std::vector<Fix> fixUnresolvedName() const;
+
+  std::string File;
+  std::shared_ptr<IncludeInserter> Inserter;
+  const SymbolIndex &Index;
+  const unsigned IndexRequestLimit; // Make at most 5 index requests.
+  mutable unsigned IndexRequestCount = 0;
+
+  // These collect the last unresolved name so that we can associate it with the
+  // diagnostic.
+  llvm::Optional<UnresolvedName> LastUnresolvedName;
+
+  // There can be multiple diagnostics that are caused by the same unresolved
+  // name or incomplete type in one parse, especially when code is
+  // copy-and-pasted without #includes. We cache the index results based on
+  // index requests.
+  mutable llvm::StringMap<SymbolSlab> FuzzyFindCache;
+  mutable llvm::DenseMap<SymbolID, SymbolSlab> LookupCache;
+  // Returns None if the number of index requests has reached the limit.
+  llvm::Optional<const SymbolSlab *>
+  fuzzyFindCached(const FuzzyFindRequest &Req) const;
+  llvm::Optional<const SymbolSlab *> lookupCached(const SymbolID &ID) const;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H
diff --git a/clangd/JSONTransport.cpp b/clangd/JSONTransport.cpp
index 7189b23..1731077 100644
--- a/clangd/JSONTransport.cpp
+++ b/clangd/JSONTransport.cpp
@@ -1,9 +1,8 @@
 //===--- JSONTransport.cpp - sending and receiving LSP messages over JSON -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Logger.h"
diff --git a/clangd/Logger.cpp b/clangd/Logger.cpp
index 9d4e7b9..7b8c9a3 100644
--- a/clangd/Logger.cpp
+++ b/clangd/Logger.cpp
@@ -1,9 +1,8 @@
 //===--- Logger.cpp - Logger interface for clangd -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Logger.h b/clangd/Logger.h
index 8572ca1..7a5d514 100644
--- a/clangd/Logger.h
+++ b/clangd/Logger.h
@@ -1,9 +1,8 @@
 //===--- Logger.h - Logger interface for clangd ------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Path.h b/clangd/Path.h
index b4c9335..eaa7224 100644
--- a/clangd/Path.h
+++ b/clangd/Path.h
@@ -1,9 +1,8 @@
 //===--- Path.h - Helper typedefs --------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp
index cf3c6fd..a8b1c43 100644
--- a/clangd/Protocol.cpp
+++ b/clangd/Protocol.cpp
@@ -1,9 +1,8 @@
 //===--- Protocol.cpp - Language Server Protocol Implementation -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -14,10 +13,10 @@
 #include "Protocol.h"
 #include "Logger.h"
 #include "URI.h"
-#include "index/Index.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/JSON.h"
@@ -213,6 +212,61 @@
   }
 }
 
+SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) {
+  switch (Kind) {
+  case index::SymbolKind::Unknown:
+    return SymbolKind::Variable;
+  case index::SymbolKind::Module:
+    return SymbolKind::Module;
+  case index::SymbolKind::Namespace:
+    return SymbolKind::Namespace;
+  case index::SymbolKind::NamespaceAlias:
+    return SymbolKind::Namespace;
+  case index::SymbolKind::Macro:
+    return SymbolKind::String;
+  case index::SymbolKind::Enum:
+    return SymbolKind::Enum;
+  case index::SymbolKind::Struct:
+    return SymbolKind::Struct;
+  case index::SymbolKind::Class:
+    return SymbolKind::Class;
+  case index::SymbolKind::Protocol:
+    return SymbolKind::Interface;
+  case index::SymbolKind::Extension:
+    return SymbolKind::Interface;
+  case index::SymbolKind::Union:
+    return SymbolKind::Class;
+  case index::SymbolKind::TypeAlias:
+    return SymbolKind::Class;
+  case index::SymbolKind::Function:
+    return SymbolKind::Function;
+  case index::SymbolKind::Variable:
+    return SymbolKind::Variable;
+  case index::SymbolKind::Field:
+    return SymbolKind::Field;
+  case index::SymbolKind::EnumConstant:
+    return SymbolKind::EnumMember;
+  case index::SymbolKind::InstanceMethod:
+  case index::SymbolKind::ClassMethod:
+  case index::SymbolKind::StaticMethod:
+    return SymbolKind::Method;
+  case index::SymbolKind::InstanceProperty:
+  case index::SymbolKind::ClassProperty:
+  case index::SymbolKind::StaticProperty:
+    return SymbolKind::Property;
+  case index::SymbolKind::Constructor:
+  case index::SymbolKind::Destructor:
+    return SymbolKind::Method;
+  case index::SymbolKind::ConversionFunction:
+    return SymbolKind::Function;
+  case index::SymbolKind::Parameter:
+    return SymbolKind::Variable;
+  case index::SymbolKind::Using:
+    return SymbolKind::Namespace;
+  }
+  llvm_unreachable("invalid symbol kind");
+}
+
 bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) {
   const llvm::json::Object *O = Params.getAsObject();
   if (!O)
@@ -223,6 +277,8 @@
         R.DiagnosticCategory = *CategorySupport;
       if (auto CodeActions = Diagnostics->getBoolean("codeActionsInline"))
         R.DiagnosticFixes = *CodeActions;
+      if (auto RelatedInfo = Diagnostics->getBoolean("relatedInformation"))
+        R.DiagnosticRelatedInformation = *RelatedInfo;
     }
     if (auto *Completion = TextDocument->getObject("completion")) {
       if (auto *Item = Completion->getObject("completionItem")) {
@@ -258,6 +314,11 @@
       }
     }
   }
+  if (auto *OffsetEncoding = O->get("offsetEncoding")) {
+    R.offsetEncoding.emplace();
+    if (!fromJSON(*OffsetEncoding, *R.offsetEncoding))
+      return false;
+  }
   return true;
 }
 
@@ -360,6 +421,13 @@
   return O && O.map("textDocument", R.textDocument);
 }
 
+llvm::json::Value toJSON(const DiagnosticRelatedInformation &DRI) {
+  return llvm::json::Object{
+    {"location", DRI.location},
+    {"message", DRI.message},
+  };
+}
+
 llvm::json::Value toJSON(const Diagnostic &D) {
   llvm::json::Object Diag{
       {"range", D.range},
@@ -370,6 +438,12 @@
     Diag["category"] = *D.category;
   if (D.codeActions)
     Diag["codeActions"] = D.codeActions;
+  if (!D.code.empty())
+    Diag["code"] = D.code;
+  if (!D.source.empty())
+    Diag["source"] = D.source;
+  if (D.relatedInformation)
+    Diag["relatedInformation"] = *D.relatedInformation;
   return std::move(Diag);
 }
 
@@ -379,6 +453,8 @@
     return false;
   O.map("severity", R.severity);
   O.map("category", R.category);
+  O.map("code", R.code);
+  O.map("source", R.source);
   return true;
 }
 
@@ -422,6 +498,9 @@
 
 const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND =
     "clangd.applyFix";
+const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_TWEAK =
+    "clangd.applyTweak";
+
 bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R) {
   llvm::json::ObjectMapper O(Params);
   if (!O || !O.map("command", R.command))
@@ -432,6 +511,8 @@
     return Args && Args->size() == 1 &&
            fromJSON(Args->front(), R.workspaceEdit);
   }
+  if (R.command == ExecuteCommandParams::CLANGD_APPLY_TWEAK)
+    return Args && Args->size() == 1 && fromJSON(Args->front(), R.tweakArgs);
   return false; // Unrecognized command.
 }
 
@@ -456,25 +537,25 @@
 }
 
 llvm::json::Value toJSON(const SymbolDetails &P) {
-  llvm::json::Object result{{"name", llvm::json::Value(nullptr)},
+  llvm::json::Object Result{{"name", llvm::json::Value(nullptr)},
                             {"containerName", llvm::json::Value(nullptr)},
                             {"usr", llvm::json::Value(nullptr)},
                             {"id", llvm::json::Value(nullptr)}};
 
   if (!P.name.empty())
-    result["name"] = P.name;
+    Result["name"] = P.name;
 
   if (!P.containerName.empty())
-    result["containerName"] = P.containerName;
+    Result["containerName"] = P.containerName;
 
   if (!P.USR.empty())
-    result["usr"] = P.USR;
+    Result["usr"] = P.USR;
 
   if (P.ID.hasValue())
-    result["id"] = P.ID.getValue().str();
+    Result["id"] = P.ID.getValue().str();
 
   // Older clang cannot compile 'return Result', even though it is legal.
-  return llvm::json::Value(std::move(result));
+  return llvm::json::Value(std::move(Result));
 }
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
@@ -498,10 +579,13 @@
   auto Cmd = llvm::json::Object{{"title", C.title}, {"command", C.command}};
   if (C.workspaceEdit)
     Cmd["arguments"] = {*C.workspaceEdit};
+  if (C.tweakArgs)
+    Cmd["arguments"] = {*C.tweakArgs};
   return std::move(Cmd);
 }
 
 const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
+const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor";
 
 llvm::json::Value toJSON(const CodeAction &CA) {
   auto CodeAction = llvm::json::Object{{"title", CA.title}};
@@ -545,6 +629,17 @@
   return llvm::json::Object{{"changes", std::move(FileChanges)}};
 }
 
+bool fromJSON(const llvm::json::Value &Params, TweakArgs &A) {
+  llvm::json::ObjectMapper O(Params);
+  return O && O.map("file", A.file) && O.map("selection", A.selection) &&
+         O.map("tweakID", A.tweakID);
+}
+
+llvm::json::Value toJSON(const TweakArgs &A) {
+  return llvm::json::Object{
+      {"tweakID", A.tweakID}, {"selection", A.selection}, {"file", A.file}};
+}
+
 llvm::json::Value toJSON(const ApplyWorkspaceEditParams &Params) {
   return llvm::json::Object{{"edit", Params.edit}};
 }
@@ -560,10 +655,10 @@
   if (!O)
     return false;
 
-  int triggerKind;
-  if (!O.map("triggerKind", triggerKind))
+  int TriggerKind;
+  if (!O.map("triggerKind", TriggerKind))
     return false;
-  R.triggerKind = static_cast<CompletionTriggerKind>(triggerKind);
+  R.triggerKind = static_cast<CompletionTriggerKind>(TriggerKind);
 
   if (auto *TC = Params.getAsObject()->get("triggerCharacter"))
     return fromJSON(*TC, R.triggerCharacter);
@@ -620,11 +715,11 @@
 
 CompletionItemKind
 adjustKindToCapability(CompletionItemKind Kind,
-                       CompletionItemKindBitset &supportedCompletionItemKinds) {
+                       CompletionItemKindBitset &SupportedCompletionItemKinds) {
   auto KindVal = static_cast<size_t>(Kind);
   if (KindVal >= CompletionItemKindMin &&
-      KindVal <= supportedCompletionItemKinds.size() &&
-      supportedCompletionItemKinds[KindVal])
+      KindVal <= SupportedCompletionItemKinds.size() &&
+      SupportedCompletionItemKinds[KindVal])
     return Kind;
 
   switch (Kind) {
@@ -795,10 +890,99 @@
   return true;
 }
 
+bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out) {
+  auto T = E.getAsInteger();
+  if (!T)
+    return false;
+  if (*T < static_cast<int>(TypeHierarchyDirection::Children) ||
+      *T > static_cast<int>(TypeHierarchyDirection::Both))
+    return false;
+  Out = static_cast<TypeHierarchyDirection>(*T);
+  return true;
+}
+
+bool fromJSON(const llvm::json::Value &Params, TypeHierarchyParams &R) {
+  llvm::json::ObjectMapper O(Params);
+  return O && O.map("textDocument", R.textDocument) &&
+         O.map("position", R.position) && O.map("resolve", R.resolve) &&
+         O.map("direction", R.direction);
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
+                              const TypeHierarchyItem &I) {
+  return O << I.name << " - " << toJSON(I);
+}
+
+llvm::json::Value toJSON(const TypeHierarchyItem &I) {
+  llvm::json::Object Result{{"name", I.name},
+                            {"kind", static_cast<int>(I.kind)},
+                            {"range", I.range},
+                            {"selectionRange", I.selectionRange},
+                            {"uri", I.uri}};
+
+  if (I.detail)
+    Result["detail"] = I.detail;
+  if (I.deprecated)
+    Result["deprecated"] = I.deprecated;
+  if (I.parents)
+    Result["parents"] = I.parents;
+  if (I.children)
+    Result["children"] = I.children;
+  return std::move(Result);
+}
+
+bool fromJSON(const llvm::json::Value &Params, TypeHierarchyItem &I) {
+  llvm::json::ObjectMapper O(Params);
+
+  // Required fields.
+  if (!(O && O.map("name", I.name) && O.map("kind", I.kind) &&
+        O.map("uri", I.uri) && O.map("range", I.range) &&
+        O.map("selectionRange", I.selectionRange))) {
+    return false;
+  }
+
+  // Optional fields.
+  O.map("detail", I.detail);
+  O.map("deprecated", I.deprecated);
+  O.map("parents", I.parents);
+  O.map("children", I.children);
+
+  return true;
+}
+
 bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R) {
   TextDocumentPositionParams &Base = R;
   return fromJSON(Params, Base);
 }
 
+static const char *toString(OffsetEncoding OE) {
+  switch (OE) {
+  case OffsetEncoding::UTF8:
+    return "utf-8";
+  case OffsetEncoding::UTF16:
+    return "utf-16";
+  case OffsetEncoding::UTF32:
+    return "utf-32";
+  case OffsetEncoding::UnsupportedEncoding:
+    return "unknown";
+  }
+  llvm_unreachable("Unknown clang.clangd.OffsetEncoding");
+}
+llvm::json::Value toJSON(const OffsetEncoding &OE) { return toString(OE); }
+bool fromJSON(const llvm::json::Value &V, OffsetEncoding &OE) {
+  auto Str = V.getAsString();
+  if (!Str)
+    return false;
+  OE = llvm::StringSwitch<OffsetEncoding>(*Str)
+           .Case("utf-8", OffsetEncoding::UTF8)
+           .Case("utf-16", OffsetEncoding::UTF16)
+           .Case("utf-32", OffsetEncoding::UTF32)
+           .Default(OffsetEncoding::UnsupportedEncoding);
+  return true;
+}
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OffsetEncoding Enc) {
+  return OS << toString(Enc);
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/Protocol.h b/clangd/Protocol.h
index 17b69bd..957e2f3 100644
--- a/clangd/Protocol.h
+++ b/clangd/Protocol.h
@@ -1,9 +1,8 @@
 //===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -26,8 +25,10 @@
 
 #include "URI.h"
 #include "index/SymbolID.h"
+#include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
 #include <bitset>
 #include <string>
 #include <vector>
@@ -205,11 +206,10 @@
   /// The string to be inserted. For delete operations use an
   /// empty string.
   std::string newText;
-
-  bool operator==(const TextEdit &rhs) const {
-    return newText == rhs.newText && range == rhs.range;
-  }
 };
+inline bool operator==(const TextEdit &L, const TextEdit &R) {
+  return std::tie(L.newText, L.range) == std::tie(R.newText, R.range);
+}
 bool fromJSON(const llvm::json::Value &, TextEdit &);
 llvm::json::Value toJSON(const TextEdit &);
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TextEdit &);
@@ -293,7 +293,7 @@
 bool fromJSON(const llvm::json::Value &, CompletionItemKindBitset &);
 CompletionItemKind
 adjustKindToCapability(CompletionItemKind Kind,
-                       CompletionItemKindBitset &supportedCompletionItemKinds);
+                       CompletionItemKindBitset &SupportedCompletionItemKinds);
 
 /// A symbol kind.
 enum class SymbolKind {
@@ -332,6 +332,27 @@
 SymbolKind adjustKindToCapability(SymbolKind Kind,
                                   SymbolKindBitset &supportedSymbolKinds);
 
+// Convert a index::SymbolKind to clangd::SymbolKind (LSP)
+// Note, some are not perfect matches and should be improved when this LSP
+// issue is addressed:
+// https://github.com/Microsoft/language-server-protocol/issues/344
+SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind);
+
+// Determines the encoding used to measure offsets and lengths of source in LSP.
+enum class OffsetEncoding {
+  // Any string is legal on the wire. Unrecognized encodings parse as this.
+  UnsupportedEncoding,
+  // Length counts code units of UTF-16 encoded text. (Standard LSP behavior).
+  UTF16,
+  // Length counts bytes of UTF-8 encoded text. (Clangd extension).
+  UTF8,
+  // Length counts codepoints in unicode text. (Clangd extension).
+  UTF32,
+};
+llvm::json::Value toJSON(const OffsetEncoding &);
+bool fromJSON(const llvm::json::Value &, OffsetEncoding &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, OffsetEncoding);
+
 // This struct doesn't mirror LSP!
 // The protocol defines deeply nested structures for client capabilities.
 // Instead of mapping them all, this just parses out the bits we care about.
@@ -344,6 +365,10 @@
   /// textDocument.publishDiagnostics.codeActionsInline.
   bool DiagnosticFixes = false;
 
+  /// Whether the client accepts diagnostics with related locations.
+  /// textDocument.publishDiagnostics.relatedInformation.
+  bool DiagnosticRelatedInformation = false;
+
   /// Whether the client accepts diagnostics with category attached to it
   /// using the "category" extension.
   /// textDocument.publishDiagnostics.categorySupport
@@ -363,6 +388,9 @@
   /// Client supports CodeAction return value for textDocument/codeAction.
   /// textDocument.codeAction.codeActionLiteralSupport.
   bool CodeActionStructure = false;
+
+  /// Supported encodings for LSP character offsets. (clangd extension).
+  llvm::Optional<std::vector<OffsetEncoding>> offsetEncoding;
 };
 bool fromJSON(const llvm::json::Value &, ClientCapabilities &);
 
@@ -557,6 +585,18 @@
 };
 bool fromJSON(const llvm::json::Value &, DocumentSymbolParams &);
 
+
+/// Represents a related message and source code location for a diagnostic.
+/// This should be used to point to code locations that cause or related to a
+/// diagnostics, e.g when duplicating a symbol in a scope.
+struct DiagnosticRelatedInformation {
+  /// The location of this related diagnostic information.
+  Location location;
+  /// The message of this related diagnostic information.
+  std::string message;
+};
+llvm::json::Value toJSON(const DiagnosticRelatedInformation &);
+
 struct CodeAction;
 struct Diagnostic {
   /// The range at which the message applies.
@@ -567,17 +607,19 @@
   int severity = 0;
 
   /// The diagnostic's code. Can be omitted.
-  /// Note: Not currently used by clangd
-  // std::string code;
+  std::string code;
 
   /// A human-readable string describing the source of this
   /// diagnostic, e.g. 'typescript' or 'super lint'.
-  /// Note: Not currently used by clangd
-  // std::string source;
+  std::string source;
 
   /// The diagnostic's message.
   std::string message;
 
+  /// An array of related diagnostic information, e.g. when symbol-names within
+  /// a scope collide all definitions can be marked via this property.
+  llvm::Optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
+
   /// The diagnostic's category. Can be omitted.
   /// An LSP extension that's used to send the name of the category over to the
   /// client. The category typically describes the compilation stage during
@@ -632,6 +674,21 @@
 bool fromJSON(const llvm::json::Value &, WorkspaceEdit &);
 llvm::json::Value toJSON(const WorkspaceEdit &WE);
 
+/// Arguments for the 'applyTweak' command. The server sends these commands as a
+/// response to the textDocument/codeAction request. The client can later send a
+/// command back to the server if the user requests to execute a particular code
+/// tweak.
+struct TweakArgs {
+  /// A file provided by the client on a textDocument/codeAction request.
+  URIForFile file;
+  /// A selection provided by the client on a textDocument/codeAction request.
+  Range selection;
+  /// ID of the tweak that should be executed. Corresponds to Tweak::id().
+  std::string tweakID;
+};
+bool fromJSON(const llvm::json::Value &, TweakArgs &);
+llvm::json::Value toJSON(const TweakArgs &A);
+
 /// Exact commands are not specified in the protocol so we define the
 /// ones supported by Clangd here. The protocol specifies the command arguments
 /// to be "any[]" but to make this safer and more manageable, each command we
@@ -643,12 +700,15 @@
 struct ExecuteCommandParams {
   // Command to apply fix-its. Uses WorkspaceEdit as argument.
   const static llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND;
+  // Command to apply the code action. Uses TweakArgs as argument.
+  const static llvm::StringLiteral CLANGD_APPLY_TWEAK;
 
   /// The command identifier, e.g. CLANGD_APPLY_FIX_COMMAND
   std::string command;
 
   // Arguments
   llvm::Optional<WorkspaceEdit> workspaceEdit;
+  llvm::Optional<TweakArgs> tweakArgs;
 };
 bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &);
 
@@ -670,6 +730,7 @@
   /// Used to filter code actions.
   llvm::Optional<std::string> kind;
   const static llvm::StringLiteral QUICKFIX_KIND;
+  const static llvm::StringLiteral REFACTOR_KIND;
 
   /// The diagnostics that this code action resolves.
   llvm::Optional<std::vector<Diagnostic>> diagnostics;
@@ -996,6 +1057,67 @@
 llvm::json::Value toJSON(const DocumentHighlight &DH);
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &);
 
+enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 };
+bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out);
+
+/// The type hierarchy params is an extension of the
+/// `TextDocumentPositionsParams` with optional properties which can be used to
+/// eagerly resolve the item when requesting from the server.
+struct TypeHierarchyParams : public TextDocumentPositionParams {
+  /// The hierarchy levels to resolve. `0` indicates no level.
+  int resolve = 0;
+
+  /// The direction of the hierarchy levels to resolve.
+  TypeHierarchyDirection direction = TypeHierarchyDirection::Parents;
+};
+bool fromJSON(const llvm::json::Value &, TypeHierarchyParams &);
+
+struct TypeHierarchyItem {
+  /// The human readable name of the hierarchy item.
+  std::string name;
+
+  /// Optional detail for the hierarchy item. It can be, for instance, the
+  /// signature of a function or method.
+  llvm::Optional<std::string> detail;
+
+  /// The kind of the hierarchy item. For instance, class or interface.
+  SymbolKind kind;
+
+  /// `true` if the hierarchy item is deprecated. Otherwise, `false`.
+  bool deprecated;
+
+  /// The URI of the text document where this type hierarchy item belongs to.
+  URIForFile uri;
+
+  /// The range enclosing this type hierarchy item not including
+  /// leading/trailing whitespace but everything else like comments. This
+  /// information is typically used to determine if the client's cursor is
+  /// inside the type hierarch item to reveal in the symbol in the UI.
+  Range range;
+
+  /// The range that should be selected and revealed when this type hierarchy
+  /// item is being picked, e.g. the name of a function. Must be contained by
+  /// the `range`.
+  Range selectionRange;
+
+  /// If this type hierarchy item is resolved, it contains the direct parents.
+  /// Could be empty if the item does not have direct parents. If not defined,
+  /// the parents have not been resolved yet.
+  llvm::Optional<std::vector<TypeHierarchyItem>> parents;
+
+  /// If this type hierarchy item is resolved, it contains the direct children
+  /// of the current item. Could be empty if the item does not have any
+  /// descendants. If not defined, the children have not been resolved.
+  llvm::Optional<std::vector<TypeHierarchyItem>> children;
+
+  /// The protocol has a slot here for an optional 'data' filed, which can
+  /// be used to identify a type hierarchy item in a resolve request. We don't
+  /// need this (the item itself is sufficient to identify what to resolve)
+  /// so don't declare it.
+};
+llvm::json::Value toJSON(const TypeHierarchyItem &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &);
+
 struct ReferenceParams : public TextDocumentPositionParams {
   // For now, no options like context.includeDeclaration are supported.
 };
diff --git a/clangd/Quality.cpp b/clangd/Quality.cpp
index cef35c4..6307006 100644
--- a/clangd/Quality.cpp
+++ b/clangd/Quality.cpp
@@ -1,16 +1,16 @@
 //===--- Quality.cpp ---------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+
 #include "Quality.h"
 #include "AST.h"
 #include "FileDistance.h"
 #include "URI.h"
-#include "index/Index.h"
+#include "index/Symbol.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
@@ -283,12 +283,12 @@
 }
 
 void SymbolRelevanceSignals::merge(const Symbol &IndexResult) {
-  // FIXME: Index results always assumed to be at global scope. If Scope becomes
-  // relevant to non-completion requests, we should recognize class members etc.
-
   SymbolURI = IndexResult.CanonicalDeclaration.FileURI;
   SymbolScope = IndexResult.Scope;
   IsInstanceMember |= isInstanceMember(IndexResult.SymInfo);
+  if (!(IndexResult.Flags & Symbol::VisibleOutsideFile)) {
+    Scope = AccessibleScope::FileScope;
+  }
 }
 
 void SymbolRelevanceSignals::merge(const CodeCompletionResult &SemaCCResult) {
@@ -336,6 +336,15 @@
   return std::max(0.65, 2.0 * std::pow(0.6, D / 2.0));
 }
 
+static llvm::Optional<llvm::StringRef>
+wordMatching(llvm::StringRef Name, const llvm::StringSet<> *ContextWords) {
+  if (ContextWords)
+    for (const auto& Word : ContextWords->keys())
+      if (Name.contains_lower(Word))
+        return Word;
+  return llvm::None;
+}
+
 float SymbolRelevanceSignals::evaluate() const {
   float Score = 1;
 
@@ -357,6 +366,9 @@
     Score *=
         SemaSaysInScope ? 2.0 : scopeBoost(*ScopeProximityMatch, SymbolScope);
 
+  if (wordMatching(Name, ContextWords))
+    Score *= 1.5;
+
   // Symbols like local variables may only be referenced within their scope.
   // Conversely if we're in that scope, it's likely we'll reference them.
   if (Query == CodeComplete) {
@@ -366,7 +378,7 @@
     case GlobalScope:
       break;
     case FileScope:
-      Score *= 1.5;
+      Score *= 1.5f;
       break;
     case ClassScope:
       Score *= 2;
@@ -375,6 +387,19 @@
       Score *= 4;
       break;
     }
+  } else {
+    // For non-completion queries, the wider the scope where a symbol is
+    // visible, the more likely it is to be relevant.
+    switch (Scope) {
+    case GlobalScope:
+      break;
+    case FileScope:
+      Score *= 0.5f;
+      break;
+    default:
+      // TODO: Handle other scopes as we start to use them for index results.
+      break;
+    }
   }
 
   if (TypeMatchesPreferred)
@@ -400,7 +425,12 @@
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
                               const SymbolRelevanceSignals &S) {
   OS << llvm::formatv("=== Symbol relevance: {0}\n", S.evaluate());
+  OS << llvm::formatv("\tName: {0}\n", S.Name);
   OS << llvm::formatv("\tName match: {0}\n", S.NameMatch);
+  if (S.ContextWords)
+    OS << llvm::formatv(
+        "\tMatching context word: {0}\n",
+        wordMatching(S.Name, S.ContextWords).getValueOr("<none>"));
   OS << llvm::formatv("\tForbidden: {0}\n", S.Forbidden);
   OS << llvm::formatv("\tNeedsFixIts: {0}\n", S.NeedsFixIts);
   OS << llvm::formatv("\tIsInstanceMember: {0}\n", S.IsInstanceMember);
diff --git a/clangd/Quality.h b/clangd/Quality.h
index 9cb0c2f..b358a91 100644
--- a/clangd/Quality.h
+++ b/clangd/Quality.h
@@ -1,9 +1,8 @@
 //===--- Quality.h - Ranking alternatives for ambiguous queries --*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -33,13 +32,14 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include <algorithm>
 #include <functional>
 #include <vector>
 
 namespace llvm {
 class raw_ostream;
-}
+} // namespace llvm
 
 namespace clang {
 class CodeCompletionResult;
@@ -85,8 +85,12 @@
 
 /// Attributes of a symbol-query pair that affect how much we like it.
 struct SymbolRelevanceSignals {
+  /// The name of the symbol (for ContextWords). Must be explicitly assigned.
+  llvm::StringRef Name;
   /// 0-1+ fuzzy-match score for unqualified name. Must be explicitly assigned.
   float NameMatch = 1;
+  /// Lowercase words relevant to the context (e.g. near the completion point).
+  llvm::StringSet<>* ContextWords = nullptr;
   bool Forbidden = false; // Unavailable (e.g const) or inaccessible (private).
   /// Whether fixits needs to be applied for that completion or not.
   bool NeedsFixIts = false;
diff --git a/clangd/RIFF.cpp b/clangd/RIFF.cpp
index c0bf785..cdbae4f 100644
--- a/clangd/RIFF.cpp
+++ b/clangd/RIFF.cpp
@@ -1,9 +1,8 @@
 //===--- RIFF.cpp - Binary container file format --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/RIFF.h b/clangd/RIFF.h
index f56d087..d827a90 100644
--- a/clangd/RIFF.h
+++ b/clangd/RIFF.h
@@ -1,9 +1,8 @@
 //===--- RIFF.h - Binary container file format -------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp
new file mode 100644
index 0000000..233a436
--- /dev/null
+++ b/clangd/Selection.cpp
@@ -0,0 +1,300 @@
+//===--- Selection.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Selection.h"
+#include "ClangdUnit.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+using Node = SelectionTree::Node;
+using ast_type_traits::DynTypedNode;
+
+// We find the selection by visiting written nodes in the AST, looking for nodes
+// that intersect with the selected character range.
+//
+// While traversing, we maintain a parent stack. As nodes pop off the stack,
+// we decide whether to keep them or not. To be kept, they must either be
+// selected or contain some nodes that are.
+//
+// For simple cases (not inside macros) we prune subtrees that don't intersect.
+class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
+public:
+  // Runs the visitor to gather selected nodes and their ancestors.
+  // If there is any selection, the root (TUDecl) is the first node.
+  static std::deque<Node> collect(ASTContext &AST, unsigned Begin,
+                                  unsigned End, FileID File) {
+    SelectionVisitor V(AST, Begin, End, File);
+    V.TraverseAST(AST);
+    assert(V.Stack.size() == 1 && "Unpaired push/pop?");
+    assert(V.Stack.top() == &V.Nodes.front());
+    if (V.Nodes.size() == 1) // TUDecl, but no nodes under it.
+      V.Nodes.clear();
+    return std::move(V.Nodes);
+  }
+
+  // We traverse all "well-behaved" nodes the same way:
+  //  - push the node onto the stack
+  //  - traverse its children recursively
+  //  - pop it from the stack
+  //  - hit testing: is intersection(node, selection) - union(children) empty?
+  //  - attach it to the tree if it or any children hit the selection
+  //
+  // Two categories of nodes are not "well-behaved":
+  //  - those without source range information, we don't record those
+  //  - those that can't be stored in DynTypedNode.
+  // We're missing some interesting things like Attr due to the latter.
+  bool TraverseDecl(Decl *X) {
+    if (X && isa<TranslationUnitDecl>(X))
+      return Base::TraverseDecl(X); // Already pushed by constructor.
+    return traverseNode(X, [&] { return Base::TraverseDecl(X); });
+  }
+  bool TraverseTypeLoc(TypeLoc X) {
+    return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); });
+  }
+  bool TraverseTypeNestedNameSpecifierLoc(NestedNameSpecifierLoc X) {
+    return traverseNode(
+        &X, [&] { return Base::TraverseNestedNameSpecifierLoc(X); });
+  }
+  bool TraverseConstructorInitializer(CXXCtorInitializer *X) {
+    return traverseNode(
+        X, [&] { return Base::TraverseConstructorInitializer(X); });
+  }
+  // Stmt is the same, but this form allows the data recursion optimization.
+  bool dataTraverseStmtPre(Stmt *X) {
+    if (!X || canSafelySkipNode(X->getSourceRange()))
+      return false;
+    push(DynTypedNode::create(*X));
+    return true;
+  }
+  bool dataTraverseStmtPost(Stmt *X) {
+    pop();
+    return true;
+  }
+  // Uninteresting parts of the AST that don't have locations within them.
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; }
+  bool TraverseType(QualType) { return true; }
+
+private:
+  using Base = RecursiveASTVisitor<SelectionVisitor>;
+  SelectionVisitor(ASTContext &AST, unsigned SelBegin, unsigned SelEnd,
+                   FileID SelFile)
+      : SM(AST.getSourceManager()), LangOpts(AST.getLangOpts()),
+        SelBegin(SelBegin), SelEnd(SelEnd), SelFile(SelFile),
+        SelBeginTokenStart(SM.getFileOffset(Lexer::GetBeginningOfToken(
+            SM.getComposedLoc(SelFile, SelBegin), SM, LangOpts))) {
+    // Ensure we have a node for the TU decl, regardless of traversal scope.
+    Nodes.emplace_back();
+    Nodes.back().ASTNode = DynTypedNode::create(*AST.getTranslationUnitDecl());
+    Nodes.back().Parent = nullptr;
+    Nodes.back().Selected = SelectionTree::Unselected;
+    Stack.push(&Nodes.back());
+  }
+
+  // Generic case of TraverseFoo. Func should be the call to Base::TraverseFoo.
+  // Node is always a pointer so the generic code can handle any null checks.
+  template <typename T, typename Func>
+  bool traverseNode(T *Node, const Func &Body) {
+    if (Node == nullptr || canSafelySkipNode(Node->getSourceRange()))
+      return true;
+    push(DynTypedNode::create(*Node));
+    bool Ret = Body();
+    pop();
+    return Ret;
+  }
+
+  // An optimization for a common case: nodes outside macro expansions that
+  // don't intersect the selection may be recursively skipped.
+  bool canSafelySkipNode(SourceRange S) {
+    auto B = SM.getDecomposedLoc(S.getBegin());
+    auto E = SM.getDecomposedLoc(S.getEnd());
+    if (B.first != SelFile || E.first != SelFile)
+      return false;
+    return B.second >= SelEnd || E.second < SelBeginTokenStart;
+  }
+
+  // Pushes a node onto the ancestor stack. Pairs with pop().
+  void push(DynTypedNode Node) {
+    Nodes.emplace_back();
+    Nodes.back().ASTNode = std::move(Node);
+    Nodes.back().Parent = Stack.top();
+    Nodes.back().Selected = SelectionTree::Unselected;
+    Stack.push(&Nodes.back());
+  }
+
+  // Pops a node off the ancestor stack, and finalizes it. Pairs with push().
+  void pop() {
+    Node &N = *Stack.top();
+    N.Selected = computeSelection(N);
+    if (N.Selected || !N.Children.empty()) {
+      // Attach to the tree.
+      N.Parent->Children.push_back(&N);
+    } else {
+      // Neither N any children are selected, it doesn't belong in the tree.
+      assert(&N == &Nodes.back());
+      Nodes.pop_back();
+    }
+    Stack.pop();
+  }
+
+  // Perform hit-testing of a complete Node against the selection.
+  // This runs for every node in the AST, and must be fast in common cases.
+  // This is called from pop(), so we can take children into account.
+  SelectionTree::Selection computeSelection(const Node &N) {
+    SourceRange S = N.ASTNode.getSourceRange();
+    if (!S.isValid())
+      return SelectionTree::Unselected;
+    // getTopMacroCallerLoc() allows selection of constructs in macro args. e.g:
+    //   #define LOOP_FOREVER(Body) for(;;) { Body }
+    //   void IncrementLots(int &x) {
+    //     LOOP_FOREVER( ++x; )
+    //   }
+    // Selecting "++x" or "x" will do the right thing.
+    auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin()));
+    auto E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd()));
+    // Otherwise, nodes in macro expansions can't be selected.
+    if (B.first != SelFile || E.first != SelFile)
+      return SelectionTree::Unselected;
+    // Cheap test: is there any overlap at all between the selection and range?
+    // Note that E.second is the *start* of the last token, which is why we
+    // compare against the "rounded-down" SelBegin.
+    if (B.second >= SelEnd || E.second < SelBeginTokenStart)
+      return SelectionTree::Unselected;
+
+    // We hit something, need some more precise checks.
+    // Adjust [B, E) to be a half-open character range.
+    E.second += Lexer::MeasureTokenLength(S.getEnd(), SM, LangOpts);
+    // This node's own selected text is (this range ^ selection) - child ranges.
+    // If that's empty, then we've only collided with children.
+    if (nodesCoverRange(N.Children, std::max(SelBegin, B.second),
+                        std::min(SelEnd, E.second)))
+      return SelectionTree::Unselected; // Hit children only.
+    // Some of our own characters are covered, this is a true hit.
+    return (B.second >= SelBegin && E.second <= SelEnd)
+               ? SelectionTree::Complete
+               : SelectionTree::Partial;
+  }
+
+  // Is the range [Begin, End) entirely covered by the union of the Nodes?
+  // (The range is a parent node's extent, and the covering nodes are children).
+  bool nodesCoverRange(llvm::ArrayRef<const Node *> Nodes, unsigned Begin,
+                       unsigned End) {
+    if (Begin >= End)
+      return true;
+    if (Nodes.empty())
+      return false;
+
+    // Collect all the expansion ranges, as offsets.
+    SmallVector<std::pair<unsigned, unsigned>, 8> ChildRanges;
+    for (const Node *N : Nodes) {
+      CharSourceRange R = SM.getExpansionRange(N->ASTNode.getSourceRange());
+      auto B = SM.getDecomposedLoc(R.getBegin());
+      auto E = SM.getDecomposedLoc(R.getEnd());
+      if (B.first != SelFile || E.first != SelFile)
+        continue;
+      // Try to cover up to the next token, spaces between children don't count.
+      if (auto Tok = Lexer::findNextToken(R.getEnd(), SM, LangOpts))
+        E.second = SM.getFileOffset(Tok->getLocation());
+      else if (R.isTokenRange())
+        E.second += Lexer::MeasureTokenLength(R.getEnd(), SM, LangOpts);
+      ChildRanges.push_back({B.second, E.second});
+    }
+    llvm::sort(ChildRanges);
+
+    // Scan through the child ranges, removing as we go.
+    for (const auto R : ChildRanges) {
+      if (R.first > Begin)
+        return false;   // [Begin, R.first) is not covered.
+      Begin = R.second; // Eliminate [R.first, R.second).
+      if (Begin >= End)
+        return true; // Remaining range is empty.
+    }
+    return false; // Went through all children, trailing characters remain.
+  }
+
+  SourceManager &SM;
+  const LangOptions &LangOpts;
+  std::stack<Node *> Stack;
+  std::deque<Node> Nodes; // Stable pointers as we add more nodes.
+  // Half-open selection range.
+  unsigned SelBegin;
+  unsigned SelEnd;
+  FileID SelFile;
+  // If the selection start slices a token in half, the beginning of that token.
+  // This is useful for checking whether the end of a token range overlaps
+  // the selection: range.end < SelBeginTokenStart is equivalent to
+  // range.end + measureToken(range.end) < SelBegin (assuming range.end points
+  // to a token), and it saves a lex every time.
+  unsigned SelBeginTokenStart;
+};
+
+} // namespace
+
+void SelectionTree::print(llvm::raw_ostream &OS, const SelectionTree::Node &N,
+                          int Indent) const {
+  if (N.Selected)
+    OS.indent(Indent - 1) << (N.Selected == SelectionTree::Complete ? '*'
+                                                                    : '.');
+  else
+    OS.indent(Indent);
+  OS << N.ASTNode.getNodeKind().asStringRef() << " ";
+  N.ASTNode.print(OS, PrintPolicy);
+  OS << "\n";
+  for (const Node *Child : N.Children)
+    print(OS, *Child, Indent + 2);
+}
+
+// Decide which selection emulates a "point" query in between characters.
+static std::pair<unsigned, unsigned> pointBounds(unsigned Offset, FileID FID,
+                                                 ASTContext &AST) {
+  StringRef Buf = AST.getSourceManager().getBufferData(FID);
+  // Edge-cases where the choice is forced.
+  if (Buf.size() == 0)
+    return {0, 0};
+  if (Offset == 0)
+    return {0, 1};
+  if (Offset == Buf.size())
+    return {Offset - 1, Offset};
+  // We could choose either this byte or the previous. Usually we prefer the
+  // character on the right of the cursor (or under a block cursor).
+  // But if that's whitespace, we likely want the token on the left.
+  if (isWhitespace(Buf[Offset]) && !isWhitespace(Buf[Offset - 1]))
+    return {Offset - 1, Offset};
+  return {Offset, Offset + 1};
+}
+
+SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End)
+    : PrintPolicy(AST.getLangOpts()) {
+  // No fundamental reason the selection needs to be in the main file,
+  // but that's all clangd has needed so far.
+  FileID FID = AST.getSourceManager().getMainFileID();
+  if (Begin == End)
+    std::tie(Begin, End) = pointBounds(Begin, FID, AST);
+  PrintPolicy.TerseOutput = true;
+
+  Nodes = SelectionVisitor::collect(AST, Begin, End, FID);
+  Root = Nodes.empty() ? nullptr : &Nodes.front();
+}
+
+SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset)
+    : SelectionTree(AST, Offset, Offset) {}
+
+const Node *SelectionTree::commonAncestor() const {
+  if (!Root)
+    return nullptr;
+  for (const Node *Ancestor = Root;; Ancestor = Ancestor->Children.front()) {
+    if (Ancestor->Selected || Ancestor->Children.size() > 1)
+      return Ancestor;
+    // The tree only contains ancestors of the interesting nodes.
+    assert(!Ancestor->Children.empty() && "bad node in selection tree");
+  }
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/Selection.h b/clangd/Selection.h
new file mode 100644
index 0000000..c7cee64
--- /dev/null
+++ b/clangd/Selection.h
@@ -0,0 +1,123 @@
+//===--- Selection.h - What's under the cursor? -------------------*-C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Many features are triggered at locations/ranges and operate on AST nodes.
+// (e.g. go-to-definition or code tweaks).
+// At a high level, such features need to work out which node is the correct
+// target.
+//
+// There are a few levels of ambiguity here:
+//
+// Which tokens are included:
+//   int x = one + two;  // what should "go to definition" do?
+//            ^^^^^^
+//
+// Same token means multiple things:
+//   string("foo")       // class string, or a constructor?
+//   ^
+//
+// Which level of the AST is interesting?
+//   if (err) {          // reference to 'err', or operator bool(),
+//       ^               // or the if statement itself?
+//
+// Here we build and expose a data structure that allows features to resolve
+// these ambiguities in an appropriate way:
+//   - we determine which low-level nodes are partly or completely covered
+//     by the selection.
+//   - we expose a tree of the selected nodes and their lexical parents.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+namespace clangd {
+class ParsedAST;
+
+// A selection can partially or completely cover several AST nodes.
+// The SelectionTree contains nodes that are covered, and their parents.
+// SelectionTree does not contain all AST nodes, rather only:
+//   Decl, Stmt, TypeLoc, NestedNamespaceSpecifierLoc, CXXCtorInitializer.
+// (These are the nodes with source ranges that fit in DynTypedNode).
+//
+// Usually commonAncestor() is the place to start:
+//  - it's the simplest answer to "what node is under the cursor"
+//  - the selected Expr (for example) can be found by walking up the parent
+//    chain and checking Node->ASTNode.
+//  - if you want to traverse the selected nodes, they are all under
+//    commonAncestor() in the tree.
+//
+// The SelectionTree owns the Node structures, but the ASTNode attributes
+// point back into the AST it was constructed with.
+class SelectionTree {
+public:
+  // Creates a selection tree at the given byte offset in the main file.
+  // This is approximately equivalent to a range of one character.
+  // (Usually, the character to the right of Offset, sometimes to the left).
+  SelectionTree(ASTContext &AST, unsigned Offset);
+  // Creates a selection tree for the given range in the main file.
+  // The range includes bytes [Start, End).
+  // If Start == End, uses the same heuristics as SelectionTree(AST, Start).
+  SelectionTree(ASTContext &AST, unsigned Start, unsigned End);
+
+  // Describes to what extent an AST node is covered by the selection.
+  enum Selection {
+    // The AST node owns no characters covered by the selection.
+    // Note that characters owned by children don't count:
+    //   if (x == 0) scream();
+    //       ^^^^^^
+    // The IfStmt would be Unselected because all the selected characters are
+    // associated with its children.
+    // (Invisible nodes like ImplicitCastExpr are always unselected).
+    Unselected,
+    // The AST node owns selected characters, but is not completely covered.
+    Partial,
+    // The AST node owns characters, and is covered by the selection.
+    Complete,
+  };
+  // An AST node that is implicated in the selection.
+  // (Either selected directly, or some descendant is selected).
+  struct Node {
+    // The parent within the selection tree. nullptr for TranslationUnitDecl.
+    Node *Parent;
+    // Direct children within the selection tree.
+    llvm::SmallVector<const Node *, 8> Children;
+    // The corresponding node from the full AST.
+    ast_type_traits::DynTypedNode ASTNode;
+    // The extent to which this node is covered by the selection.
+    Selection Selected;
+  };
+
+  // The most specific common ancestor of all the selected nodes.
+  // If there is no selection, this is nullptr.
+  const Node *commonAncestor() const;
+  // The selection node corresponding to TranslationUnitDecl.
+  // If there is no selection, this is nullptr.
+  const Node *root() const { return Root; }
+
+private:
+  std::deque<Node> Nodes; // Stable-pointer storage.
+  const Node *Root;
+  clang::PrintingPolicy PrintPolicy;
+
+  void print(llvm::raw_ostream &OS, const Node &N, int Indent) const;
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                       const SelectionTree &T) {
+    if (auto R = T.root())
+      T.print(OS, *R, 0);
+    else
+      OS << "(empty selection)\n";
+    return OS;
+  }
+};
+
+} // namespace clangd
+} // namespace clang
+#endif
diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp
index 343fc70..6c52ca6 100644
--- a/clangd/SourceCode.cpp
+++ b/clangd/SourceCode.cpp
@@ -1,20 +1,30 @@
 //===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "SourceCode.h"
 
+#include "Context.h"
+#include "FuzzyMatch.h"
 #include "Logger.h"
+#include "Protocol.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Path.h"
+#include <algorithm>
 
 namespace clang {
 namespace clangd {
@@ -27,6 +37,8 @@
 // Returns true if CB returned true, false if we hit the end of string.
 template <typename Callback>
 static bool iterateCodepoints(llvm::StringRef U8, const Callback &CB) {
+  // A codepoint takes two UTF-16 code unit if it's astral (outside BMP).
+  // Astral codepoints are encoded as 4 bytes in UTF-8, starting with 11110xxx.
   for (size_t I = 0; I < U8.size();) {
     unsigned char C = static_cast<unsigned char>(U8[I]);
     if (LLVM_LIKELY(!(C & 0x80))) { // ASCII character.
@@ -50,31 +62,75 @@
   return false;
 }
 
-// Returns the offset into the string that matches \p Units UTF-16 code units.
-// Conceptually, this converts to UTF-16, truncates to CodeUnits, converts back
-// to UTF-8, and returns the length in bytes.
-static size_t measureUTF16(llvm::StringRef U8, int U16Units, bool &Valid) {
+// Returns the byte offset into the string that is an offset of \p Units in
+// the specified encoding.
+// Conceptually, this converts to the encoding, truncates to CodeUnits,
+// converts back to UTF-8, and returns the length in bytes.
+static size_t measureUnits(llvm::StringRef U8, int Units, OffsetEncoding Enc,
+                           bool &Valid) {
+  Valid = Units >= 0;
+  if (Units <= 0)
+    return 0;
   size_t Result = 0;
-  Valid = U16Units == 0 || iterateCodepoints(U8, [&](int U8Len, int U16Len) {
-            Result += U8Len;
-            U16Units -= U16Len;
-            return U16Units <= 0;
-          });
-  if (U16Units < 0) // Offset was into the middle of a surrogate pair.
-    Valid = false;
+  switch (Enc) {
+  case OffsetEncoding::UTF8:
+    Result = Units;
+    break;
+  case OffsetEncoding::UTF16:
+    Valid = iterateCodepoints(U8, [&](int U8Len, int U16Len) {
+      Result += U8Len;
+      Units -= U16Len;
+      return Units <= 0;
+    });
+    if (Units < 0) // Offset in the middle of a surrogate pair.
+      Valid = false;
+    break;
+  case OffsetEncoding::UTF32:
+    Valid = iterateCodepoints(U8, [&](int U8Len, int U16Len) {
+      Result += U8Len;
+      Units--;
+      return Units <= 0;
+    });
+    break;
+  case OffsetEncoding::UnsupportedEncoding:
+    llvm_unreachable("unsupported encoding");
+  }
   // Don't return an out-of-range index if we overran.
-  return std::min(Result, U8.size());
+  if (Result > U8.size()) {
+    Valid = false;
+    return U8.size();
+  }
+  return Result;
+}
+
+Key<OffsetEncoding> kCurrentOffsetEncoding;
+static OffsetEncoding lspEncoding() {
+  auto *Enc = Context::current().get(kCurrentOffsetEncoding);
+  return Enc ? *Enc : OffsetEncoding::UTF16;
 }
 
 // Like most strings in clangd, the input is UTF-8 encoded.
 size_t lspLength(llvm::StringRef Code) {
-  // A codepoint takes two UTF-16 code unit if it's astral (outside BMP).
-  // Astral codepoints are encoded as 4 bytes in UTF-8, starting with 11110xxx.
   size_t Count = 0;
-  iterateCodepoints(Code, [&](int U8Len, int U16Len) {
-    Count += U16Len;
-    return false;
-  });
+  switch (lspEncoding()) {
+  case OffsetEncoding::UTF8:
+    Count = Code.size();
+    break;
+  case OffsetEncoding::UTF16:
+    iterateCodepoints(Code, [&](int U8Len, int U16Len) {
+      Count += U16Len;
+      return false;
+    });
+    break;
+  case OffsetEncoding::UTF32:
+    iterateCodepoints(Code, [&](int U8Len, int U16Len) {
+      ++Count;
+      return false;
+    });
+    break;
+  case OffsetEncoding::UnsupportedEncoding:
+    llvm_unreachable("unsupported encoding");
+  }
   return Count;
 }
 
@@ -97,20 +153,18 @@
           llvm::errc::invalid_argument);
     StartOfLine = NextNL + 1;
   }
+  StringRef Line =
+      Code.substr(StartOfLine).take_until([](char C) { return C == '\n'; });
 
-  size_t NextNL = Code.find('\n', StartOfLine);
-  if (NextNL == llvm::StringRef::npos)
-    NextNL = Code.size();
-
+  // P.character may be in UTF-16, transcode if necessary.
   bool Valid;
-  size_t ByteOffsetInLine = measureUTF16(
-      Code.substr(StartOfLine, NextNL - StartOfLine), P.character, Valid);
+  size_t ByteInLine = measureUnits(Line, P.character, lspEncoding(), Valid);
   if (!Valid && !AllowColumnsBeyondLineLength)
     return llvm::make_error<llvm::StringError>(
-        llvm::formatv("UTF-16 offset {0} is invalid for line {1}", P.character,
-                      P.line),
+        llvm::formatv("{0} offset {1} is invalid for line {2}", lspEncoding(),
+                      P.character, P.line),
         llvm::errc::invalid_argument);
-  return StartOfLine + ByteOffsetInLine;
+  return StartOfLine + ByteInLine;
 }
 
 Position offsetToPosition(llvm::StringRef Code, size_t Offset) {
@@ -142,6 +196,79 @@
   return P;
 }
 
+bool isValidFileRange(const SourceManager &Mgr, SourceRange R) {
+  if (!R.getBegin().isValid() || !R.getEnd().isValid())
+    return false;
+
+  FileID BeginFID;
+  size_t BeginOffset = 0;
+  std::tie(BeginFID, BeginOffset) = Mgr.getDecomposedLoc(R.getBegin());
+
+  FileID EndFID;
+  size_t EndOffset = 0;
+  std::tie(EndFID, EndOffset) = Mgr.getDecomposedLoc(R.getEnd());
+
+  return BeginFID.isValid() && BeginFID == EndFID && BeginOffset <= EndOffset;
+}
+
+bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R,
+                           SourceLocation L) {
+  assert(isValidFileRange(Mgr, R));
+
+  FileID BeginFID;
+  size_t BeginOffset = 0;
+  std::tie(BeginFID, BeginOffset) = Mgr.getDecomposedLoc(R.getBegin());
+  size_t EndOffset = Mgr.getFileOffset(R.getEnd());
+
+  FileID LFid;
+  size_t LOffset;
+  std::tie(LFid, LOffset) = Mgr.getDecomposedLoc(L);
+  return BeginFID == LFid && BeginOffset <= LOffset && LOffset < EndOffset;
+}
+
+bool halfOpenRangeTouches(const SourceManager &Mgr, SourceRange R,
+                          SourceLocation L) {
+  return L == R.getEnd() || halfOpenRangeContains(Mgr, R, L);
+}
+
+llvm::Optional<SourceRange> toHalfOpenFileRange(const SourceManager &Mgr,
+                                                const LangOptions &LangOpts,
+                                                SourceRange R) {
+  auto Begin = Mgr.getFileLoc(R.getBegin());
+  if (Begin.isInvalid())
+    return llvm::None;
+  auto End = Mgr.getFileLoc(R.getEnd());
+  if (End.isInvalid())
+    return llvm::None;
+  End = Lexer::getLocForEndOfToken(End, 0, Mgr, LangOpts);
+
+  SourceRange Result(Begin, End);
+  if (!isValidFileRange(Mgr, Result))
+    return llvm::None;
+  return Result;
+}
+
+llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R) {
+  assert(isValidFileRange(SM, R));
+  bool Invalid = false;
+  auto *Buf = SM.getBuffer(SM.getFileID(R.getBegin()), &Invalid);
+  assert(!Invalid);
+
+  size_t BeginOffset = SM.getFileOffset(R.getBegin());
+  size_t EndOffset = SM.getFileOffset(R.getEnd());
+  return Buf->getBuffer().substr(BeginOffset, EndOffset - BeginOffset);
+}
+
+llvm::Expected<SourceLocation> sourceLocationInMainFile(const SourceManager &SM,
+                                                        Position P) {
+  llvm::StringRef Code = SM.getBuffer(SM.getMainFileID())->getBuffer();
+  auto Offset =
+      positionToOffset(Code, P, /*AllowColumnBeyondLineLength=*/false);
+  if (!Offset)
+    return Offset.takeError();
+  return SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(*Offset);
+}
+
 Range halfOpenToRange(const SourceManager &SM, CharSourceRange R) {
   // Clang is 1-based, LSP uses 0-based indexes.
   Position Begin = sourceLocToPosition(SM, R.getBegin());
@@ -160,8 +287,7 @@
   return {Lines + 1, Offset - StartOfLine + 1};
 }
 
-std::pair<llvm::StringRef, llvm::StringRef>
-splitQualifiedName(llvm::StringRef QName) {
+std::pair<StringRef, StringRef> splitQualifiedName(StringRef QName) {
   size_t Pos = QName.rfind("::");
   if (Pos == llvm::StringRef::npos)
     return {llvm::StringRef(), QName};
@@ -192,7 +318,7 @@
   llvm::SmallString<128> FilePath = F->getName();
   if (!llvm::sys::path::is_absolute(FilePath)) {
     if (auto EC =
-            SourceMgr.getFileManager().getVirtualFileSystem()->makeAbsolute(
+            SourceMgr.getFileManager().getVirtualFileSystem().makeAbsolute(
                 FilePath)) {
       elog("Could not turn relative path '{0}' to absolute: {1}", FilePath,
            EC.message());
@@ -232,7 +358,7 @@
   return Result;
 }
 
-bool IsRangeConsecutive(const Range &Left, const Range &Right) {
+bool isRangeConsecutive(const Range &Left, const Range &Right) {
   return Left.end.line == Right.start.line &&
          Left.end.character == Right.start.character;
 }
@@ -249,5 +375,272 @@
   return digest(Content);
 }
 
+format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
+                                          llvm::StringRef Content,
+                                          llvm::vfs::FileSystem *FS) {
+  auto Style = format::getStyle(format::DefaultFormatStyle, File,
+                                format::DefaultFallbackStyle, Content, FS);
+  if (!Style) {
+    log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.", File,
+        Style.takeError());
+    Style = format::getLLVMStyle();
+  }
+  return *Style;
+}
+
+llvm::Expected<tooling::Replacements>
+cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces,
+                 const format::FormatStyle &Style) {
+  auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
+  if (!CleanReplaces)
+    return CleanReplaces;
+  return formatReplacements(Code, std::move(*CleanReplaces), Style);
+}
+
+template <typename Action>
+static void lex(llvm::StringRef Code, const format::FormatStyle &Style,
+                Action A) {
+  // FIXME: InMemoryFileAdapter crashes unless the buffer is null terminated!
+  std::string NullTerminatedCode = Code.str();
+  SourceManagerForFile FileSM("dummy.cpp", NullTerminatedCode);
+  auto &SM = FileSM.get();
+  auto FID = SM.getMainFileID();
+  Lexer Lex(FID, SM.getBuffer(FID), SM, format::getFormattingLangOpts(Style));
+  Token Tok;
+
+  while (!Lex.LexFromRawLexer(Tok))
+    A(Tok);
+}
+
+llvm::StringMap<unsigned> collectIdentifiers(llvm::StringRef Content,
+                                             const format::FormatStyle &Style) {
+  llvm::StringMap<unsigned> Identifiers;
+  lex(Content, Style, [&](const clang::Token &Tok) {
+    switch (Tok.getKind()) {
+    case tok::identifier:
+      ++Identifiers[Tok.getIdentifierInfo()->getName()];
+      break;
+    case tok::raw_identifier:
+      ++Identifiers[Tok.getRawIdentifier()];
+      break;
+    default:
+      break;
+    }
+  });
+  return Identifiers;
+}
+
+namespace {
+enum NamespaceEvent {
+  BeginNamespace, // namespace <ns> {.     Payload is resolved <ns>.
+  EndNamespace,   // } // namespace <ns>.  Payload is resolved *outer* namespace.
+  UsingDirective  // using namespace <ns>. Payload is unresolved <ns>.
+};
+// Scans C++ source code for constructs that change the visible namespaces.
+void parseNamespaceEvents(
+    llvm::StringRef Code, const format::FormatStyle &Style,
+    llvm::function_ref<void(NamespaceEvent, llvm::StringRef)> Callback) {
+
+  // Stack of enclosing namespaces, e.g. {"clang", "clangd"}
+  std::vector<std::string> Enclosing; // Contains e.g. "clang", "clangd"
+  // Stack counts open braces. true if the brace opened a namespace.
+  std::vector<bool> BraceStack;
+
+  enum {
+    Default,
+    Namespace,          // just saw 'namespace'
+    NamespaceName,      // just saw 'namespace' NSName
+    Using,              // just saw 'using'
+    UsingNamespace,     // just saw 'using namespace'
+    UsingNamespaceName, // just saw 'using namespace' NSName
+  } State = Default;
+  std::string NSName;
+
+  lex(Code, Style, [&](const clang::Token &Tok) {
+    switch(Tok.getKind()) {
+    case tok::raw_identifier:
+      // In raw mode, this could be a keyword or a name.
+      switch (State) {
+      case UsingNamespace:
+      case UsingNamespaceName:
+        NSName.append(Tok.getRawIdentifier());
+        State = UsingNamespaceName;
+        break;
+      case Namespace:
+      case NamespaceName:
+        NSName.append(Tok.getRawIdentifier());
+        State = NamespaceName;
+        break;
+      case Using:
+        State =
+            (Tok.getRawIdentifier() == "namespace") ? UsingNamespace : Default;
+        break;
+      case Default:
+        NSName.clear();
+        if (Tok.getRawIdentifier() == "namespace")
+          State = Namespace;
+        else if (Tok.getRawIdentifier() == "using")
+          State = Using;
+        break;
+      }
+      break;
+    case tok::coloncolon:
+      // This can come at the beginning or in the middle of a namespace name.
+      switch (State) {
+      case UsingNamespace:
+      case UsingNamespaceName:
+        NSName.append("::");
+        State = UsingNamespaceName;
+        break;
+      case NamespaceName:
+        NSName.append("::");
+        State = NamespaceName;
+        break;
+      case Namespace: // Not legal here.
+      case Using:
+      case Default:
+        State = Default;
+        break;
+      }
+      break;
+    case tok::l_brace:
+      // Record which { started a namespace, so we know when } ends one.
+      if (State == NamespaceName) {
+        // Parsed: namespace <name> {
+        BraceStack.push_back(true);
+        Enclosing.push_back(NSName);
+        Callback(BeginNamespace, llvm::join(Enclosing, "::"));
+      } else {
+        // This case includes anonymous namespaces (State = Namespace).
+        // For our purposes, they're not namespaces and we ignore them.
+        BraceStack.push_back(false);
+      }
+      State = Default;
+      break;
+    case tok::r_brace:
+      // If braces are unmatched, we're going to be confused, but don't crash.
+      if (!BraceStack.empty()) {
+        if (BraceStack.back()) {
+          // Parsed: } // namespace
+          Enclosing.pop_back();
+          Callback(EndNamespace, llvm::join(Enclosing, "::"));
+        }
+        BraceStack.pop_back();
+      }
+      break;
+    case tok::semi:
+      if (State == UsingNamespaceName)
+        // Parsed: using namespace <name> ;
+        Callback(UsingDirective, llvm::StringRef(NSName));
+      State = Default;
+      break;
+    default:
+      State = Default;
+      break;
+    }
+  });
+}
+
+// Returns the prefix namespaces of NS: {"" ... NS}.
+llvm::SmallVector<llvm::StringRef, 8> ancestorNamespaces(llvm::StringRef NS) {
+  llvm::SmallVector<llvm::StringRef, 8> Results;
+  Results.push_back(NS.take_front(0));
+  NS.split(Results, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  for (llvm::StringRef &R : Results)
+    R = NS.take_front(R.end() - NS.begin());
+  return Results;
+}
+
+} // namespace
+
+std::vector<std::string> visibleNamespaces(llvm::StringRef Code,
+                                           const format::FormatStyle &Style) {
+  std::string Current;
+  // Map from namespace to (resolved) namespaces introduced via using directive.
+  llvm::StringMap<llvm::StringSet<>> UsingDirectives;
+
+  parseNamespaceEvents(Code, Style,
+                       [&](NamespaceEvent Event, llvm::StringRef NS) {
+                         switch (Event) {
+                         case BeginNamespace:
+                         case EndNamespace:
+                           Current = NS;
+                           break;
+                         case UsingDirective:
+                           if (NS.consume_front("::"))
+                             UsingDirectives[Current].insert(NS);
+                           else {
+                             for (llvm::StringRef Enclosing :
+                                  ancestorNamespaces(Current)) {
+                               if (Enclosing.empty())
+                                 UsingDirectives[Current].insert(NS);
+                               else
+                                 UsingDirectives[Current].insert(
+                                     (Enclosing + "::" + NS).str());
+                             }
+                           }
+                           break;
+                         }
+                       });
+
+  std::vector<std::string> Found;
+  for (llvm::StringRef Enclosing : ancestorNamespaces(Current)) {
+    Found.push_back(Enclosing);
+    auto It = UsingDirectives.find(Enclosing);
+    if (It != UsingDirectives.end())
+      for (const auto& Used : It->second)
+        Found.push_back(Used.getKey());
+  }
+
+
+  llvm::sort(Found, [&](const std::string &LHS, const std::string &RHS) {
+    if (Current == RHS)
+      return false;
+    if (Current == LHS)
+      return true;
+    return LHS < RHS;
+  });
+  Found.erase(std::unique(Found.begin(), Found.end()), Found.end());
+  return Found;
+}
+
+llvm::StringSet<> collectWords(llvm::StringRef Content) {
+  // We assume short words are not significant.
+  // We may want to consider other stopwords, e.g. language keywords.
+  // (A very naive implementation showed no benefit, but lexing might do better)
+  static constexpr int MinWordLength = 4;
+
+  std::vector<CharRole> Roles(Content.size());
+  calculateRoles(Content, Roles);
+
+  llvm::StringSet<> Result;
+  llvm::SmallString<256> Word;
+  auto Flush = [&] {
+    if (Word.size() >= MinWordLength) {
+      for (char &C : Word)
+        C = llvm::toLower(C);
+      Result.insert(Word);
+    }
+    Word.clear();
+  };
+  for (unsigned I = 0; I < Content.size(); ++I) {
+    switch (Roles[I]) {
+    case Head:
+      Flush();
+      LLVM_FALLTHROUGH;
+    case Tail:
+      Word.push_back(Content[I]);
+      break;
+    case Unknown:
+    case Separator:
+      Flush();
+      break;
+    }
+  }
+  Flush();
+
+  return Result;
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h
index b768d09..85db945 100644
--- a/clangd/SourceCode.h
+++ b/clangd/SourceCode.h
@@ -1,9 +1,8 @@
 //===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -13,11 +12,16 @@
 //===----------------------------------------------------------------------===//
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H
+#include "Context.h"
 #include "Protocol.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
 #include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/SHA1.h"
 
 namespace clang {
@@ -32,8 +36,14 @@
 FileDigest digest(StringRef Content);
 Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID);
 
+// This context variable controls the behavior of functions in this file
+// that convert between LSP offsets and native clang byte offsets.
+// If not set, defaults to UTF-16 for backwards-compatibility.
+extern Key<OffsetEncoding> kCurrentOffsetEncoding;
+
 // Counts the number of UTF-16 code units needed to represent a string (LSP
 // specifies string lengths in UTF-16 code units).
+// Use of UTF-16 may be overridden by kCurrentOffsetEncoding.
 size_t lspLength(StringRef Code);
 
 /// Turn a [line, column] pair into an offset in Code.
@@ -55,6 +65,51 @@
 /// FIXME: This should return an error if the location is invalid.
 Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc);
 
+/// Return the file location, corresponding to \p P. Note that one should take
+/// care to avoid comparing the result with expansion locations.
+llvm::Expected<SourceLocation> sourceLocationInMainFile(const SourceManager &SM,
+                                                        Position P);
+
+/// Turns a token range into a half-open range and checks its correctness.
+/// The resulting range will have only valid source location on both sides, both
+/// of which are file locations.
+///
+/// File locations always point to a particular offset in a file, i.e. they
+/// never refer to a location inside a macro expansion. Turning locations from
+/// macro expansions into file locations is ambiguous - one can use
+/// SourceManager::{getExpansion|getFile|getSpelling}Loc. This function
+/// calls SourceManager::getFileLoc on both ends of \p R to do the conversion.
+///
+/// User input (e.g. cursor position) is expressed as a file location, so this
+/// function can be viewed as a way to normalize the ranges used in the clang
+/// AST so that they are comparable with ranges coming from the user input.
+llvm::Optional<SourceRange> toHalfOpenFileRange(const SourceManager &Mgr,
+                                                const LangOptions &LangOpts,
+                                                SourceRange R);
+
+/// Returns true iff all of the following conditions hold:
+///   - start and end locations are valid,
+///   - start and end locations are file locations from the same file
+///     (i.e. expansion locations are not taken into account).
+///   - start offset <= end offset.
+/// FIXME: introduce a type for source range with this invariant.
+bool isValidFileRange(const SourceManager &Mgr, SourceRange R);
+
+/// Returns true iff \p L is contained in \p R.
+/// EXPECTS: isValidFileRange(R) == true, L is a file location.
+bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R,
+                           SourceLocation L);
+
+/// Returns true iff \p L is contained in \p R or \p L is equal to the end point
+/// of \p R.
+/// EXPECTS: isValidFileRange(R) == true, L is a file location.
+bool halfOpenRangeTouches(const SourceManager &Mgr, SourceRange R,
+                          SourceLocation L);
+
+/// Returns the source code covered by the source range.
+/// EXPECTS: isValidFileRange(R) == true.
+llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R);
+
 // Converts a half-open clang source range to an LSP range.
 // Note that clang also uses closed source ranges, which this can't handle!
 Range halfOpenToRange(const SourceManager &SM, CharSourceRange R);
@@ -91,7 +146,56 @@
 llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
                                              const SourceManager &SourceMgr);
 
-bool IsRangeConsecutive(const Range &Left, const Range &Right);
+bool isRangeConsecutive(const Range &Left, const Range &Right);
+
+/// Choose the clang-format style we should apply to a certain file.
+/// This will usually use FS to look for .clang-format directories.
+/// FIXME: should we be caching the .clang-format file search?
+/// This uses format::DefaultFormatStyle and format::DefaultFallbackStyle,
+/// though the latter may have been overridden in main()!
+format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
+                                          llvm::StringRef Content,
+                                          llvm::vfs::FileSystem *FS);
+
+// Cleanup and format the given replacements.
+llvm::Expected<tooling::Replacements>
+cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces,
+                 const format::FormatStyle &Style);
+
+/// Collects identifiers with counts in the source code.
+llvm::StringMap<unsigned> collectIdentifiers(llvm::StringRef Content,
+                                             const format::FormatStyle &Style);
+
+/// Collects words from the source code.
+/// Unlike collectIdentifiers:
+/// - also finds text in comments:
+/// - splits text into words
+/// - drops stopwords like "get" and "for"
+llvm::StringSet<> collectWords(llvm::StringRef Content);
+
+/// Heuristically determine namespaces visible at a point, without parsing Code.
+/// This considers using-directives and enclosing namespace-declarations that
+/// are visible (and not obfuscated) in the file itself (not headers).
+/// Code should be truncated at the point of interest.
+///
+/// The returned vector is always non-empty.
+/// - The first element is the namespace that encloses the point: a declaration
+///   near the point would be within this namespace.
+/// - The elements are the namespaces in scope at the point: an unqualified
+///   lookup would search within these namespaces.
+///
+/// Using directives are resolved against all enclosing scopes, but no other
+/// namespace directives.
+///
+/// example:
+///   using namespace a;
+///   namespace foo {
+///     using namespace b;
+///
+/// visibleNamespaces are {"foo::", "", "a::", "b::", "foo::b::"}, not "a::b::".
+std::vector<std::string> visibleNamespaces(llvm::StringRef Code,
+                                           const format::FormatStyle &Style);
+
 } // namespace clangd
 } // namespace clang
 #endif
diff --git a/clangd/StdSymbolMap.inc b/clangd/StdSymbolMap.inc
new file mode 100644
index 0000000..85fd474
--- /dev/null
+++ b/clangd/StdSymbolMap.inc
@@ -0,0 +1,1513 @@
+//===-- gen_std.py generated file -------------------------------*- C++ -*-===//
+//
+// Used to build a lookup table (qualified names => include headers) for C++
+// Standard Library symbols.
+//
+// Automatically generated file, DO NOT EDIT!
+//
+// Generated from cppreference offline HTML book (modified on 2018-10-28).
+//===----------------------------------------------------------------------===//
+
+SYMBOL(Assignable, std::, <concepts>)
+SYMBOL(Boolean, std::, <concepts>)
+SYMBOL(Common, std::, <concepts>)
+SYMBOL(CommonReference, std::, <concepts>)
+SYMBOL(Constructible, std::, <concepts>)
+SYMBOL(ConvertibleTo, std::, <concepts>)
+SYMBOL(CopyConstructible, std::, <concepts>)
+SYMBOL(Copyable, std::, <concepts>)
+SYMBOL(DefaultConstructible, std::, <concepts>)
+SYMBOL(DerivedFrom, std::, <concepts>)
+SYMBOL(Destructible, std::, <concepts>)
+SYMBOL(EqualityComparable, std::, <concepts>)
+SYMBOL(EqualityComparableWith, std::, <concepts>)
+SYMBOL(FILE, std::, <cstdio>)
+SYMBOL(Integral, std::, <concepts>)
+SYMBOL(Invocable, std::, <concepts>)
+SYMBOL(Movable, std::, <concepts>)
+SYMBOL(MoveConstructible, std::, <concepts>)
+SYMBOL(Predicate, std::, <concepts>)
+SYMBOL(Regular, std::, <concepts>)
+SYMBOL(RegularInvocable, std::, <concepts>)
+SYMBOL(Relation, std::, <concepts>)
+SYMBOL(Same, std::, <concepts>)
+SYMBOL(Semiregular, std::, <concepts>)
+SYMBOL(SignedIntegral, std::, <concepts>)
+SYMBOL(StrictTotallyOrdered, std::, <concepts>)
+SYMBOL(StrictTotallyOrderedWith, std::, <concepts>)
+SYMBOL(StrictWeakOrder, std::, <concepts>)
+SYMBOL(Swappable, std::, <concepts>)
+SYMBOL(SwappableWith, std::, <concepts>)
+SYMBOL(UniformRandomBitGenerator, std::, <random>)
+SYMBOL(UnsignedIntegral, std::, <concepts>)
+SYMBOL(_Exit, std::, <cstdlib>)
+SYMBOL(accumulate, std::, <numeric>)
+SYMBOL(acos, std::, <cmath>)
+SYMBOL(acosh, std::, <cmath>)
+SYMBOL(add_const, std::, <type_traits>)
+SYMBOL(add_const_t, std::, <type_traits>)
+SYMBOL(add_cv, std::, <type_traits>)
+SYMBOL(add_cv_t, std::, <type_traits>)
+SYMBOL(add_lvalue_reference, std::, <type_traits>)
+SYMBOL(add_lvalue_reference_t, std::, <type_traits>)
+SYMBOL(add_pointer, std::, <type_traits>)
+SYMBOL(add_pointer_t, std::, <type_traits>)
+SYMBOL(add_rvalue_reference, std::, <type_traits>)
+SYMBOL(add_rvalue_reference_t, std::, <type_traits>)
+SYMBOL(add_volatile, std::, <type_traits>)
+SYMBOL(add_volatile_t, std::, <type_traits>)
+SYMBOL(addressof, std::, <memory>)
+SYMBOL(adjacent_difference, std::, <numeric>)
+SYMBOL(adjacent_find, std::, <algorithm>)
+SYMBOL(adopt_lock, std::, <mutex>)
+SYMBOL(adopt_lock_t, std::, <mutex>)
+SYMBOL(advance, std::, <iterator>)
+SYMBOL(align, std::, <memory>)
+SYMBOL(align_val_t, std::, <new>)
+SYMBOL(aligned_alloc, std::, <cstdlib>)
+SYMBOL(aligned_storage, std::, <type_traits>)
+SYMBOL(aligned_storage_t, std::, <type_traits>)
+SYMBOL(aligned_union, std::, <type_traits>)
+SYMBOL(aligned_union_t, std::, <type_traits>)
+SYMBOL(alignment_of, std::, <type_traits>)
+SYMBOL(alignment_of_v, std::, <type_traits>)
+SYMBOL(all_of, std::, <algorithm>)
+SYMBOL(allocate_shared, std::, <memory>)
+SYMBOL(allocator, std::, <memory>)
+SYMBOL(allocator_arg, std::, <memory>)
+SYMBOL(allocator_arg_t, std::, <memory>)
+SYMBOL(allocator_traits, std::, <memory>)
+SYMBOL(any, std::, <any>)
+SYMBOL(any_of, std::, <algorithm>)
+SYMBOL(apply, std::, <tuple>)
+SYMBOL(arg, std::, <complex>)
+SYMBOL(array, std::, <array>)
+SYMBOL(as_const, std::, <utility>)
+SYMBOL(asctime, std::, <ctime>)
+SYMBOL(asin, std::, <cmath>)
+SYMBOL(asinh, std::, <cmath>)
+SYMBOL(async, std::, <future>)
+SYMBOL(at_quick_exit, std::, <cstdlib>)
+SYMBOL(atan, std::, <cmath>)
+SYMBOL(atan2, std::, <cmath>)
+SYMBOL(atanh, std::, <cmath>)
+SYMBOL(atexit, std::, <cstdlib>)
+SYMBOL(atof, std::, <cstdlib>)
+SYMBOL(atoi, std::, <cstdlib>)
+SYMBOL(atol, std::, <cstdlib>)
+SYMBOL(atoll, std::, <cstdlib>)
+SYMBOL(atomic_compare_exchange_strong, std::, <atomic>)
+SYMBOL(atomic_compare_exchange_strong_explicit, std::, <atomic>)
+SYMBOL(atomic_compare_exchange_weak, std::, <atomic>)
+SYMBOL(atomic_compare_exchange_weak_explicit, std::, <atomic>)
+SYMBOL(atomic_exchange, std::, <atomic>)
+SYMBOL(atomic_exchange_explicit, std::, <atomic>)
+SYMBOL(atomic_fetch_add, std::, <atomic>)
+SYMBOL(atomic_fetch_add_explicit, std::, <atomic>)
+SYMBOL(atomic_fetch_and, std::, <atomic>)
+SYMBOL(atomic_fetch_and_explicit, std::, <atomic>)
+SYMBOL(atomic_fetch_or, std::, <atomic>)
+SYMBOL(atomic_fetch_or_explicit, std::, <atomic>)
+SYMBOL(atomic_fetch_sub, std::, <atomic>)
+SYMBOL(atomic_fetch_sub_explicit, std::, <atomic>)
+SYMBOL(atomic_fetch_xor, std::, <atomic>)
+SYMBOL(atomic_fetch_xor_explicit, std::, <atomic>)
+SYMBOL(atomic_flag, std::, <atomic>)
+SYMBOL(atomic_flag_clear, std::, <atomic>)
+SYMBOL(atomic_flag_clear_explicit, std::, <atomic>)
+SYMBOL(atomic_flag_test_and_set, std::, <atomic>)
+SYMBOL(atomic_flag_test_and_set_explicit, std::, <atomic>)
+SYMBOL(atomic_init, std::, <atomic>)
+SYMBOL(atomic_is_lockfree, std::, <atomic>)
+SYMBOL(atomic_load, std::, <atomic>)
+SYMBOL(atomic_load_explicit, std::, <atomic>)
+SYMBOL(atomic_ref, std::, <atomic>)
+SYMBOL(atomic_signal_fence, std::, <atomic>)
+SYMBOL(atomic_store, std::, <atomic>)
+SYMBOL(atomic_store_explicit, std::, <atomic>)
+SYMBOL(atomic_thread_fence, std::, <atomic>)
+SYMBOL(atto, std::, <ratio>)
+SYMBOL(auto_ptr, std::, <memory>)
+SYMBOL(back_insert_iterator, std::, <iterator>)
+SYMBOL(back_inserter, std::, <iterator>)
+SYMBOL(bad_alloc, std::, <new>)
+SYMBOL(bad_any_cast, std::, <any>)
+SYMBOL(bad_array_new_length, std::, <new>)
+SYMBOL(bad_cast, std::, <typeinfo>)
+SYMBOL(bad_exception, std::, <exception>)
+SYMBOL(bad_function_call, std::, <functional>)
+SYMBOL(bad_optional_access, std::, <optional>)
+SYMBOL(bad_typeid, std::, <typeinfo>)
+SYMBOL(bad_variant_access, std::, <variant>)
+SYMBOL(bad_weak_ptr, std::, <memory>)
+SYMBOL(basic_common_reference, std::, <type_traits>)
+SYMBOL(basic_filebuf, std::, <fstream>)
+SYMBOL(basic_fstream, std::, <fstream>)
+SYMBOL(basic_ifstream, std::, <fstream>)
+SYMBOL(basic_ios, std::, <ios>)
+SYMBOL(basic_iostream, std::, <istream>)
+SYMBOL(basic_istream, std::, <istream>)
+SYMBOL(basic_istringstream, std::, <sstream>)
+SYMBOL(basic_ofstream, std::, <fstream>)
+SYMBOL(basic_ostream, std::, <ostream>)
+SYMBOL(basic_ostringstream, std::, <sstream>)
+SYMBOL(basic_osyncstream, std::, <syncstream>)
+SYMBOL(basic_regex, std::, <regex>)
+SYMBOL(basic_streambuf, std::, <streambuf>)
+SYMBOL(basic_string, std::, <string>)
+SYMBOL(basic_string_view, std::, <string_view>)
+SYMBOL(basic_stringbuf, std::, <sstream>)
+SYMBOL(basic_stringstream, std::, <sstream>)
+SYMBOL(basic_syncbuf, std::, <syncstream>)
+SYMBOL(begin, std::, <iterator>)
+SYMBOL(bernoulli_distribution, std::, <random>)
+SYMBOL(bidirectional_iterator_tag, std::, <iterator>)
+SYMBOL(binary_search, std::, <algorithm>)
+SYMBOL(bind, std::, <functional>)
+SYMBOL(binomial_distribution, std::, <random>)
+SYMBOL(bit_and, std::, <functional>)
+SYMBOL(bit_cast, std::, <bit>)
+SYMBOL(bit_not, std::, <functional>)
+SYMBOL(bit_or, std::, <functional>)
+SYMBOL(bit_xor, std::, <functional>)
+SYMBOL(bitset, std::, <bitset>)
+SYMBOL(bool_constant, std::, <type_traits>)
+SYMBOL(boolalpha, std::, <ios>)
+SYMBOL(boyer_moore_horspool_searcher, std::, <functional>)
+SYMBOL(boyer_moore_searcher, std::, <functional>)
+SYMBOL(bsearch, std::, <cstdlib>)
+SYMBOL(btowc, std::, <cwchar>)
+SYMBOL(byte, std::, <cstddef>)
+SYMBOL(c16rtomb, std::, <cuchar>)
+SYMBOL(c32rtomb, std::, <cuchar>)
+SYMBOL(call_once, std::, <mutex>)
+SYMBOL(calloc, std::, <cstdlib>)
+SYMBOL(cauchy_distribution, std::, <random>)
+SYMBOL(cbegin, std::, <iterator>)
+SYMBOL(cbrt, std::, <cmath>)
+SYMBOL(ceil, std::, <cmath>)
+SYMBOL(ceil2, std::, <bit>)
+SYMBOL(cend, std::, <iterator>)
+SYMBOL(centi, std::, <ratio>)
+SYMBOL(cerr, std::, <iostream>)
+SYMBOL(char_traits, std::, <string>)
+SYMBOL(chars_format, std::, <charconv>)
+SYMBOL(chi_squared_distribution, std::, <random>)
+SYMBOL(cin, std::, <iostream>)
+SYMBOL(clamp, std::, <algorithm>)
+SYMBOL(clearerr, std::, <cstdio>)
+SYMBOL(clock, std::, <ctime>)
+SYMBOL(clock_t, std::, <ctime>)
+SYMBOL(clog, std::, <iostream>)
+SYMBOL(cmatch, std::, <regex>)
+SYMBOL(codecvt, std::, <locale>)
+SYMBOL(codecvt_base, std::, <locale>)
+SYMBOL(codecvt_byname, std::, <locale>)
+SYMBOL(codecvt_mode, std::, <codecvt>)
+SYMBOL(codecvt_utf16, std::, <codecvt>)
+SYMBOL(codecvt_utf8, std::, <codecvt>)
+SYMBOL(codecvt_utf8_utf16, std::, <codecvt>)
+SYMBOL(collate, std::, <locale>)
+SYMBOL(collate_byname, std::, <locale>)
+SYMBOL(common_comparison_category, std::, <compare>)
+SYMBOL(common_comparison_category_t, std::, <compare>)
+SYMBOL(common_reference, std::, <type_traits>)
+SYMBOL(common_reference_t, std::, <type_traits>)
+SYMBOL(common_type, std::, <type_traits>)
+SYMBOL(common_type_t, std::, <type_traits>)
+SYMBOL(compare_3way, std::, <algorithm>)
+SYMBOL(complex, std::, <complex>)
+SYMBOL(condition_variable, std::, <condition_variable>)
+SYMBOL(condition_variable_any, std::, <condition_variable>)
+SYMBOL(conditional, std::, <type_traits>)
+SYMBOL(conditional_t, std::, <type_traits>)
+SYMBOL(conj, std::, <complex>)
+SYMBOL(conjunction, std::, <type_traits>)
+SYMBOL(conjunction_v, std::, <type_traits>)
+SYMBOL(const_pointer_cast, std::, <memory>)
+SYMBOL(contract_violation, std::, <contract>)
+SYMBOL(copy, std::, <algorithm>)
+SYMBOL(copy_backward, std::, <algorithm>)
+SYMBOL(copy_if, std::, <algorithm>)
+SYMBOL(copy_n, std::, <algorithm>)
+SYMBOL(copysign, std::, <cmath>)
+SYMBOL(cos, std::, <cmath>)
+SYMBOL(cosh, std::, <cmath>)
+SYMBOL(count, std::, <algorithm>)
+SYMBOL(count_if, std::, <algorithm>)
+SYMBOL(cout, std::, <iostream>)
+SYMBOL(crbegin, std::, <iterator>)
+SYMBOL(cref, std::, <functional>)
+SYMBOL(cregex_iterator, std::, <regex>)
+SYMBOL(cregex_token_iterator, std::, <regex>)
+SYMBOL(crend, std::, <iterator>)
+SYMBOL(csub_match, std::, <regex>)
+SYMBOL(ctime, std::, <ctime>)
+SYMBOL(ctype, std::, <locale>)
+SYMBOL(ctype_base, std::, <locale>)
+SYMBOL(ctype_byname, std::, <locale>)
+SYMBOL(current_exception, std::, <exception>)
+SYMBOL(cv_status, std::, <condition_variable>)
+SYMBOL(data, std::, <iterator>)
+SYMBOL(dec, std::, <ios>)
+SYMBOL(deca, std::, <ratio>)
+SYMBOL(decay, std::, <type_traits>)
+SYMBOL(decay_t, std::, <type_traits>)
+SYMBOL(deci, std::, <ratio>)
+SYMBOL(declare_no_pointers, std::, <memory>)
+SYMBOL(declare_reachable, std::, <memory>)
+SYMBOL(declval, std::, <utility>)
+SYMBOL(default_delete, std::, <memory>)
+SYMBOL(default_random_engine, std::, <random>)
+SYMBOL(default_searcher, std::, <functional>)
+SYMBOL(defaultfloat, std::, <ios>)
+SYMBOL(defer_lock, std::, <mutex>)
+SYMBOL(defer_lock_t, std::, <mutex>)
+SYMBOL(denorm_absent, std::, <limits>)
+SYMBOL(denorm_indeterminate, std::, <limits>)
+SYMBOL(denorm_present, std::, <limits>)
+SYMBOL(deque, std::, <deque>)
+SYMBOL(destroy, std::, <memory>)
+SYMBOL(destroy_at, std::, <memory>)
+SYMBOL(destroy_n, std::, <memory>)
+SYMBOL(destroying_delete, std::, <new>)
+SYMBOL(destroying_delete_t, std::, <new>)
+SYMBOL(difftime, std::, <ctime>)
+SYMBOL(discard_block_engine, std::, <random>)
+SYMBOL(discrete_distribution, std::, <random>)
+SYMBOL(disjunction, std::, <type_traits>)
+SYMBOL(disjunction_v, std::, <type_traits>)
+SYMBOL(distance, std::, <iterator>)
+SYMBOL(div_t, std::, <cstdlib>)
+SYMBOL(divides, std::, <functional>)
+SYMBOL(domain_error, std::, <stdexcept>)
+SYMBOL(double_t, std::, <cmath>)
+SYMBOL(dynamic_extent, std::, <span>)
+SYMBOL(dynamic_pointer_cast, std::, <memory>)
+SYMBOL(emit_on_flush, std::, <ostream>)
+SYMBOL(empty, std::, <iterator>)
+SYMBOL(enable_if, std::, <type_traits>)
+SYMBOL(enable_if_t, std::, <type_traits>)
+SYMBOL(enable_shared_from_this, std::, <memory>)
+SYMBOL(end, std::, <iterator>)
+SYMBOL(endian, std::, <type_traits>)
+SYMBOL(endl, std::, <ostream>)
+SYMBOL(ends, std::, <ostream>)
+SYMBOL(equal, std::, <algorithm>)
+SYMBOL(equal_range, std::, <algorithm>)
+SYMBOL(equal_to, std::, <functional>)
+SYMBOL(erf, std::, <cmath>)
+SYMBOL(erfc, std::, <cmath>)
+SYMBOL(errc, std::, <system_error>)
+SYMBOL(error_category, std::, <system_error>)
+SYMBOL(error_code, std::, <system_error>)
+SYMBOL(error_condition, std::, <system_error>)
+SYMBOL(exa, std::, <ratio>)
+SYMBOL(exception, std::, <exception>)
+SYMBOL(exception_ptr, std::, <exception>)
+SYMBOL(exchange, std::, <utility>)
+SYMBOL(exclusive_scan, std::, <numeric>)
+SYMBOL(exit, std::, <cstdlib>)
+SYMBOL(exp, std::, <cmath>)
+SYMBOL(exp2, std::, <cmath>)
+SYMBOL(expm1, std::, <cmath>)
+SYMBOL(exponential_distribution, std::, <random>)
+SYMBOL(extent, std::, <type_traits>)
+SYMBOL(extent_v, std::, <type_traits>)
+SYMBOL(extreme_value_distribution, std::, <random>)
+SYMBOL(false_type, std::, <type_traits>)
+SYMBOL(fclose, std::, <cstdio>)
+SYMBOL(fdim, std::, <cmath>)
+SYMBOL(feclearexcept, std::, <cfenv>)
+SYMBOL(fegetenv, std::, <cfenv>)
+SYMBOL(fegetexceptflag, std::, <cfenv>)
+SYMBOL(fegetround, std::, <cfenv>)
+SYMBOL(feholdexcept, std::, <cfenv>)
+SYMBOL(femto, std::, <ratio>)
+SYMBOL(fenv_t, std::, <cfenv>)
+SYMBOL(feof, std::, <cstdio>)
+SYMBOL(feraiseexcept, std::, <cfenv>)
+SYMBOL(ferror, std::, <cstdio>)
+SYMBOL(fesetenv, std::, <cfenv>)
+SYMBOL(fesetexceptflag, std::, <cfenv>)
+SYMBOL(fesetround, std::, <cfenv>)
+SYMBOL(fetestexcept, std::, <cfenv>)
+SYMBOL(feupdateenv, std::, <cfenv>)
+SYMBOL(fexcept_t, std::, <cfenv>)
+SYMBOL(fflush, std::, <cstdio>)
+SYMBOL(fgetc, std::, <cstdio>)
+SYMBOL(fgetpos, std::, <cstdio>)
+SYMBOL(fgets, std::, <cstdio>)
+SYMBOL(fgetwc, std::, <cwchar>)
+SYMBOL(fgetws, std::, <cwchar>)
+SYMBOL(filebuf, std::, <streambuf>)
+SYMBOL(fill, std::, <algorithm>)
+SYMBOL(fill_n, std::, <algorithm>)
+SYMBOL(find, std::, <algorithm>)
+SYMBOL(find_end, std::, <algorithm>)
+SYMBOL(find_first_of, std::, <algorithm>)
+SYMBOL(find_if, std::, <algorithm>)
+SYMBOL(find_if_not, std::, <algorithm>)
+SYMBOL(fisher_f_distribution, std::, <random>)
+SYMBOL(fixed, std::, <ios>)
+SYMBOL(float_denorm_style, std::, <limits>)
+SYMBOL(float_round_style, std::, <limits>)
+SYMBOL(float_t, std::, <cmath>)
+SYMBOL(floor, std::, <cmath>)
+SYMBOL(floor2, std::, <bit>)
+SYMBOL(flush, std::, <ostream>)
+SYMBOL(flush_emit, std::, <ostream>)
+SYMBOL(fma, std::, <cmath>)
+SYMBOL(fmax, std::, <cmath>)
+SYMBOL(fmin, std::, <cmath>)
+SYMBOL(fmod, std::, <cmath>)
+SYMBOL(fopen, std::, <cstdio>)
+SYMBOL(for_each, std::, <algorithm>)
+SYMBOL(for_each_n, std::, <algorithm>)
+SYMBOL(forward, std::, <utility>)
+SYMBOL(forward_as_tuple, std::, <tuple>)
+SYMBOL(forward_iterator_tag, std::, <iterator>)
+SYMBOL(forward_list, std::, <forward_list>)
+SYMBOL(fpclassify, std::, <cmath>)
+SYMBOL(fpos, std::, <ios>)
+SYMBOL(fpos_t, std::, <cstdio>)
+SYMBOL(fprintf, std::, <cstdio>)
+SYMBOL(fputc, std::, <cstdio>)
+SYMBOL(fputs, std::, <cstdio>)
+SYMBOL(fputwc, std::, <cwchar>)
+SYMBOL(fputws, std::, <cwchar>)
+SYMBOL(fread, std::, <cstdio>)
+SYMBOL(free, std::, <cstdlib>)
+SYMBOL(freopen, std::, <cstdio>)
+SYMBOL(frexp, std::, <cmath>)
+SYMBOL(from_chars, std::, <charconv>)
+SYMBOL(front_insert_iterator, std::, <iterator>)
+SYMBOL(front_inserter, std::, <iterator>)
+SYMBOL(fscanf, std::, <cstdio>)
+SYMBOL(fseek, std::, <cstdio>)
+SYMBOL(fsetpos, std::, <cstdio>)
+SYMBOL(fstream, std::, <fstream>)
+SYMBOL(ftell, std::, <cstdio>)
+SYMBOL(function, std::, <functional>)
+SYMBOL(future, std::, <future>)
+SYMBOL(future_category, std::, <future>)
+SYMBOL(future_errc, std::, <future>)
+SYMBOL(future_error, std::, <future>)
+SYMBOL(future_status, std::, <future>)
+SYMBOL(fwide, std::, <cwchar>)
+SYMBOL(fwprintf, std::, <cwchar>)
+SYMBOL(fwrite, std::, <cstdio>)
+SYMBOL(fwscanf, std::, <cwchar>)
+SYMBOL(gamma_distribution, std::, <random>)
+SYMBOL(gcd, std::, <numeric>)
+SYMBOL(generate, std::, <algorithm>)
+SYMBOL(generate_canonical, std::, <random>)
+SYMBOL(generate_n, std::, <algorithm>)
+SYMBOL(generic_category, std::, <system_error>)
+SYMBOL(geometric_distribution, std::, <random>)
+SYMBOL(get_if, std::, <variant>)
+SYMBOL(get_money, std::, <iomanip>)
+SYMBOL(get_new_handler, std::, <new>)
+SYMBOL(get_pointer_safety, std::, <memory>)
+SYMBOL(get_terminate, std::, <exception>)
+SYMBOL(get_time, std::, <iomanip>)
+SYMBOL(getc, std::, <cstdio>)
+SYMBOL(getchar, std::, <cstdio>)
+SYMBOL(getenv, std::, <cstdlib>)
+SYMBOL(gets, std::, <cstdio>)
+SYMBOL(getwc, std::, <cwchar>)
+SYMBOL(getwchar, std::, <cwchar>)
+SYMBOL(giga, std::, <ratio>)
+SYMBOL(gmtime, std::, <ctime>)
+SYMBOL(greater, std::, <functional>)
+SYMBOL(greater_equal, std::, <functional>)
+SYMBOL(gslice, std::, <valarray>)
+SYMBOL(gslice_array, std::, <valarray>)
+SYMBOL(hardware_constructive_interference_size, std::, <new>)
+SYMBOL(hardware_destructive_interference_size, std::, <new>)
+SYMBOL(has_facet, std::, <locale>)
+SYMBOL(has_unique_object_representations, std::, <type_traits>)
+SYMBOL(has_unique_object_representations_v, std::, <type_traits>)
+SYMBOL(has_virtual_destructor, std::, <type_traits>)
+SYMBOL(has_virtual_destructor_v, std::, <type_traits>)
+SYMBOL(hash, std::, <functional>)
+SYMBOL(hecto, std::, <ratio>)
+SYMBOL(hex, std::, <ios>)
+SYMBOL(hexfloat, std::, <ios>)
+SYMBOL(holds_alternative, std::, <variant>)
+SYMBOL(hypot, std::, <cmath>)
+SYMBOL(identity, std::, <functional>)
+SYMBOL(ifstream, std::, <fstream>)
+SYMBOL(ignore, std::, <tuple>)
+SYMBOL(ilogb, std::, <cmath>)
+SYMBOL(imag, std::, <complex>)
+SYMBOL(imaxabs, std::, <cinttypes>)
+SYMBOL(imaxdiv, std::, <cinttypes>)
+SYMBOL(imaxdiv_t, std::, <cinttypes>)
+SYMBOL(in_place, std::, <utility>)
+SYMBOL(in_place_index, std::, <utility>)
+SYMBOL(in_place_index_t, std::, <utility>)
+SYMBOL(in_place_t, std::, <utility>)
+SYMBOL(in_place_type, std::, <utility>)
+SYMBOL(in_place_type_t, std::, <utility>)
+SYMBOL(includes, std::, <algorithm>)
+SYMBOL(inclusive_scan, std::, <numeric>)
+SYMBOL(independent_bits_engine, std::, <random>)
+SYMBOL(indirect_array, std::, <valarray>)
+SYMBOL(inner_product, std::, <numeric>)
+SYMBOL(inplace_merge, std::, <algorithm>)
+SYMBOL(input_iterator_tag, std::, <iterator>)
+SYMBOL(insert_iterator, std::, <iterator>)
+SYMBOL(inserter, std::, <iterator>)
+SYMBOL(integer_sequence, std::, <utility>)
+SYMBOL(integral_constant, std::, <type_traits>)
+SYMBOL(internal, std::, <ios>)
+SYMBOL(intmax_t, std::, <cstdint>)
+SYMBOL(intptr_t, std::, <cstdint>)
+SYMBOL(invalid_argument, std::, <stdexcept>)
+SYMBOL(invoke, std::, <functional>)
+SYMBOL(invoke_result, std::, <type_traits>)
+SYMBOL(invoke_result_t, std::, <type_traits>)
+SYMBOL(io_errc, std::, <ios>)
+SYMBOL(ios, std::, <ios>)
+SYMBOL(ios_base, std::, <ios>)
+SYMBOL(iostream, std::, <istream>)
+SYMBOL(iostream_category, std::, <ios>)
+SYMBOL(iota, std::, <numeric>)
+SYMBOL(is_abstract, std::, <type_traits>)
+SYMBOL(is_abstract_v, std::, <type_traits>)
+SYMBOL(is_aggregate, std::, <type_traits>)
+SYMBOL(is_aggregate_v, std::, <type_traits>)
+SYMBOL(is_arithmetic, std::, <type_traits>)
+SYMBOL(is_arithmetic_v, std::, <type_traits>)
+SYMBOL(is_array, std::, <type_traits>)
+SYMBOL(is_array_v, std::, <type_traits>)
+SYMBOL(is_assignable, std::, <type_traits>)
+SYMBOL(is_assignable_v, std::, <type_traits>)
+SYMBOL(is_base_of, std::, <type_traits>)
+SYMBOL(is_base_of_v, std::, <type_traits>)
+SYMBOL(is_bind_expression, std::, <functional>)
+SYMBOL(is_bind_expression_v, std::, <functional>)
+SYMBOL(is_class, std::, <type_traits>)
+SYMBOL(is_class_v, std::, <type_traits>)
+SYMBOL(is_compound, std::, <type_traits>)
+SYMBOL(is_compound_v, std::, <type_traits>)
+SYMBOL(is_const, std::, <type_traits>)
+SYMBOL(is_const_v, std::, <type_traits>)
+SYMBOL(is_constructible, std::, <type_traits>)
+SYMBOL(is_constructible_v, std::, <type_traits>)
+SYMBOL(is_convertible, std::, <type_traits>)
+SYMBOL(is_convertible_v, std::, <type_traits>)
+SYMBOL(is_copy_assignable, std::, <type_traits>)
+SYMBOL(is_copy_assignable_v, std::, <type_traits>)
+SYMBOL(is_copy_constructible, std::, <type_traits>)
+SYMBOL(is_copy_constructible_v, std::, <type_traits>)
+SYMBOL(is_default_constructible, std::, <type_traits>)
+SYMBOL(is_default_constructible_v, std::, <type_traits>)
+SYMBOL(is_destructible, std::, <type_traits>)
+SYMBOL(is_destructible_v, std::, <type_traits>)
+SYMBOL(is_empty, std::, <type_traits>)
+SYMBOL(is_empty_v, std::, <type_traits>)
+SYMBOL(is_enum, std::, <type_traits>)
+SYMBOL(is_enum_v, std::, <type_traits>)
+SYMBOL(is_eq, std::, <compare>)
+SYMBOL(is_error_code_enum, std::, <system_error>)
+SYMBOL(is_error_condition_enum, std::, <system_error>)
+SYMBOL(is_error_condition_enum_v, std::, <system_error>)
+SYMBOL(is_execution_policy, std::, <execution>)
+SYMBOL(is_execution_policy_v, std::, <execution>)
+SYMBOL(is_final, std::, <type_traits>)
+SYMBOL(is_final_v, std::, <type_traits>)
+SYMBOL(is_floating_point, std::, <type_traits>)
+SYMBOL(is_floating_point_v, std::, <type_traits>)
+SYMBOL(is_function, std::, <type_traits>)
+SYMBOL(is_function_v, std::, <type_traits>)
+SYMBOL(is_fundamental, std::, <type_traits>)
+SYMBOL(is_fundamental_v, std::, <type_traits>)
+SYMBOL(is_gt, std::, <compare>)
+SYMBOL(is_gteq, std::, <compare>)
+SYMBOL(is_heap, std::, <algorithm>)
+SYMBOL(is_heap_until, std::, <algorithm>)
+SYMBOL(is_integral, std::, <type_traits>)
+SYMBOL(is_integral_v, std::, <type_traits>)
+SYMBOL(is_invocable, std::, <type_traits>)
+SYMBOL(is_invocable_r, std::, <type_traits>)
+SYMBOL(is_invocable_r_v, std::, <type_traits>)
+SYMBOL(is_invocable_v, std::, <type_traits>)
+SYMBOL(is_lt, std::, <compare>)
+SYMBOL(is_lteq, std::, <compare>)
+SYMBOL(is_lvalue_reference, std::, <type_traits>)
+SYMBOL(is_lvalue_reference_v, std::, <type_traits>)
+SYMBOL(is_member_function_pointer, std::, <type_traits>)
+SYMBOL(is_member_function_pointer_v, std::, <type_traits>)
+SYMBOL(is_member_object_pointer, std::, <type_traits>)
+SYMBOL(is_member_object_pointer_v, std::, <type_traits>)
+SYMBOL(is_member_pointer, std::, <type_traits>)
+SYMBOL(is_member_pointer_v, std::, <type_traits>)
+SYMBOL(is_move_assignable, std::, <type_traits>)
+SYMBOL(is_move_assignable_v, std::, <type_traits>)
+SYMBOL(is_move_constructible, std::, <type_traits>)
+SYMBOL(is_move_constructible_v, std::, <type_traits>)
+SYMBOL(is_neq, std::, <compare>)
+SYMBOL(is_nothrow_assignable, std::, <type_traits>)
+SYMBOL(is_nothrow_assignable_v, std::, <type_traits>)
+SYMBOL(is_nothrow_constructible, std::, <type_traits>)
+SYMBOL(is_nothrow_constructible_v, std::, <type_traits>)
+SYMBOL(is_nothrow_copy_assignable, std::, <type_traits>)
+SYMBOL(is_nothrow_copy_assignable_v, std::, <type_traits>)
+SYMBOL(is_nothrow_copy_constructible, std::, <type_traits>)
+SYMBOL(is_nothrow_copy_constructible_v, std::, <type_traits>)
+SYMBOL(is_nothrow_default_constructible, std::, <type_traits>)
+SYMBOL(is_nothrow_default_constructible_v, std::, <type_traits>)
+SYMBOL(is_nothrow_destructible, std::, <type_traits>)
+SYMBOL(is_nothrow_destructible_v, std::, <type_traits>)
+SYMBOL(is_nothrow_invocable, std::, <type_traits>)
+SYMBOL(is_nothrow_invocable_r, std::, <type_traits>)
+SYMBOL(is_nothrow_invocable_r_v, std::, <type_traits>)
+SYMBOL(is_nothrow_invocable_v, std::, <type_traits>)
+SYMBOL(is_nothrow_move_assignable, std::, <type_traits>)
+SYMBOL(is_nothrow_move_assignable_v, std::, <type_traits>)
+SYMBOL(is_nothrow_move_constructible, std::, <type_traits>)
+SYMBOL(is_nothrow_move_constructible_v, std::, <type_traits>)
+SYMBOL(is_nothrow_swappable, std::, <type_traits>)
+SYMBOL(is_nothrow_swappable_v, std::, <type_traits>)
+SYMBOL(is_nothrow_swappable_with, std::, <type_traits>)
+SYMBOL(is_nothrow_swappable_with_v, std::, <type_traits>)
+SYMBOL(is_null_pointer, std::, <type_traits>)
+SYMBOL(is_null_pointer_v, std::, <type_traits>)
+SYMBOL(is_object, std::, <type_traits>)
+SYMBOL(is_object_v, std::, <type_traits>)
+SYMBOL(is_partitioned, std::, <algorithm>)
+SYMBOL(is_permutation, std::, <algorithm>)
+SYMBOL(is_placeholder, std::, <functional>)
+SYMBOL(is_placeholder_v, std::, <functional>)
+SYMBOL(is_pod, std::, <type_traits>)
+SYMBOL(is_pod_v, std::, <type_traits>)
+SYMBOL(is_pointer, std::, <type_traits>)
+SYMBOL(is_pointer_v, std::, <type_traits>)
+SYMBOL(is_polymorphic, std::, <type_traits>)
+SYMBOL(is_polymorphic_v, std::, <type_traits>)
+SYMBOL(is_reference, std::, <type_traits>)
+SYMBOL(is_reference_v, std::, <type_traits>)
+SYMBOL(is_rvalue_reference, std::, <type_traits>)
+SYMBOL(is_rvalue_reference_v, std::, <type_traits>)
+SYMBOL(is_same, std::, <type_traits>)
+SYMBOL(is_same_v, std::, <type_traits>)
+SYMBOL(is_scalar, std::, <type_traits>)
+SYMBOL(is_scalar_v, std::, <type_traits>)
+SYMBOL(is_signed, std::, <type_traits>)
+SYMBOL(is_signed_v, std::, <type_traits>)
+SYMBOL(is_sorted, std::, <algorithm>)
+SYMBOL(is_sorted_until, std::, <algorithm>)
+SYMBOL(is_standard_layout, std::, <type_traits>)
+SYMBOL(is_standard_layout_v, std::, <type_traits>)
+SYMBOL(is_swappable, std::, <type_traits>)
+SYMBOL(is_swappable_v, std::, <type_traits>)
+SYMBOL(is_swappable_with, std::, <type_traits>)
+SYMBOL(is_swappable_with_v, std::, <type_traits>)
+SYMBOL(is_trivial, std::, <type_traits>)
+SYMBOL(is_trivial_v, std::, <type_traits>)
+SYMBOL(is_trivially_assignable, std::, <type_traits>)
+SYMBOL(is_trivially_assignable_v, std::, <type_traits>)
+SYMBOL(is_trivially_constructible, std::, <type_traits>)
+SYMBOL(is_trivially_constructible_v, std::, <type_traits>)
+SYMBOL(is_trivially_copy_assignable, std::, <type_traits>)
+SYMBOL(is_trivially_copy_assignable_v, std::, <type_traits>)
+SYMBOL(is_trivially_copy_constructible, std::, <type_traits>)
+SYMBOL(is_trivially_copy_constructible_v, std::, <type_traits>)
+SYMBOL(is_trivially_copyable, std::, <type_traits>)
+SYMBOL(is_trivially_copyable_v, std::, <type_traits>)
+SYMBOL(is_trivially_default_constructible, std::, <type_traits>)
+SYMBOL(is_trivially_default_constructible_v, std::, <type_traits>)
+SYMBOL(is_trivially_destructible, std::, <type_traits>)
+SYMBOL(is_trivially_destructible_v, std::, <type_traits>)
+SYMBOL(is_trivially_move_assignable, std::, <type_traits>)
+SYMBOL(is_trivially_move_assignable_v, std::, <type_traits>)
+SYMBOL(is_trivially_move_constructible, std::, <type_traits>)
+SYMBOL(is_trivially_move_constructible_v, std::, <type_traits>)
+SYMBOL(is_union, std::, <type_traits>)
+SYMBOL(is_union_v, std::, <type_traits>)
+SYMBOL(is_unsigned, std::, <type_traits>)
+SYMBOL(is_unsigned_v, std::, <type_traits>)
+SYMBOL(is_void, std::, <type_traits>)
+SYMBOL(is_void_v, std::, <type_traits>)
+SYMBOL(is_volatile, std::, <type_traits>)
+SYMBOL(is_volatile_v, std::, <type_traits>)
+SYMBOL(isalnum, std::, <cctype>)
+SYMBOL(isalpha, std::, <cctype>)
+SYMBOL(isblank, std::, <cctype>)
+SYMBOL(iscntrl, std::, <cctype>)
+SYMBOL(isdigit, std::, <cctype>)
+SYMBOL(isfinite, std::, <cmath>)
+SYMBOL(isgraph, std::, <cctype>)
+SYMBOL(isgreater, std::, <cmath>)
+SYMBOL(isgreaterequal, std::, <cmath>)
+SYMBOL(isinf, std::, <cmath>)
+SYMBOL(isless, std::, <cmath>)
+SYMBOL(islessequal, std::, <cmath>)
+SYMBOL(islessgreater, std::, <cmath>)
+SYMBOL(islower, std::, <cctype>)
+SYMBOL(isnan, std::, <cmath>)
+SYMBOL(isnormal, std::, <cmath>)
+SYMBOL(ispow2, std::, <bit>)
+SYMBOL(isprint, std::, <cctype>)
+SYMBOL(ispunct, std::, <cctype>)
+SYMBOL(isspace, std::, <cctype>)
+SYMBOL(istream, std::, <istream>)
+SYMBOL(istream_iterator, std::, <iterator>)
+SYMBOL(istreambuf_iterator, std::, <iterator>)
+SYMBOL(istringstream, std::, <sstream>)
+SYMBOL(isunordered, std::, <cmath>)
+SYMBOL(isupper, std::, <cctype>)
+SYMBOL(iswalnum, std::, <cwctype>)
+SYMBOL(iswalpha, std::, <cwctype>)
+SYMBOL(iswblank, std::, <cwctype>)
+SYMBOL(iswcntrl, std::, <cwctype>)
+SYMBOL(iswctype, std::, <cwctype>)
+SYMBOL(iswdigit, std::, <cwctype>)
+SYMBOL(iswgraph, std::, <cwctype>)
+SYMBOL(iswlower, std::, <cwctype>)
+SYMBOL(iswprint, std::, <cwctype>)
+SYMBOL(iswpunct, std::, <cwctype>)
+SYMBOL(iswspace, std::, <cwctype>)
+SYMBOL(iswupper, std::, <cwctype>)
+SYMBOL(iswxdigit, std::, <cwctype>)
+SYMBOL(isxdigit, std::, <cctype>)
+SYMBOL(iter_swap, std::, <algorithm>)
+SYMBOL(iterator, std::, <iterator>)
+SYMBOL(iterator_traits, std::, <iterator>)
+SYMBOL(jmp_buf, std::, <csetjmp>)
+SYMBOL(kill_dependency, std::, <atomic>)
+SYMBOL(kilo, std::, <ratio>)
+SYMBOL(knuth_b, std::, <random>)
+SYMBOL(labs, std::, <cstdlib>)
+SYMBOL(launch, std::, <future>)
+SYMBOL(launder, std::, <new>)
+SYMBOL(lcm, std::, <numeric>)
+SYMBOL(lconv, std::, <clocale>)
+SYMBOL(ldexp, std::, <cmath>)
+SYMBOL(ldiv, std::, <cstdlib>)
+SYMBOL(ldiv_t, std::, <cstdlib>)
+SYMBOL(left, std::, <ios>)
+SYMBOL(length_error, std::, <stdexcept>)
+SYMBOL(less, std::, <functional>)
+SYMBOL(less_equal, std::, <functional>)
+SYMBOL(lexicographical_compare, std::, <algorithm>)
+SYMBOL(lexicographical_compare_3way, std::, <algorithm>)
+SYMBOL(lgamma, std::, <cmath>)
+SYMBOL(linear_congruential_engine, std::, <random>)
+SYMBOL(list, std::, <list>)
+SYMBOL(llabs, std::, <cstdlib>)
+SYMBOL(lldiv, std::, <cstdlib>)
+SYMBOL(lldiv_t, std::, <cstdlib>)
+SYMBOL(llrint, std::, <cmath>)
+SYMBOL(llround, std::, <cmath>)
+SYMBOL(locale, std::, <locale>)
+SYMBOL(localeconv, std::, <clocale>)
+SYMBOL(localtime, std::, <ctime>)
+SYMBOL(lock, std::, <mutex>)
+SYMBOL(lock_guard, std::, <mutex>)
+SYMBOL(log, std::, <cmath>)
+SYMBOL(log10, std::, <cmath>)
+SYMBOL(log1p, std::, <cmath>)
+SYMBOL(log2, std::, <cmath>)
+SYMBOL(log2p1, std::, <bit>)
+SYMBOL(logb, std::, <cmath>)
+SYMBOL(logic_error, std::, <stdexcept>)
+SYMBOL(logical_and, std::, <functional>)
+SYMBOL(logical_not, std::, <functional>)
+SYMBOL(logical_or, std::, <functional>)
+SYMBOL(lognormal_distribution, std::, <random>)
+SYMBOL(longjmp, std::, <csetjmp>)
+SYMBOL(lower_bound, std::, <algorithm>)
+SYMBOL(lrint, std::, <cmath>)
+SYMBOL(lround, std::, <cmath>)
+SYMBOL(make_exception_ptr, std::, <exception>)
+SYMBOL(make_from_tuple, std::, <tuple>)
+SYMBOL(make_heap, std::, <algorithm>)
+SYMBOL(make_move_iterator, std::, <iterator>)
+SYMBOL(make_optional, std::, <optional>)
+SYMBOL(make_pair, std::, <utility>)
+SYMBOL(make_reverse_iterator, std::, <iterator>)
+SYMBOL(make_shared, std::, <memory>)
+SYMBOL(make_signed, std::, <type_traits>)
+SYMBOL(make_signed_t, std::, <type_traits>)
+SYMBOL(make_tuple, std::, <tuple>)
+SYMBOL(make_unique, std::, <memory>)
+SYMBOL(make_unsigned, std::, <type_traits>)
+SYMBOL(make_unsigned_t, std::, <type_traits>)
+SYMBOL(malloc, std::, <cstdlib>)
+SYMBOL(map, std::, <map>)
+SYMBOL(mask_array, std::, <valarray>)
+SYMBOL(match_results, std::, <regex>)
+SYMBOL(max, std::, <algorithm>)
+SYMBOL(max_align_t, std::, <cstddef>)
+SYMBOL(max_element, std::, <algorithm>)
+SYMBOL(mblen, std::, <cstdlib>)
+SYMBOL(mbrlen, std::, <cwchar>)
+SYMBOL(mbrtoc16, std::, <cuchar>)
+SYMBOL(mbrtoc32, std::, <cuchar>)
+SYMBOL(mbrtowc, std::, <cwchar>)
+SYMBOL(mbsinit, std::, <cwchar>)
+SYMBOL(mbsrtowcs, std::, <cwchar>)
+SYMBOL(mbstowcs, std::, <cstdlib>)
+SYMBOL(mbtowc, std::, <cstdlib>)
+SYMBOL(mega, std::, <ratio>)
+SYMBOL(mem_fn, std::, <functional>)
+SYMBOL(memchr, std::, <cstring>)
+SYMBOL(memcmp, std::, <cstring>)
+SYMBOL(memcpy, std::, <cstring>)
+SYMBOL(memmove, std::, <cstring>)
+SYMBOL(memory_order, std::, <atomic>)
+SYMBOL(memory_order_acq_rel, std::, <atomic>)
+SYMBOL(memory_order_acquire, std::, <atomic>)
+SYMBOL(memory_order_consume, std::, <atomic>)
+SYMBOL(memory_order_relaxed, std::, <atomic>)
+SYMBOL(memory_order_release, std::, <atomic>)
+SYMBOL(memory_order_seq_cst, std::, <atomic>)
+SYMBOL(memset, std::, <cstring>)
+SYMBOL(merge, std::, <algorithm>)
+SYMBOL(mersenne_twister_engine, std::, <random>)
+SYMBOL(messages, std::, <locale>)
+SYMBOL(messages_base, std::, <locale>)
+SYMBOL(messages_byname, std::, <locale>)
+SYMBOL(micro, std::, <ratio>)
+SYMBOL(milli, std::, <ratio>)
+SYMBOL(min, std::, <algorithm>)
+SYMBOL(min_element, std::, <algorithm>)
+SYMBOL(minmax, std::, <algorithm>)
+SYMBOL(minmax_element, std::, <algorithm>)
+SYMBOL(minstd_rand, std::, <random>)
+SYMBOL(minstd_rand0, std::, <random>)
+SYMBOL(minus, std::, <functional>)
+SYMBOL(mismatch, std::, <algorithm>)
+SYMBOL(mktime, std::, <ctime>)
+SYMBOL(modf, std::, <cmath>)
+SYMBOL(modulus, std::, <functional>)
+SYMBOL(money_base, std::, <locale>)
+SYMBOL(money_get, std::, <locale>)
+SYMBOL(money_put, std::, <locale>)
+SYMBOL(moneypunct, std::, <locale>)
+SYMBOL(moneypunct_byname, std::, <locale>)
+SYMBOL(monostate, std::, <variant>)
+SYMBOL(move_backward, std::, <algorithm>)
+SYMBOL(move_if_noexcept, std::, <utility>)
+SYMBOL(move_iterator, std::, <iterator>)
+SYMBOL(mt19937, std::, <random>)
+SYMBOL(mt19937_64, std::, <random>)
+SYMBOL(multimap, std::, <map>)
+SYMBOL(multiplies, std::, <functional>)
+SYMBOL(multiset, std::, <set>)
+SYMBOL(mutex, std::, <mutex>)
+SYMBOL(nan, std::, <cmath>)
+SYMBOL(nanf, std::, <cmath>)
+SYMBOL(nanl, std::, <cmath>)
+SYMBOL(nano, std::, <ratio>)
+SYMBOL(nearbyint, std::, <cmath>)
+SYMBOL(negate, std::, <functional>)
+SYMBOL(negation, std::, <type_traits>)
+SYMBOL(negation_v, std::, <type_traits>)
+SYMBOL(negative_binomial_distribution, std::, <random>)
+SYMBOL(nested_exception, std::, <exception>)
+SYMBOL(new_handler, std::, <new>)
+SYMBOL(next, std::, <iterator>)
+SYMBOL(next_permutation, std::, <algorithm>)
+SYMBOL(nextafter, std::, <cmath>)
+SYMBOL(nexttoward, std::, <cmath>)
+SYMBOL(no_emit_on_flush, std::, <ostream>)
+SYMBOL(noboolalpha, std::, <ios>)
+SYMBOL(none_of, std::, <algorithm>)
+SYMBOL(norm, std::, <complex>)
+SYMBOL(normal_distribution, std::, <random>)
+SYMBOL(noshowbase, std::, <ios>)
+SYMBOL(noshowpoint, std::, <ios>)
+SYMBOL(noshowpos, std::, <ios>)
+SYMBOL(noskipws, std::, <ios>)
+SYMBOL(not_equal_to, std::, <functional>)
+SYMBOL(not_fn, std::, <functional>)
+SYMBOL(nothrow, std::, <new>)
+SYMBOL(nothrow_t, std::, <new>)
+SYMBOL(notify_all_at_thread_exit, std::, <condition_variable>)
+SYMBOL(nounitbuf, std::, <ios>)
+SYMBOL(nouppercase, std::, <ios>)
+SYMBOL(nth_element, std::, <algorithm>)
+SYMBOL(nullopt, std::, <optional>)
+SYMBOL(nullopt_t, std::, <optional>)
+SYMBOL(nullptr_t, std::, <cstddef>)
+SYMBOL(num_get, std::, <locale>)
+SYMBOL(num_put, std::, <locale>)
+SYMBOL(numeric_limits, std::, <limits>)
+SYMBOL(numpunct, std::, <locale>)
+SYMBOL(numpunct_byname, std::, <locale>)
+SYMBOL(oct, std::, <ios>)
+SYMBOL(ofstream, std::, <fstream>)
+SYMBOL(once_flag, std::, <mutex>)
+SYMBOL(optional, std::, <optional>)
+SYMBOL(ostream, std::, <ostream>)
+SYMBOL(ostream_iterator, std::, <iterator>)
+SYMBOL(ostreambuf_iterator, std::, <iterator>)
+SYMBOL(ostringstream, std::, <sstream>)
+SYMBOL(osyncstream, std::, <syncstream>)
+SYMBOL(out_of_range, std::, <stdexcept>)
+SYMBOL(output_iterator_tag, std::, <iterator>)
+SYMBOL(overflow_error, std::, <stdexcept>)
+SYMBOL(owner_less, std::, <memory>)
+SYMBOL(packaged_task, std::, <future>)
+SYMBOL(pair, std::, <utility>)
+SYMBOL(partial_order, std::, <compare>)
+SYMBOL(partial_ordering, std::, <compare>)
+SYMBOL(partial_sort, std::, <algorithm>)
+SYMBOL(partial_sort_copy, std::, <algorithm>)
+SYMBOL(partial_sum, std::, <numeric>)
+SYMBOL(partition, std::, <algorithm>)
+SYMBOL(partition_copy, std::, <algorithm>)
+SYMBOL(partition_point, std::, <algorithm>)
+SYMBOL(perror, std::, <cstdio>)
+SYMBOL(peta, std::, <ratio>)
+SYMBOL(pico, std::, <ratio>)
+SYMBOL(piecewise_constant_distribution, std::, <random>)
+SYMBOL(piecewise_construct_t, std::, <utility>)
+SYMBOL(piecewise_linear_distribution, std::, <random>)
+SYMBOL(plus, std::, <functional>)
+SYMBOL(pointer_safety, std::, <memory>)
+SYMBOL(pointer_traits, std::, <memory>)
+SYMBOL(poisson_distribution, std::, <random>)
+SYMBOL(polar, std::, <complex>)
+SYMBOL(polymorphic_allocator, std::, <memory_resource>)
+SYMBOL(pop_heap, std::, <algorithm>)
+SYMBOL(pow, std::, <cmath>)
+SYMBOL(prev, std::, <iterator>)
+SYMBOL(prev_permutation, std::, <algorithm>)
+SYMBOL(printf, std::, <cstdio>)
+SYMBOL(priority_queue, std::, <queue>)
+SYMBOL(proj, std::, <complex>)
+SYMBOL(promise, std::, <future>)
+SYMBOL(ptrdiff_t, std::, <cstddef>)
+SYMBOL(push_heap, std::, <algorithm>)
+SYMBOL(put_money, std::, <iomanip>)
+SYMBOL(put_time, std::, <iomanip>)
+SYMBOL(putc, std::, <cstdio>)
+SYMBOL(putchar, std::, <cstdio>)
+SYMBOL(puts, std::, <cstdio>)
+SYMBOL(putwc, std::, <cwchar>)
+SYMBOL(putwchar, std::, <cwchar>)
+SYMBOL(qsort, std::, <cstdlib>)
+SYMBOL(queue, std::, <queue>)
+SYMBOL(quick_exit, std::, <cstdlib>)
+SYMBOL(quoted, std::, <iomanip>)
+SYMBOL(raise, std::, <csignal>)
+SYMBOL(rand, std::, <cstdlib>)
+SYMBOL(random_access_iterator_tag, std::, <iterator>)
+SYMBOL(random_device, std::, <random>)
+SYMBOL(random_shuffle, std::, <algorithm>)
+SYMBOL(range_error, std::, <stdexcept>)
+SYMBOL(rank, std::, <type_traits>)
+SYMBOL(rank_v, std::, <type_traits>)
+SYMBOL(ranlux24, std::, <random>)
+SYMBOL(ranlux24_base, std::, <random>)
+SYMBOL(ranlux48, std::, <random>)
+SYMBOL(ranlux48_base, std::, <random>)
+SYMBOL(ratio, std::, <ratio>)
+SYMBOL(ratio_add, std::, <ratio>)
+SYMBOL(ratio_divide, std::, <ratio>)
+SYMBOL(ratio_equal, std::, <ratio>)
+SYMBOL(ratio_equal_v, std::, <ratio>)
+SYMBOL(ratio_greater, std::, <ratio>)
+SYMBOL(ratio_greater_equal, std::, <ratio>)
+SYMBOL(ratio_greater_equal_v, std::, <ratio>)
+SYMBOL(ratio_greater_v, std::, <ratio>)
+SYMBOL(ratio_less, std::, <ratio>)
+SYMBOL(ratio_less_equal, std::, <ratio>)
+SYMBOL(ratio_less_equal_v, std::, <ratio>)
+SYMBOL(ratio_less_v, std::, <ratio>)
+SYMBOL(ratio_multiply, std::, <ratio>)
+SYMBOL(ratio_not_equal, std::, <ratio>)
+SYMBOL(ratio_not_equal_v, std::, <ratio>)
+SYMBOL(ratio_subtract, std::, <ratio>)
+SYMBOL(rbegin, std::, <iterator>)
+SYMBOL(real, std::, <complex>)
+SYMBOL(realloc, std::, <cstdlib>)
+SYMBOL(recursive_mutex, std::, <mutex>)
+SYMBOL(recursive_timed_mutex, std::, <mutex>)
+SYMBOL(reduce, std::, <numeric>)
+SYMBOL(ref, std::, <functional>)
+SYMBOL(reference_wrapper, std::, <functional>)
+SYMBOL(regex, std::, <regex>)
+SYMBOL(regex_error, std::, <regex>)
+SYMBOL(regex_iterator, std::, <regex>)
+SYMBOL(regex_match, std::, <regex>)
+SYMBOL(regex_replace, std::, <regex>)
+SYMBOL(regex_search, std::, <regex>)
+SYMBOL(regex_token_iterator, std::, <regex>)
+SYMBOL(regex_traits, std::, <regex>)
+SYMBOL(reinterpret_pointer_cast, std::, <memory>)
+SYMBOL(remainder, std::, <cmath>)
+SYMBOL(remove, std::, <cstdio>)
+SYMBOL(remove_all_extents, std::, <type_traits>)
+SYMBOL(remove_all_extents_t, std::, <type_traits>)
+SYMBOL(remove_const, std::, <type_traits>)
+SYMBOL(remove_const_t, std::, <type_traits>)
+SYMBOL(remove_copy, std::, <algorithm>)
+SYMBOL(remove_copy_if, std::, <algorithm>)
+SYMBOL(remove_cv, std::, <type_traits>)
+SYMBOL(remove_cv_t, std::, <type_traits>)
+SYMBOL(remove_cvref, std::, <type_traits>)
+SYMBOL(remove_cvref_t, std::, <type_traits>)
+SYMBOL(remove_extent, std::, <type_traits>)
+SYMBOL(remove_extent_t, std::, <type_traits>)
+SYMBOL(remove_pointer, std::, <type_traits>)
+SYMBOL(remove_pointer_t, std::, <type_traits>)
+SYMBOL(remove_reference, std::, <type_traits>)
+SYMBOL(remove_reference_t, std::, <type_traits>)
+SYMBOL(remove_volatile, std::, <type_traits>)
+SYMBOL(remove_volatile_t, std::, <type_traits>)
+SYMBOL(remquo, std::, <cmath>)
+SYMBOL(rename, std::, <cstdio>)
+SYMBOL(rend, std::, <iterator>)
+SYMBOL(replace, std::, <algorithm>)
+SYMBOL(replace_copy, std::, <algorithm>)
+SYMBOL(replace_copy_if, std::, <algorithm>)
+SYMBOL(replace_if, std::, <algorithm>)
+SYMBOL(resetiosflags, std::, <iomanip>)
+SYMBOL(result_of, std::, <type_traits>)
+SYMBOL(result_of_t, std::, <type_traits>)
+SYMBOL(rethrow_exception, std::, <exception>)
+SYMBOL(rethrow_if_nested, std::, <exception>)
+SYMBOL(reverse, std::, <algorithm>)
+SYMBOL(reverse_copy, std::, <algorithm>)
+SYMBOL(reverse_iterator, std::, <iterator>)
+SYMBOL(rewind, std::, <cstdio>)
+SYMBOL(right, std::, <ios>)
+SYMBOL(rint, std::, <cmath>)
+SYMBOL(rotate, std::, <algorithm>)
+SYMBOL(rotate_copy, std::, <algorithm>)
+SYMBOL(round, std::, <cmath>)
+SYMBOL(round_indeterminate, std::, <limits>)
+SYMBOL(round_to_nearest, std::, <limits>)
+SYMBOL(round_toward_infinity, std::, <limits>)
+SYMBOL(round_toward_neg_infinity, std::, <limits>)
+SYMBOL(round_toward_zero, std::, <limits>)
+SYMBOL(runtime_error, std::, <stdexcept>)
+SYMBOL(sample, std::, <algorithm>)
+SYMBOL(scalbln, std::, <cmath>)
+SYMBOL(scalbn, std::, <cmath>)
+SYMBOL(scanf, std::, <cstdio>)
+SYMBOL(scientific, std::, <ios>)
+SYMBOL(scoped_allocator_adaptor, std::, <scoped_allocator>)
+SYMBOL(search, std::, <algorithm>)
+SYMBOL(search_n, std::, <algorithm>)
+SYMBOL(seed_seq, std::, <random>)
+SYMBOL(set, std::, <set>)
+SYMBOL(set_difference, std::, <algorithm>)
+SYMBOL(set_intersection, std::, <algorithm>)
+SYMBOL(set_new_handler, std::, <new>)
+SYMBOL(set_symmetric_difference, std::, <algorithm>)
+SYMBOL(set_terminate, std::, <exception>)
+SYMBOL(set_union, std::, <algorithm>)
+SYMBOL(setbase, std::, <iomanip>)
+SYMBOL(setbuf, std::, <cstdio>)
+SYMBOL(setfill, std::, <iomanip>)
+SYMBOL(setiosflags, std::, <iomanip>)
+SYMBOL(setlocale, std::, <clocale>)
+SYMBOL(setprecision, std::, <iomanip>)
+SYMBOL(setvbuf, std::, <cstdio>)
+SYMBOL(setw, std::, <iomanip>)
+SYMBOL(shared_future, std::, <future>)
+SYMBOL(shared_lock, std::, <shared_mutex>)
+SYMBOL(shared_mutex, std::, <shared_mutex>)
+SYMBOL(shared_ptr, std::, <memory>)
+SYMBOL(shared_timed_mutex, std::, <shared_mutex>)
+SYMBOL(shift_left, std::, <algorithm>)
+SYMBOL(shift_right, std::, <algorithm>)
+SYMBOL(showbase, std::, <ios>)
+SYMBOL(showpoint, std::, <ios>)
+SYMBOL(showpos, std::, <ios>)
+SYMBOL(shuffle, std::, <algorithm>)
+SYMBOL(shuffle_order_engine, std::, <random>)
+SYMBOL(sig_atomic_t, std::, <csignal>)
+SYMBOL(signal, std::, <csignal>)
+SYMBOL(signbit, std::, <cmath>)
+SYMBOL(sin, std::, <cmath>)
+SYMBOL(sinh, std::, <cmath>)
+SYMBOL(size, std::, <iterator>)
+SYMBOL(skipws, std::, <ios>)
+SYMBOL(slice, std::, <valarray>)
+SYMBOL(slice_array, std::, <valarray>)
+SYMBOL(smatch, std::, <regex>)
+SYMBOL(snprintf, std::, <cstdio>)
+SYMBOL(sort, std::, <algorithm>)
+SYMBOL(sort_heap, std::, <algorithm>)
+SYMBOL(span, std::, <span>)
+SYMBOL(sprintf, std::, <cstdio>)
+SYMBOL(sqrt, std::, <cmath>)
+SYMBOL(srand, std::, <cstdlib>)
+SYMBOL(sregex_iterator, std::, <regex>)
+SYMBOL(sregex_token_iterator, std::, <regex>)
+SYMBOL(sscanf, std::, <cstdio>)
+SYMBOL(ssub_match, std::, <regex>)
+SYMBOL(stable_partition, std::, <algorithm>)
+SYMBOL(stable_sort, std::, <algorithm>)
+SYMBOL(stack, std::, <stack>)
+SYMBOL(static_pointer_cast, std::, <memory>)
+SYMBOL(strcat, std::, <cstring>)
+SYMBOL(strchr, std::, <cstring>)
+SYMBOL(strcmp, std::, <cstring>)
+SYMBOL(strcoll, std::, <cstring>)
+SYMBOL(strcpy, std::, <cstring>)
+SYMBOL(strcspn, std::, <cstring>)
+SYMBOL(streambuf, std::, <streambuf>)
+SYMBOL(streamoff, std::, <ios>)
+SYMBOL(streampos, std::, <ios>)
+SYMBOL(streamsize, std::, <ios>)
+SYMBOL(strerror, std::, <cstring>)
+SYMBOL(strftime, std::, <ctime>)
+SYMBOL(string, std::, <string>)
+SYMBOL(string_view, std::, <string_view>)
+SYMBOL(stringbuf, std::, <sstream>)
+SYMBOL(stringstream, std::, <sstream>)
+SYMBOL(strlen, std::, <cstring>)
+SYMBOL(strncat, std::, <cstring>)
+SYMBOL(strncmp, std::, <cstring>)
+SYMBOL(strncpy, std::, <cstring>)
+SYMBOL(strong_equal, std::, <compare>)
+SYMBOL(strong_equality, std::, <compare>)
+SYMBOL(strong_order, std::, <compare>)
+SYMBOL(strong_ordering, std::, <compare>)
+SYMBOL(strpbrk, std::, <cstring>)
+SYMBOL(strrchr, std::, <cstring>)
+SYMBOL(strspn, std::, <cstring>)
+SYMBOL(strstr, std::, <cstring>)
+SYMBOL(strtod, std::, <cstdlib>)
+SYMBOL(strtof, std::, <cstdlib>)
+SYMBOL(strtoimax, std::, <cinttypes>)
+SYMBOL(strtok, std::, <cstring>)
+SYMBOL(strtol, std::, <cstdlib>)
+SYMBOL(strtold, std::, <cstdlib>)
+SYMBOL(strtoll, std::, <cstdlib>)
+SYMBOL(strtoul, std::, <cstdlib>)
+SYMBOL(strtoull, std::, <cstdlib>)
+SYMBOL(strtoumax, std::, <cinttypes>)
+SYMBOL(strxfrm, std::, <cstring>)
+SYMBOL(student_t_distribution, std::, <random>)
+SYMBOL(sub_match, std::, <regex>)
+SYMBOL(subtract_with_carry_engine, std::, <random>)
+SYMBOL(swap_ranges, std::, <algorithm>)
+SYMBOL(swprintf, std::, <cwchar>)
+SYMBOL(swscanf, std::, <cwchar>)
+SYMBOL(syncbuf, std::, <syncstream>)
+SYMBOL(system, std::, <cstdlib>)
+SYMBOL(system_category, std::, <system_error>)
+SYMBOL(system_error, std::, <system_error>)
+SYMBOL(tan, std::, <cmath>)
+SYMBOL(tanh, std::, <cmath>)
+SYMBOL(tera, std::, <ratio>)
+SYMBOL(terminate, std::, <exception>)
+SYMBOL(terminate_handler, std::, <exception>)
+SYMBOL(tgamma, std::, <cmath>)
+SYMBOL(thread, std::, <thread>)
+SYMBOL(throw_with_nested, std::, <exception>)
+SYMBOL(tie, std::, <tuple>)
+SYMBOL(time, std::, <ctime>)
+SYMBOL(time_base, std::, <locale>)
+SYMBOL(time_get, std::, <locale>)
+SYMBOL(time_get_byname, std::, <locale>)
+SYMBOL(time_put, std::, <locale>)
+SYMBOL(time_put_byname, std::, <locale>)
+SYMBOL(time_t, std::, <ctime>)
+SYMBOL(timed_mutex, std::, <mutex>)
+SYMBOL(timespec, std::, <ctime>)
+SYMBOL(timespec_get, std::, <ctime>)
+SYMBOL(tm, std::, <ctime>)
+SYMBOL(tmpfile, std::, <cstdio>)
+SYMBOL(tmpnam, std::, <cstdio>)
+SYMBOL(to_address, std::, <memory>)
+SYMBOL(to_chars, std::, <charconv>)
+SYMBOL(to_integer, std::, <cstddef>)
+SYMBOL(to_string, std::, <string>)
+SYMBOL(tolower, std::, <cctype>)
+SYMBOL(toupper, std::, <cctype>)
+SYMBOL(towctrans, std::, <cwctype>)
+SYMBOL(towlower, std::, <cwctype>)
+SYMBOL(towupper, std::, <cwctype>)
+SYMBOL(transform, std::, <algorithm>)
+SYMBOL(transform_exclusive_scan, std::, <numeric>)
+SYMBOL(transform_inclusive_scan, std::, <numeric>)
+SYMBOL(transform_reduce, std::, <numeric>)
+SYMBOL(true_type, std::, <type_traits>)
+SYMBOL(trunc, std::, <cmath>)
+SYMBOL(try_lock, std::, <mutex>)
+SYMBOL(try_to_lock, std::, <mutex>)
+SYMBOL(try_to_lock_t, std::, <mutex>)
+SYMBOL(tuple, std::, <tuple>)
+SYMBOL(tuple_cat, std::, <tuple>)
+SYMBOL(type_identity, std::, <type_traits>)
+SYMBOL(type_identity_t, std::, <type_traits>)
+SYMBOL(type_index, std::, <typeindex>)
+SYMBOL(type_info, std::, <typeinfo>)
+SYMBOL(u16streampos, std::, <ios>)
+SYMBOL(u16string, std::, <string>)
+SYMBOL(u16string_view, std::, <string_view>)
+SYMBOL(u32streampos, std::, <ios>)
+SYMBOL(u32string, std::, <string>)
+SYMBOL(u32string_view, std::, <string_view>)
+SYMBOL(uintmax_t, std::, <cstdint>)
+SYMBOL(uintptr_t, std::, <cstdint>)
+SYMBOL(uncaught_exceptions, std::, <exception>)
+SYMBOL(undeclare_no_pointers, std::, <memory>)
+SYMBOL(undeclare_reachable, std::, <memory>)
+SYMBOL(underflow_error, std::, <stdexcept>)
+SYMBOL(underlying_type, std::, <type_traits>)
+SYMBOL(underlying_type_t, std::, <type_traits>)
+SYMBOL(ungetc, std::, <cstdio>)
+SYMBOL(ungetwc, std::, <cwchar>)
+SYMBOL(uniform_int_distribution, std::, <random>)
+SYMBOL(uniform_real_distribution, std::, <random>)
+SYMBOL(uninitialized_copy, std::, <memory>)
+SYMBOL(uninitialized_copy_n, std::, <memory>)
+SYMBOL(uninitialized_default_construct, std::, <memory>)
+SYMBOL(uninitialized_default_construct_n, std::, <memory>)
+SYMBOL(uninitialized_fill, std::, <memory>)
+SYMBOL(uninitialized_fill_n, std::, <memory>)
+SYMBOL(uninitialized_move, std::, <memory>)
+SYMBOL(uninitialized_move_n, std::, <memory>)
+SYMBOL(uninitialized_value_construct, std::, <memory>)
+SYMBOL(uninitialized_value_construct_n, std::, <memory>)
+SYMBOL(unique, std::, <algorithm>)
+SYMBOL(unique_copy, std::, <algorithm>)
+SYMBOL(unique_lock, std::, <mutex>)
+SYMBOL(unique_ptr, std::, <memory>)
+SYMBOL(unitbuf, std::, <ios>)
+SYMBOL(unordered_map, std::, <unordered_map>)
+SYMBOL(unordered_multimap, std::, <unordered_map>)
+SYMBOL(unordered_multiset, std::, <unordered_set>)
+SYMBOL(unordered_set, std::, <unordered_set>)
+SYMBOL(upper_bound, std::, <algorithm>)
+SYMBOL(uppercase, std::, <ios>)
+SYMBOL(use_facet, std::, <locale>)
+SYMBOL(uses_allocator, std::, <memory>)
+SYMBOL(uses_allocator_v, std::, <memory>)
+SYMBOL(va_list, std::, <cstdarg>)
+SYMBOL(valarray, std::, <valarray>)
+SYMBOL(variant, std::, <variant>)
+SYMBOL(variant_alternative, std::, <variant>)
+SYMBOL(variant_alternative_t, std::, <variant>)
+SYMBOL(variant_npos, std::, <variant>)
+SYMBOL(variant_size, std::, <variant>)
+SYMBOL(variant_size_v, std::, <variant>)
+SYMBOL(vector, std::, <vector>)
+SYMBOL(vfprintf, std::, <cstdio>)
+SYMBOL(vfscanf, std::, <cstdio>)
+SYMBOL(vfwprintf, std::, <cwchar>)
+SYMBOL(vfwscanf, std::, <cwchar>)
+SYMBOL(visit, std::, <variant>)
+SYMBOL(void_t, std::, <type_traits>)
+SYMBOL(vprintf, std::, <cstdio>)
+SYMBOL(vscanf, std::, <cstdio>)
+SYMBOL(vsnprintf, std::, <cstdio>)
+SYMBOL(vsprintf, std::, <cstdio>)
+SYMBOL(vsscanf, std::, <cstdio>)
+SYMBOL(vswprintf, std::, <cwchar>)
+SYMBOL(vswscanf, std::, <cwchar>)
+SYMBOL(vwprintf, std::, <cwchar>)
+SYMBOL(vwscanf, std::, <cwchar>)
+SYMBOL(wbuffer_convert, std::, <locale>)
+SYMBOL(wcerr, std::, <iostream>)
+SYMBOL(wcin, std::, <iostream>)
+SYMBOL(wclog, std::, <iostream>)
+SYMBOL(wcmatch, std::, <regex>)
+SYMBOL(wcout, std::, <iostream>)
+SYMBOL(wcregex_iterator, std::, <regex>)
+SYMBOL(wcregex_token_iterator, std::, <regex>)
+SYMBOL(wcrtomb, std::, <cwchar>)
+SYMBOL(wcscat, std::, <cwchar>)
+SYMBOL(wcschr, std::, <cwchar>)
+SYMBOL(wcscmp, std::, <cwchar>)
+SYMBOL(wcscoll, std::, <cwchar>)
+SYMBOL(wcscpy, std::, <cwchar>)
+SYMBOL(wcscspn, std::, <cwchar>)
+SYMBOL(wcsftime, std::, <cwchar>)
+SYMBOL(wcslen, std::, <cwchar>)
+SYMBOL(wcsncat, std::, <cwchar>)
+SYMBOL(wcsncmp, std::, <cwchar>)
+SYMBOL(wcsncpy, std::, <cwchar>)
+SYMBOL(wcspbrk, std::, <cwchar>)
+SYMBOL(wcsrchr, std::, <cwchar>)
+SYMBOL(wcsrtombs, std::, <cwchar>)
+SYMBOL(wcsspn, std::, <cwchar>)
+SYMBOL(wcsstr, std::, <cwchar>)
+SYMBOL(wcstod, std::, <cwchar>)
+SYMBOL(wcstof, std::, <cwchar>)
+SYMBOL(wcstoimax, std::, <cinttypes>)
+SYMBOL(wcstok, std::, <cwchar>)
+SYMBOL(wcstol, std::, <cwchar>)
+SYMBOL(wcstold, std::, <cwchar>)
+SYMBOL(wcstoll, std::, <cwchar>)
+SYMBOL(wcstombs, std::, <cstdlib>)
+SYMBOL(wcstoul, std::, <cwchar>)
+SYMBOL(wcstoull, std::, <cwchar>)
+SYMBOL(wcstoumax, std::, <cinttypes>)
+SYMBOL(wcsub_match, std::, <regex>)
+SYMBOL(wcsxfrm, std::, <cwchar>)
+SYMBOL(wctob, std::, <cwchar>)
+SYMBOL(wctomb, std::, <cstdlib>)
+SYMBOL(wctrans, std::, <cwctype>)
+SYMBOL(wctrans_t, std::, <cwctype>)
+SYMBOL(wctype, std::, <cwctype>)
+SYMBOL(wctype_t, std::, <cwctype>)
+SYMBOL(weak_equal, std::, <compare>)
+SYMBOL(weak_equality, std::, <compare>)
+SYMBOL(weak_order, std::, <compare>)
+SYMBOL(weak_ordering, std::, <compare>)
+SYMBOL(weak_ptr, std::, <memory>)
+SYMBOL(weibull_distribution, std::, <random>)
+SYMBOL(wfilebuf, std::, <streambuf>)
+SYMBOL(wfstream, std::, <fstream>)
+SYMBOL(wifstream, std::, <fstream>)
+SYMBOL(wios, std::, <ios>)
+SYMBOL(wiostream, std::, <istream>)
+SYMBOL(wistream, std::, <istream>)
+SYMBOL(wistringstream, std::, <sstream>)
+SYMBOL(wmemchr, std::, <cwchar>)
+SYMBOL(wmemcmp, std::, <cwchar>)
+SYMBOL(wmemcpy, std::, <cwchar>)
+SYMBOL(wmemmove, std::, <cwchar>)
+SYMBOL(wmemset, std::, <cwchar>)
+SYMBOL(wofstream, std::, <fstream>)
+SYMBOL(wostream, std::, <ostream>)
+SYMBOL(wostringstream, std::, <sstream>)
+SYMBOL(wosyncstream, std::, <syncstream>)
+SYMBOL(wprintf, std::, <cwchar>)
+SYMBOL(wregex, std::, <regex>)
+SYMBOL(ws, std::, <istream>)
+SYMBOL(wscanf, std::, <cwchar>)
+SYMBOL(wsmatch, std::, <regex>)
+SYMBOL(wsregex_iterator, std::, <regex>)
+SYMBOL(wsregex_token_iterator, std::, <regex>)
+SYMBOL(wssub_match, std::, <regex>)
+SYMBOL(wstreambuf, std::, <streambuf>)
+SYMBOL(wstreampos, std::, <ios>)
+SYMBOL(wstring, std::, <string>)
+SYMBOL(wstring_convert, std::, <locale>)
+SYMBOL(wstring_view, std::, <string_view>)
+SYMBOL(wstringbuf, std::, <sstream>)
+SYMBOL(wstringstream, std::, <sstream>)
+SYMBOL(wsyncbuf, std::, <syncstream>)
+SYMBOL(yocto, std::, <ratio>)
+SYMBOL(yotta, std::, <ratio>)
+SYMBOL(zepto, std::, <ratio>)
+SYMBOL(zetta, std::, <ratio>)
+SYMBOL(April, std::chrono::, <chrono>)
+SYMBOL(August, std::chrono::, <chrono>)
+SYMBOL(December, std::chrono::, <chrono>)
+SYMBOL(February, std::chrono::, <chrono>)
+SYMBOL(Friday, std::chrono::, <chrono>)
+SYMBOL(January, std::chrono::, <chrono>)
+SYMBOL(July, std::chrono::, <chrono>)
+SYMBOL(June, std::chrono::, <chrono>)
+SYMBOL(March, std::chrono::, <chrono>)
+SYMBOL(May, std::chrono::, <chrono>)
+SYMBOL(Monday, std::chrono::, <chrono>)
+SYMBOL(November, std::chrono::, <chrono>)
+SYMBOL(October, std::chrono::, <chrono>)
+SYMBOL(Saturday, std::chrono::, <chrono>)
+SYMBOL(September, std::chrono::, <chrono>)
+SYMBOL(Sunday, std::chrono::, <chrono>)
+SYMBOL(Thursday, std::chrono::, <chrono>)
+SYMBOL(Tuesday, std::chrono::, <chrono>)
+SYMBOL(Wednesday, std::chrono::, <chrono>)
+SYMBOL(abs, std::chrono::, <chrono>)
+SYMBOL(ambiguous_local_time, std::chrono::, <chrono>)
+SYMBOL(ceil, std::chrono::, <chrono>)
+SYMBOL(choose, std::chrono::, <chrono>)
+SYMBOL(clock_cast, std::chrono::, <chrono>)
+SYMBOL(clock_time_conversion, std::chrono::, <chrono>)
+SYMBOL(current_zone, std::chrono::, <chrono>)
+SYMBOL(day, std::chrono::, <chrono>)
+SYMBOL(duration, std::chrono::, <chrono>)
+SYMBOL(duration_values, std::chrono::, <chrono>)
+SYMBOL(file_clock, std::chrono::, <chrono>)
+SYMBOL(file_seconds, std::chrono::, <chrono>)
+SYMBOL(file_time, std::chrono::, <chrono>)
+SYMBOL(floor, std::chrono::, <chrono>)
+SYMBOL(gps_clock, std::chrono::, <chrono>)
+SYMBOL(gps_seconds, std::chrono::, <chrono>)
+SYMBOL(gps_time, std::chrono::, <chrono>)
+SYMBOL(high_resolution_clock, std::chrono::, <chrono>)
+SYMBOL(hours, std::chrono::, <chrono>)
+SYMBOL(is_clock, std::chrono::, <chrono>)
+SYMBOL(is_clock_v, std::chrono::, <chrono>)
+SYMBOL(last, std::chrono::, <chrono>)
+SYMBOL(last_spec, std::chrono::, <chrono>)
+SYMBOL(leap, std::chrono::, <chrono>)
+SYMBOL(link, std::chrono::, <chrono>)
+SYMBOL(local_info, std::chrono::, <chrono>)
+SYMBOL(local_seconds, std::chrono::, <chrono>)
+SYMBOL(local_t, std::chrono::, <chrono>)
+SYMBOL(local_time, std::chrono::, <chrono>)
+SYMBOL(locate_zone, std::chrono::, <chrono>)
+SYMBOL(microseconds, std::chrono::, <chrono>)
+SYMBOL(milliseconds, std::chrono::, <chrono>)
+SYMBOL(minutes, std::chrono::, <chrono>)
+SYMBOL(month, std::chrono::, <chrono>)
+SYMBOL(month_day, std::chrono::, <chrono>)
+SYMBOL(month_day_last, std::chrono::, <chrono>)
+SYMBOL(month_weekday, std::chrono::, <chrono>)
+SYMBOL(month_weekday_last, std::chrono::, <chrono>)
+SYMBOL(nanoseconds, std::chrono::, <chrono>)
+SYMBOL(nonexistent_local_time, std::chrono::, <chrono>)
+SYMBOL(round, std::chrono::, <chrono>)
+SYMBOL(seconds, std::chrono::, <chrono>)
+SYMBOL(steady_clock, std::chrono::, <chrono>)
+SYMBOL(sys_days, std::chrono::, <chrono>)
+SYMBOL(sys_info, std::chrono::, <chrono>)
+SYMBOL(sys_seconds, std::chrono::, <chrono>)
+SYMBOL(sys_time, std::chrono::, <chrono>)
+SYMBOL(system_clock, std::chrono::, <chrono>)
+SYMBOL(tai_clock, std::chrono::, <chrono>)
+SYMBOL(tai_seconds, std::chrono::, <chrono>)
+SYMBOL(tai_time, std::chrono::, <chrono>)
+SYMBOL(time_of_day, std::chrono::, <chrono>)
+SYMBOL(time_point, std::chrono::, <chrono>)
+SYMBOL(time_zone, std::chrono::, <chrono>)
+SYMBOL(treat_as_floating_point, std::chrono::, <chrono>)
+SYMBOL(treat_as_floating_point_v, std::chrono::, <chrono>)
+SYMBOL(tzdb, std::chrono::, <chrono>)
+SYMBOL(tzdb_list, std::chrono::, <chrono>)
+SYMBOL(utc_clock, std::chrono::, <chrono>)
+SYMBOL(utc_seconds, std::chrono::, <chrono>)
+SYMBOL(utc_time, std::chrono::, <chrono>)
+SYMBOL(weekday, std::chrono::, <chrono>)
+SYMBOL(weekday_indexed, std::chrono::, <chrono>)
+SYMBOL(weekday_last, std::chrono::, <chrono>)
+SYMBOL(year, std::chrono::, <chrono>)
+SYMBOL(year_month, std::chrono::, <chrono>)
+SYMBOL(year_month_day, std::chrono::, <chrono>)
+SYMBOL(year_month_day_last, std::chrono::, <chrono>)
+SYMBOL(year_month_weekday, std::chrono::, <chrono>)
+SYMBOL(year_month_weekday_last, std::chrono::, <chrono>)
+SYMBOL(zoned_time, std::chrono::, <chrono>)
+SYMBOL(zoned_traits, std::chrono::, <chrono>)
+SYMBOL(absolute, std::filesystem::, <filesystem>)
+SYMBOL(canonical, std::filesystem::, <filesystem>)
+SYMBOL(copy, std::filesystem::, <filesystem>)
+SYMBOL(copy_file, std::filesystem::, <filesystem>)
+SYMBOL(copy_options, std::filesystem::, <filesystem>)
+SYMBOL(copy_symlink, std::filesystem::, <filesystem>)
+SYMBOL(create_directories, std::filesystem::, <filesystem>)
+SYMBOL(create_directory, std::filesystem::, <filesystem>)
+SYMBOL(create_directory_symlink, std::filesystem::, <filesystem>)
+SYMBOL(create_hard_link, std::filesystem::, <filesystem>)
+SYMBOL(create_symlink, std::filesystem::, <filesystem>)
+SYMBOL(current_path, std::filesystem::, <filesystem>)
+SYMBOL(directory_entry, std::filesystem::, <filesystem>)
+SYMBOL(directory_iterator, std::filesystem::, <filesystem>)
+SYMBOL(directory_options, std::filesystem::, <filesystem>)
+SYMBOL(equivalent, std::filesystem::, <filesystem>)
+SYMBOL(exists, std::filesystem::, <filesystem>)
+SYMBOL(file_size, std::filesystem::, <filesystem>)
+SYMBOL(file_status, std::filesystem::, <filesystem>)
+SYMBOL(file_time_type, std::filesystem::, <filesystem>)
+SYMBOL(file_type, std::filesystem::, <filesystem>)
+SYMBOL(filesystem_error, std::filesystem::, <filesystem>)
+SYMBOL(hard_link_count, std::filesystem::, <filesystem>)
+SYMBOL(is_block_file, std::filesystem::, <filesystem>)
+SYMBOL(is_character_file, std::filesystem::, <filesystem>)
+SYMBOL(is_directory, std::filesystem::, <filesystem>)
+SYMBOL(is_empty, std::filesystem::, <filesystem>)
+SYMBOL(is_fifo, std::filesystem::, <filesystem>)
+SYMBOL(is_other, std::filesystem::, <filesystem>)
+SYMBOL(is_regular_file, std::filesystem::, <filesystem>)
+SYMBOL(is_socket, std::filesystem::, <filesystem>)
+SYMBOL(is_symlink, std::filesystem::, <filesystem>)
+SYMBOL(last_write_time, std::filesystem::, <filesystem>)
+SYMBOL(path, std::filesystem::, <filesystem>)
+SYMBOL(perm_options, std::filesystem::, <filesystem>)
+SYMBOL(permissions, std::filesystem::, <filesystem>)
+SYMBOL(perms, std::filesystem::, <filesystem>)
+SYMBOL(proximate, std::filesystem::, <filesystem>)
+SYMBOL(read_symlink, std::filesystem::, <filesystem>)
+SYMBOL(recursive_directory_iterator, std::filesystem::, <filesystem>)
+SYMBOL(relative, std::filesystem::, <filesystem>)
+SYMBOL(remove, std::filesystem::, <filesystem>)
+SYMBOL(remove_all, std::filesystem::, <filesystem>)
+SYMBOL(rename, std::filesystem::, <filesystem>)
+SYMBOL(resize_file, std::filesystem::, <filesystem>)
+SYMBOL(space, std::filesystem::, <filesystem>)
+SYMBOL(space_info, std::filesystem::, <filesystem>)
+SYMBOL(status, std::filesystem::, <filesystem>)
+SYMBOL(status_known, std::filesystem::, <filesystem>)
+SYMBOL(symlink_status, std::filesystem::, <filesystem>)
+SYMBOL(temp_directory_path, std::filesystem::, <filesystem>)
+SYMBOL(u8path, std::filesystem::, <filesystem>)
+SYMBOL(weakly_canonical, std::filesystem::, <filesystem>)
+SYMBOL(basic_string, std::pmr::, <string>)
+SYMBOL(deque, std::pmr::, <deque>)
+SYMBOL(forward_list, std::pmr::, <forward_list>)
+SYMBOL(get_default_resource, std::pmr::, <memory_resource>)
+SYMBOL(list, std::pmr::, <list>)
+SYMBOL(map, std::pmr::, <map>)
+SYMBOL(memory_resource, std::pmr::, <memory_resource>)
+SYMBOL(monotonic_buffer_resource, std::pmr::, <memory_resource>)
+SYMBOL(multimap, std::pmr::, <map>)
+SYMBOL(multiset, std::pmr::, <set>)
+SYMBOL(new_delete_resource, std::pmr::, <memory_resource>)
+SYMBOL(null_memory_resource, std::pmr::, <memory_resource>)
+SYMBOL(polymorphic_allocator, std::pmr::, <memory_resource>)
+SYMBOL(pool_options, std::pmr::, <memory_resource>)
+SYMBOL(set, std::pmr::, <set>)
+SYMBOL(set_default_resource, std::pmr::, <memory_resource>)
+SYMBOL(string, std::pmr::, <string>)
+SYMBOL(synchronized_pool_resource, std::pmr::, <memory_resource>)
+SYMBOL(u16string, std::pmr::, <string>)
+SYMBOL(u32string, std::pmr::, <string>)
+SYMBOL(unordered_map, std::pmr::, <unordered_map>)
+SYMBOL(unordered_multimap, std::pmr::, <unordered_map>)
+SYMBOL(unordered_multiset, std::pmr::, <unordered_set>)
+SYMBOL(unordered_set, std::pmr::, <unordered_set>)
+SYMBOL(unsynchronized_pool_resource, std::pmr::, <memory_resource>)
+SYMBOL(vector, std::pmr::, <vector>)
+SYMBOL(wstring, std::pmr::, <string>)
+SYMBOL(ECMAScript, std::regex_constants::, <regex>)
+SYMBOL(awk, std::regex_constants::, <regex>)
+SYMBOL(basic, std::regex_constants::, <regex>)
+SYMBOL(collate, std::regex_constants::, <regex>)
+SYMBOL(egrep, std::regex_constants::, <regex>)
+SYMBOL(error_backref, std::regex_constants::, <regex>)
+SYMBOL(error_badbrace, std::regex_constants::, <regex>)
+SYMBOL(error_badrepeat, std::regex_constants::, <regex>)
+SYMBOL(error_brace, std::regex_constants::, <regex>)
+SYMBOL(error_brack, std::regex_constants::, <regex>)
+SYMBOL(error_collate, std::regex_constants::, <regex>)
+SYMBOL(error_complexity, std::regex_constants::, <regex>)
+SYMBOL(error_ctype, std::regex_constants::, <regex>)
+SYMBOL(error_escape, std::regex_constants::, <regex>)
+SYMBOL(error_paren, std::regex_constants::, <regex>)
+SYMBOL(error_range, std::regex_constants::, <regex>)
+SYMBOL(error_space, std::regex_constants::, <regex>)
+SYMBOL(error_stack, std::regex_constants::, <regex>)
+SYMBOL(error_type, std::regex_constants::, <regex>)
+SYMBOL(extended, std::regex_constants::, <regex>)
+SYMBOL(format_default, std::regex_constants::, <regex>)
+SYMBOL(format_first_only, std::regex_constants::, <regex>)
+SYMBOL(format_no_copy, std::regex_constants::, <regex>)
+SYMBOL(format_sed, std::regex_constants::, <regex>)
+SYMBOL(grep, std::regex_constants::, <regex>)
+SYMBOL(icase, std::regex_constants::, <regex>)
+SYMBOL(match_any, std::regex_constants::, <regex>)
+SYMBOL(match_continuous, std::regex_constants::, <regex>)
+SYMBOL(match_default, std::regex_constants::, <regex>)
+SYMBOL(match_flag_type, std::regex_constants::, <regex>)
+SYMBOL(match_not_bol, std::regex_constants::, <regex>)
+SYMBOL(match_not_bow, std::regex_constants::, <regex>)
+SYMBOL(match_not_eol, std::regex_constants::, <regex>)
+SYMBOL(match_not_eow, std::regex_constants::, <regex>)
+SYMBOL(match_not_null, std::regex_constants::, <regex>)
+SYMBOL(match_prev_avail, std::regex_constants::, <regex>)
+SYMBOL(multiline, std::regex_constants::, <regex>)
+SYMBOL(nosubs, std::regex_constants::, <regex>)
+SYMBOL(optimize, std::regex_constants::, <regex>)
+SYMBOL(syntax_option_type, std::regex_constants::, <regex>)
+SYMBOL(get_id, std::this_thread::, <thread>)
+SYMBOL(sleep_for, std::this_thread::, <thread>)
+SYMBOL(sleep_until, std::this_thread::, <thread>)
+SYMBOL(yield, std::this_thread::, <thread>)
diff --git a/clangd/TUScheduler.cpp b/clangd/TUScheduler.cpp
index 2326400..c4e555b 100644
--- a/clangd/TUScheduler.cpp
+++ b/clangd/TUScheduler.cpp
@@ -1,9 +1,8 @@
 //===--- TUScheduler.cpp -----------------------------------------*-C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 // For each file, managed by TUScheduler, we create a single ASTWorker that
@@ -44,10 +43,14 @@
 
 #include "TUScheduler.h"
 #include "Cancellation.h"
+#include "Compiler.h"
+#include "GlobalCompilationDatabase.h"
 #include "Logger.h"
 #include "Trace.h"
+#include "index/CanonicalIncludes.h"
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Path.h"
@@ -62,7 +65,7 @@
 
 namespace {
 class ASTWorker;
-}
+} // namespace
 
 static clang::clangd::Key<std::string> kFileBeingProcessed;
 
@@ -154,11 +157,10 @@
 /// worker.
 class ASTWorker {
   friend class ASTWorkerHandle;
-  ASTWorker(PathRef FileName, TUScheduler::ASTCache &LRUCache,
-            Semaphore &Barrier, bool RunSync,
-            steady_clock::duration UpdateDebounce,
-            std::shared_ptr<PCHContainerOperations> PCHs,
-            bool StorePreamblesInMemory, ParsingCallbacks &Callbacks);
+  ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
+            TUScheduler::ASTCache &LRUCache, Semaphore &Barrier, bool RunSync,
+            steady_clock::duration UpdateDebounce, bool StorePreamblesInMemory,
+            ParsingCallbacks &Callbacks);
 
 public:
   /// Create a new ASTWorker and return a handle to it.
@@ -166,13 +168,11 @@
   /// is null, all requests will be processed on the calling thread
   /// synchronously instead. \p Barrier is acquired when processing each
   /// request, it is used to limit the number of actively running threads.
-  static ASTWorkerHandle create(PathRef FileName,
-                                TUScheduler::ASTCache &IdleASTs,
-                                AsyncTaskRunner *Tasks, Semaphore &Barrier,
-                                steady_clock::duration UpdateDebounce,
-                                std::shared_ptr<PCHContainerOperations> PCHs,
-                                bool StorePreamblesInMemory,
-                                ParsingCallbacks &Callbacks);
+  static ASTWorkerHandle
+  create(PathRef FileName, const GlobalCompilationDatabase &CDB,
+         TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
+         Semaphore &Barrier, steady_clock::duration UpdateDebounce,
+         bool StorePreamblesInMemory, ParsingCallbacks &Callbacks);
   ~ASTWorker();
 
   void update(ParseInputs Inputs, WantDiagnostics);
@@ -182,10 +182,14 @@
   bool blockUntilIdle(Deadline Timeout) const;
 
   std::shared_ptr<const PreambleData> getPossiblyStalePreamble() const;
+
   /// Obtain a preamble reflecting all updates so far. Threadsafe.
   /// It may be delivered immediately, or later on the worker thread.
   void getCurrentPreamble(
       llvm::unique_function<void(std::shared_ptr<const PreambleData>)>);
+  /// Returns compile command from the current file inputs.
+  tooling::CompileCommand getCurrentCompileCommand() const;
+
   /// Wait for the first build of preamble to finish. Preamble itself can be
   /// accessed via getPossiblyStalePreamble(). Note that this function will
   /// return after an unsuccessful build of the preamble too, i.e. result of
@@ -216,6 +220,10 @@
   Deadline scheduleLocked();
   /// Should the first task in the queue be skipped instead of run?
   bool shouldSkipHeadLocked() const;
+  /// This is private because `FileInputs.FS` is not thread-safe and thus not
+  /// safe to share. Callers should make sure not to expose `FS` via a public
+  /// interface.
+  std::shared_ptr<const ParseInputs> getCurrentFileInputs() const;
 
   struct Request {
     llvm::unique_function<void()> Action;
@@ -232,24 +240,24 @@
   const steady_clock::duration UpdateDebounce;
   /// File that ASTWorker is responsible for.
   const Path FileName;
+  const GlobalCompilationDatabase &CDB;
   /// Whether to keep the built preambles in memory or on disk.
   const bool StorePreambleInMemory;
   /// Callback invoked when preamble or main file AST is built.
   ParsingCallbacks &Callbacks;
-  /// Helper class required to build the ASTs.
-  const std::shared_ptr<PCHContainerOperations> PCHs;
   /// Only accessed by the worker thread.
   TUStatus Status;
 
   Semaphore &Barrier;
-  /// Inputs, corresponding to the current state of AST.
-  ParseInputs FileInputs;
   /// Whether the diagnostics for the current FileInputs were reported to the
   /// users before.
   bool DiagsWereReported = false;
-  /// Size of the last AST
   /// Guards members used by both TUScheduler and the worker thread.
   mutable std::mutex Mutex;
+  /// File inputs, currently being used by the worker.
+  /// Inputs are written and read by the worker thread, compile command can also
+  /// be consumed by clients of ASTWorker.
+  std::shared_ptr<const ParseInputs> FileInputs;         /* GUARDED_BY(Mutex) */
   std::shared_ptr<const PreambleData> LastBuiltPreamble; /* GUARDED_BY(Mutex) */
   /// Becomes ready when the first preamble build finishes.
   Notification PreambleWasBuilt;
@@ -310,16 +318,14 @@
   std::shared_ptr<ASTWorker> Worker;
 };
 
-ASTWorkerHandle ASTWorker::create(PathRef FileName,
-                                  TUScheduler::ASTCache &IdleASTs,
-                                  AsyncTaskRunner *Tasks, Semaphore &Barrier,
-                                  steady_clock::duration UpdateDebounce,
-                                  std::shared_ptr<PCHContainerOperations> PCHs,
-                                  bool StorePreamblesInMemory,
-                                  ParsingCallbacks &Callbacks) {
-  std::shared_ptr<ASTWorker> Worker(new ASTWorker(
-      FileName, IdleASTs, Barrier, /*RunSync=*/!Tasks, UpdateDebounce,
-      std::move(PCHs), StorePreamblesInMemory, Callbacks));
+ASTWorkerHandle
+ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
+                  TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
+                  Semaphore &Barrier, steady_clock::duration UpdateDebounce,
+                  bool StorePreamblesInMemory, ParsingCallbacks &Callbacks) {
+  std::shared_ptr<ASTWorker> Worker(
+      new ASTWorker(FileName, CDB, IdleASTs, Barrier, /*RunSync=*/!Tasks,
+                    UpdateDebounce, StorePreamblesInMemory, Callbacks));
   if (Tasks)
     Tasks->runAsync("worker:" + llvm::sys::path::filename(FileName),
                     [Worker]() { Worker->run(); });
@@ -327,17 +333,23 @@
   return ASTWorkerHandle(std::move(Worker));
 }
 
-ASTWorker::ASTWorker(PathRef FileName, TUScheduler::ASTCache &LRUCache,
-                     Semaphore &Barrier, bool RunSync,
-                     steady_clock::duration UpdateDebounce,
-                     std::shared_ptr<PCHContainerOperations> PCHs,
+ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
+                     TUScheduler::ASTCache &LRUCache, Semaphore &Barrier,
+                     bool RunSync, steady_clock::duration UpdateDebounce,
                      bool StorePreamblesInMemory, ParsingCallbacks &Callbacks)
     : IdleASTs(LRUCache), RunSync(RunSync), UpdateDebounce(UpdateDebounce),
-      FileName(FileName), StorePreambleInMemory(StorePreamblesInMemory),
-      Callbacks(Callbacks),
-      PCHs(std::move(PCHs)), Status{TUAction(TUAction::Idle, ""),
-                                    TUStatus::BuildDetails()},
-      Barrier(Barrier), Done(false) {}
+      FileName(FileName), CDB(CDB),
+      StorePreambleInMemory(StorePreamblesInMemory),
+      Callbacks(Callbacks), Status{TUAction(TUAction::Idle, ""),
+                                   TUStatus::BuildDetails()},
+      Barrier(Barrier), Done(false) {
+  auto Inputs = std::make_shared<ParseInputs>();
+  // Set a fallback command because compile command can be accessed before
+  // `Inputs` is initialized. Other fields are only used after initialization
+  // from client inputs.
+  Inputs->CompileCommand = CDB.getFallbackCommand(FileName);
+  FileInputs = std::move(Inputs);
+}
 
 ASTWorker::~ASTWorker() {
   // Make sure we remove the cached AST, if any.
@@ -352,17 +364,32 @@
 void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
   llvm::StringRef TaskName = "Update";
   auto Task = [=]() mutable {
+    // Get the actual command as `Inputs` does not have a command.
+    // FIXME: some build systems like Bazel will take time to preparing
+    // environment to build the file, it would be nice if we could emit a
+    // "PreparingBuild" status to inform users, it is non-trivial given the
+    // current implementation.
+    if (auto Cmd = CDB.getCompileCommand(FileName))
+      Inputs.CompileCommand = *Cmd;
+    else
+      // FIXME: consider using old command if it's not a fallback one.
+      Inputs.CompileCommand = CDB.getFallbackCommand(FileName);
+    auto PrevInputs = getCurrentFileInputs();
     // Will be used to check if we can avoid rebuilding the AST.
     bool InputsAreTheSame =
-        std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
+        std::tie(PrevInputs->CompileCommand, PrevInputs->Contents) ==
         std::tie(Inputs.CompileCommand, Inputs.Contents);
 
-    tooling::CompileCommand OldCommand = std::move(FileInputs.CompileCommand);
+    tooling::CompileCommand OldCommand = PrevInputs->CompileCommand;
     bool PrevDiagsWereReported = DiagsWereReported;
-    FileInputs = Inputs;
+    {
+      std::lock_guard<std::mutex> Lock(Mutex);
+      FileInputs = std::make_shared<ParseInputs>(Inputs);
+    }
     DiagsWereReported = false;
     emitTUStatus({TUAction::BuildingPreamble, TaskName});
-    log("Updating file {0} with command [{1}] {2}", FileName,
+    log("Updating file {0} with command {1}\n[{2}]\n{3}", FileName,
+        Inputs.CompileCommand.Heuristic,
         Inputs.CompileCommand.Directory,
         llvm::join(Inputs.CompileCommand.CommandLine, " "));
     // Rebuild the preamble and the AST.
@@ -384,10 +411,11 @@
     std::shared_ptr<const PreambleData> OldPreamble =
         getPossiblyStalePreamble();
     std::shared_ptr<const PreambleData> NewPreamble = buildPreamble(
-        FileName, *Invocation, OldPreamble, OldCommand, Inputs, PCHs,
+        FileName, *Invocation, OldPreamble, OldCommand, Inputs,
         StorePreambleInMemory,
-        [this](ASTContext &Ctx, std::shared_ptr<clang::Preprocessor> PP) {
-          Callbacks.onPreambleAST(FileName, Ctx, std::move(PP));
+        [this](ASTContext &Ctx, std::shared_ptr<clang::Preprocessor> PP,
+               const CanonicalIncludes &CanonIncludes) {
+          Callbacks.onPreambleAST(FileName, Ctx, std::move(PP), CanonIncludes);
         });
 
     bool CanReuseAST = InputsAreTheSame && (OldPreamble == NewPreamble);
@@ -440,7 +468,7 @@
     llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
     if (!AST) {
       llvm::Optional<ParsedAST> NewAST =
-          buildAST(FileName, std::move(Invocation), Inputs, NewPreamble, PCHs);
+          buildAST(FileName, std::move(Invocation), Inputs, NewPreamble);
       AST = NewAST ? llvm::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
       if (!(*AST)) { // buildAST fails.
         TUStatus::BuildDetails Details;
@@ -480,15 +508,16 @@
     if (isCancelled())
       return Action(llvm::make_error<CancelledError>());
     llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
+    auto CurrentInputs = getCurrentFileInputs();
     if (!AST) {
       std::unique_ptr<CompilerInvocation> Invocation =
-          buildCompilerInvocation(FileInputs);
+          buildCompilerInvocation(*CurrentInputs);
       // Try rebuilding the AST.
       llvm::Optional<ParsedAST> NewAST =
           Invocation
               ? buildAST(FileName,
                          llvm::make_unique<CompilerInvocation>(*Invocation),
-                         FileInputs, getPossiblyStalePreamble(), PCHs)
+                         *CurrentInputs, getPossiblyStalePreamble())
               : None;
       AST = NewAST ? llvm::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
     }
@@ -499,7 +528,7 @@
     if (!*AST)
       return Action(llvm::make_error<llvm::StringError>(
           "invalid AST", llvm::errc::invalid_argument));
-    Action(InputsAndAST{FileInputs, **AST});
+    Action(InputsAndAST{*CurrentInputs, **AST});
   };
   startTask(Name, Bind(Task, std::move(Action)),
             /*UpdateType=*/None);
@@ -541,6 +570,16 @@
 
 void ASTWorker::waitForFirstPreamble() const { PreambleWasBuilt.wait(); }
 
+std::shared_ptr<const ParseInputs> ASTWorker::getCurrentFileInputs() const {
+  std::unique_lock<std::mutex> Lock(Mutex);
+  return FileInputs;
+}
+
+tooling::CompileCommand ASTWorker::getCurrentCompileCommand() const {
+  std::unique_lock<std::mutex> Lock(Mutex);
+  return FileInputs->CompileCommand;
+}
+
 std::size_t ASTWorker::getUsedBytes() const {
   // Note that we don't report the size of ASTs currently used for processing
   // the in-flight requests. We used this information for debugging purposes
@@ -779,17 +818,16 @@
 struct TUScheduler::FileData {
   /// Latest inputs, passed to TUScheduler::update().
   std::string Contents;
-  tooling::CompileCommand Command;
   ASTWorkerHandle Worker;
 };
 
-TUScheduler::TUScheduler(unsigned AsyncThreadsCount,
+TUScheduler::TUScheduler(const GlobalCompilationDatabase &CDB,
+                         unsigned AsyncThreadsCount,
                          bool StorePreamblesInMemory,
                          std::unique_ptr<ParsingCallbacks> Callbacks,
                          std::chrono::steady_clock::duration UpdateDebounce,
                          ASTRetentionPolicy RetentionPolicy)
-    : StorePreamblesInMemory(StorePreamblesInMemory),
-      PCHOps(std::make_shared<PCHContainerOperations>()),
+    : CDB(CDB), StorePreamblesInMemory(StorePreamblesInMemory),
       Callbacks(Callbacks ? move(Callbacks)
                           : llvm::make_unique<ParsingCallbacks>()),
       Barrier(AsyncThreadsCount),
@@ -828,13 +866,13 @@
   if (!FD) {
     // Create a new worker to process the AST-related tasks.
     ASTWorkerHandle Worker = ASTWorker::create(
-        File, *IdleASTs, WorkerThreads ? WorkerThreads.getPointer() : nullptr,
-        Barrier, UpdateDebounce, PCHOps, StorePreamblesInMemory, *Callbacks);
-    FD = std::unique_ptr<FileData>(new FileData{
-        Inputs.Contents, Inputs.CompileCommand, std::move(Worker)});
+        File, CDB, *IdleASTs,
+        WorkerThreads ? WorkerThreads.getPointer() : nullptr, Barrier,
+        UpdateDebounce, StorePreamblesInMemory, *Callbacks);
+    FD = std::unique_ptr<FileData>(
+        new FileData{Inputs.Contents, std::move(Worker)});
   } else {
     FD->Contents = Inputs.Contents;
-    FD->Command = Inputs.CompileCommand;
   }
   FD->Worker->update(std::move(Inputs), WantDiags);
 }
@@ -866,9 +904,9 @@
   It->second->Worker->runWithAST(Name, std::move(Action));
 }
 
-void TUScheduler::runWithPreamble(
-    llvm::StringRef Name, PathRef File, PreambleConsistency Consistency,
-    llvm::unique_function<void(llvm::Expected<InputsAndPreamble>)> Action) {
+void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
+                                  PreambleConsistency Consistency,
+                                  Callback<InputsAndPreamble> Action) {
   auto It = Files.find(File);
   if (It == Files.end()) {
     Action(llvm::make_error<LSPError>(
@@ -882,7 +920,8 @@
     SPAN_ATTACH(Tracer, "file", File);
     std::shared_ptr<const PreambleData> Preamble =
         It->second->Worker->getPossiblyStalePreamble();
-    Action(InputsAndPreamble{It->second->Contents, It->second->Command,
+    Action(InputsAndPreamble{It->second->Contents,
+                             It->second->Worker->getCurrentCompileCommand(),
                              Preamble.get()});
     return;
   }
@@ -901,19 +940,21 @@
   }
 
   std::shared_ptr<const ASTWorker> Worker = It->second->Worker.lock();
-  auto Task = [Worker, this](std::string Name, std::string File,
-                             std::string Contents,
-                             tooling::CompileCommand Command, Context Ctx,
-                             decltype(ConsistentPreamble) ConsistentPreamble,
-                             decltype(Action) Action) mutable {
+  auto Task = [Worker, Consistency,
+               this](std::string Name, std::string File, std::string Contents,
+                     tooling::CompileCommand Command, Context Ctx,
+                     decltype(ConsistentPreamble) ConsistentPreamble,
+                     decltype(Action) Action) mutable {
     std::shared_ptr<const PreambleData> Preamble;
     if (ConsistentPreamble.valid()) {
       Preamble = ConsistentPreamble.get();
     } else {
-      // We don't want to be running preamble actions before the preamble was
-      // built for the first time. This avoids extra work of processing the
-      // preamble headers in parallel multiple times.
-      Worker->waitForFirstPreamble();
+      if (Consistency != PreambleConsistency::StaleOrAbsent) {
+        // Wait until the preamble is built for the first time, if preamble is
+        // required. This avoids extra work of processing the preamble headers
+        // in parallel multiple times.
+        Worker->waitForFirstPreamble();
+      }
       Preamble = Worker->getPossiblyStalePreamble();
     }
 
@@ -927,7 +968,7 @@
   PreambleTasks->runAsync(
       "task:" + llvm::sys::path::filename(File),
       Bind(Task, std::string(Name), std::string(File), It->second->Contents,
-           It->second->Command,
+           Worker->getCurrentCompileCommand(),
            Context::current().derive(kFileBeingProcessed, File),
            std::move(ConsistentPreamble), std::move(Action)));
 }
diff --git a/clangd/TUScheduler.h b/clangd/TUScheduler.h
index 5ab66d8..dc47790 100644
--- a/clangd/TUScheduler.h
+++ b/clangd/TUScheduler.h
@@ -1,9 +1,8 @@
 //===--- TUScheduler.h -------------------------------------------*-C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,8 +11,12 @@
 
 #include "ClangdUnit.h"
 #include "Function.h"
+#include "GlobalCompilationDatabase.h"
 #include "Threading.h"
+#include "index/CanonicalIncludes.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
 #include <future>
 
 namespace clang {
@@ -32,6 +35,7 @@
 struct InputsAndPreamble {
   llvm::StringRef Contents;
   const tooling::CompileCommand &Command;
+  // This can be nullptr if no preamble is availble.
   const PreambleData *Preamble;
 };
 
@@ -92,7 +96,8 @@
   /// contains only AST nodes from the #include directives at the start of the
   /// file. AST node in the current file should be observed on onMainAST call.
   virtual void onPreambleAST(PathRef Path, ASTContext &Ctx,
-                             std::shared_ptr<clang::Preprocessor> PP) {}
+                             std::shared_ptr<clang::Preprocessor> PP,
+                             const CanonicalIncludes &) {}
   /// Called on the AST built for the file itself. Note that preamble AST nodes
   /// are not deserialized and should be processed in the onPreambleAST call
   /// instead.
@@ -121,7 +126,8 @@
 /// FIXME(sammccall): pull out a scheduler options struct.
 class TUScheduler {
 public:
-  TUScheduler(unsigned AsyncThreadsCount, bool StorePreamblesInMemory,
+  TUScheduler(const GlobalCompilationDatabase &CDB, unsigned AsyncThreadsCount,
+              bool StorePreamblesInMemory,
               std::unique_ptr<ParsingCallbacks> ASTCallbacks,
               std::chrono::steady_clock::duration UpdateDebounce,
               ASTRetentionPolicy RetentionPolicy);
@@ -137,10 +143,11 @@
   std::vector<Path> getFilesWithCachedAST() const;
 
   /// Schedule an update for \p File. Adds \p File to a list of tracked files if
-  /// \p File was not part of it before.
-  /// If diagnostics are requested (Yes), and the context is cancelled before
-  /// they are prepared, they may be skipped if eventual-consistency permits it
-  /// (i.e. WantDiagnostics is downgraded to Auto).
+  /// \p File was not part of it before. The compile command in \p Inputs is
+  /// ignored; worker queries CDB to get the actual compile command.
+  /// If diagnostics are requested (Yes), and the context is cancelled
+  /// before they are prepared, they may be skipped if eventual-consistency
+  /// permits it (i.e. WantDiagnostics is downgraded to Auto).
   void update(PathRef File, ParseInputs Inputs, WantDiagnostics WD);
 
   /// Remove \p File from the list of tracked files and schedule removal of its
@@ -177,10 +184,14 @@
     ///   reading source code from headers.
     /// This is the fastest option, usually a preamble is available immediately.
     Stale,
+    /// Besides accepting stale preamble, this also allow preamble to be absent
+    /// (not ready or failed to build).
+    StaleOrAbsent,
   };
+
   /// Schedule an async read of the preamble.
-  /// If there's no preamble yet (because the file was just opened), we'll wait
-  /// for it to build. The result may be null if it fails to build or is empty.
+  /// If there's no up-to-date preamble, we follow the PreambleConsistency
+  /// policy.
   /// If an error occurs, it is forwarded to the \p Action callback.
   /// Context cancellation is ignored and should be handled by the Action.
   /// (In practice, the Action is almost always executed immediately).
@@ -209,8 +220,8 @@
   static llvm::Optional<llvm::StringRef> getFileBeingProcessedInContext();
 
 private:
+  const GlobalCompilationDatabase &CDB;
   const bool StorePreamblesInMemory;
-  const std::shared_ptr<PCHContainerOperations> PCHOps;
   std::unique_ptr<ParsingCallbacks> Callbacks; // not nullptr
   Semaphore Barrier;
   llvm::StringMap<std::unique_ptr<FileData>> Files;
diff --git a/clangd/Threading.cpp b/clangd/Threading.cpp
index 139fcc2..016a902 100644
--- a/clangd/Threading.cpp
+++ b/clangd/Threading.cpp
@@ -7,6 +7,10 @@
 #include <thread>
 #ifdef __USE_POSIX
 #include <pthread.h>
+#elif defined(__APPLE__)
+#include <sys/resource.h>
+#elif defined (_WIN32)
+#include <windows.h>
 #endif
 
 namespace clang {
@@ -109,22 +113,5 @@
   CV.wait_until(Lock, D.time());
 }
 
-static std::atomic<bool> AvoidThreadStarvation = {false};
-
-void setCurrentThreadPriority(ThreadPriority Priority) {
-  // Some *really* old glibcs are missing SCHED_IDLE.
-#if defined(__linux__) && defined(SCHED_IDLE)
-  sched_param priority;
-  priority.sched_priority = 0;
-  pthread_setschedparam(
-      pthread_self(),
-      Priority == ThreadPriority::Low && !AvoidThreadStarvation ? SCHED_IDLE
-                                                                : SCHED_OTHER,
-      &priority);
-#endif
-}
-
-void preventThreadStarvationInTests() { AvoidThreadStarvation = true; }
-
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/Threading.h b/clangd/Threading.h
index 4c55328..920b2e0 100644
--- a/clangd/Threading.h
+++ b/clangd/Threading.h
@@ -1,9 +1,8 @@
 //===--- ThreadPool.h --------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -118,16 +117,6 @@
   std::size_t InFlightTasks = 0;
 };
 
-enum class ThreadPriority {
-  Low = 0,
-  Normal = 1,
-};
-void setCurrentThreadPriority(ThreadPriority Priority);
-// Avoid the use of scheduler policies that may starve low-priority threads.
-// This prevents tests from timing out on loaded systems.
-// Affects subsequent setThreadPriority() calls.
-void preventThreadStarvationInTests();
-
 } // namespace clangd
 } // namespace clang
 #endif
diff --git a/clangd/Trace.cpp b/clangd/Trace.cpp
index e44d3a1..2318d9c 100644
--- a/clangd/Trace.cpp
+++ b/clangd/Trace.cpp
@@ -1,9 +1,8 @@
 //===--- Trace.cpp - Performance tracing facilities -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,13 +27,14 @@
 // Perhaps we should replace this by something that disturbs performance less.
 class JSONTracer : public EventTracer {
 public:
-  JSONTracer(llvm::raw_ostream &Out, bool Pretty)
-      : Out(Out), Sep(""), Start(std::chrono::system_clock::now()),
-        JSONFormat(Pretty ? "{0:2}" : "{0}") {
+  JSONTracer(llvm::raw_ostream &OS, bool Pretty)
+      : Out(OS, Pretty ? 2 : 0), Start(std::chrono::system_clock::now()) {
     // The displayTimeUnit must be ns to avoid low-precision overlap
     // calculations!
-    Out << R"({"displayTimeUnit":"ns","traceEvents":[)"
-        << "\n";
+    Out.objectBegin();
+    Out.attribute("displayTimeUnit", "ns");
+    Out.attributeBegin("traceEvents");
+    Out.arrayBegin();
     rawEvent("M", llvm::json::Object{
                       {"name", "process_name"},
                       {"args", llvm::json::Object{{"name", "clangd"}}},
@@ -42,7 +42,9 @@
   }
 
   ~JSONTracer() {
-    Out << "\n]}";
+    Out.arrayEnd();
+    Out.attributeEnd();
+    Out.objectEnd();
     Out.flush();
   }
 
@@ -74,7 +76,7 @@
     Contents["ts"] = Timestamp ? Timestamp : timestamp();
     Contents["tid"] = int64_t(TID);
     std::lock_guard<std::mutex> Lock(Mu);
-    rawEvent(Phase, std::move(Contents));
+    rawEvent(Phase, Contents);
   }
 
 private:
@@ -146,13 +148,14 @@
   // Record an event. ph and pid are set.
   // Contents must be a list of the other JSON key/values.
   void rawEvent(llvm::StringRef Phase,
-                llvm::json::Object &&Event) /*REQUIRES(Mu)*/ {
+                const llvm::json::Object &Event) /*REQUIRES(Mu)*/ {
     // PID 0 represents the clangd process.
-    Event["pid"] = 0;
-    Event["ph"] = Phase;
-    Out << Sep
-        << llvm::formatv(JSONFormat, llvm::json::Value(std::move(Event)));
-    Sep = ",\n";
+    Out.object([&]{
+      Out.attribute("pid", 0);
+      Out.attribute("ph", Phase);
+      for (const auto& KV : Event)
+        Out.attribute(KV.first, KV.second);
+    });
   }
 
   // If we haven't already, emit metadata describing this thread.
@@ -178,11 +181,9 @@
   }
 
   std::mutex Mu;
-  llvm::raw_ostream &Out /*GUARDED_BY(Mu)*/;
-  const char *Sep /*GUARDED_BY(Mu)*/;
+  llvm::json::OStream Out /*GUARDED_BY(Mu)*/;
   llvm::DenseSet<uint64_t> ThreadsWithMD /*GUARDED_BY(Mu)*/;
   const llvm::sys::TimePoint<> Start;
-  const char *JSONFormat;
 };
 
 Key<std::unique_ptr<JSONTracer::JSONSpan>> JSONTracer::SpanKey;
diff --git a/clangd/Trace.h b/clangd/Trace.h
index 4b2f72e..a36be77 100644
--- a/clangd/Trace.h
+++ b/clangd/Trace.h
@@ -1,9 +1,8 @@
 //===--- Trace.h - Performance tracing facilities ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/Transport.h b/clangd/Transport.h
index 87fb8f9..1cca573 100644
--- a/clangd/Transport.h
+++ b/clangd/Transport.h
@@ -1,9 +1,8 @@
 //===--- Transport.h - sending and receiving LSP messages -------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -86,7 +85,7 @@
                  llvm::raw_ostream *InMirror, bool Pretty,
                  JSONStreamStyle = JSONStreamStyle::Standard);
 
-#ifdef CLANGD_BUILD_XPC
+#if CLANGD_BUILD_XPC
 // Returns a Transport for macOS based on XPC.
 // Clangd with this transport is meant to be run as bundled XPC service.
 std::unique_ptr<Transport> newXPCTransport();
diff --git a/clangd/URI.cpp b/clangd/URI.cpp
index 888acb7..ed6b4d3 100644
--- a/clangd/URI.cpp
+++ b/clangd/URI.cpp
@@ -1,9 +1,8 @@
 //===---- URI.h - File URIs with schemes -------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/URI.h b/clangd/URI.h
index cbde008..110b39a 100644
--- a/clangd/URI.h
+++ b/clangd/URI.h
@@ -1,9 +1,8 @@
 //===--- URI.h - File URIs with schemes --------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp
index 29561df..c51631a 100644
--- a/clangd/XRefs.cpp
+++ b/clangd/XRefs.cpp
@@ -1,19 +1,24 @@
 //===--- XRefs.cpp -----------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "XRefs.h"
 #include "AST.h"
+#include "FindSymbols.h"
 #include "Logger.h"
 #include "SourceCode.h"
 #include "URI.h"
+#include "index/Merge.h"
+#include "index/SymbolCollector.h"
+#include "index/SymbolLocation.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
 #include "clang/Index/IndexDataConsumer.h"
+#include "clang/Index/IndexSymbol.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/Support/Path.h"
@@ -22,18 +27,27 @@
 namespace clangd {
 namespace {
 
-// Get the definition from a given declaration `D`.
-// Return nullptr if no definition is found, or the declaration type of `D` is
-// not supported.
+// Returns the single definition of the entity declared by D, if visible.
+// In particular:
+// - for non-redeclarable kinds (e.g. local vars), return D
+// - for kinds that allow multiple definitions (e.g. namespaces), return nullptr
+// Kinds of nodes that always return nullptr here will not have definitions
+// reported by locateSymbolAt().
 const Decl *getDefinition(const Decl *D) {
   assert(D);
+  // Decl has one definition that we can find.
   if (const auto *TD = dyn_cast<TagDecl>(D))
     return TD->getDefinition();
-  else if (const auto *VD = dyn_cast<VarDecl>(D))
+  if (const auto *VD = dyn_cast<VarDecl>(D))
     return VD->getDefinition();
-  else if (const auto *FD = dyn_cast<FunctionDecl>(D))
+  if (const auto *FD = dyn_cast<FunctionDecl>(D))
     return FD->getDefinition();
-  return nullptr;
+  // Only a single declaration is allowed.
+  if (isa<ValueDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
+      isa<TemplateTemplateParmDecl>(D)) // except cases above
+    return D;
+  // Multiple definitions are allowed.
+  return nullptr; // except cases above
 }
 
 void logIfOverflow(const SymbolLocation &Loc) {
@@ -70,25 +84,40 @@
   return LSPLoc;
 }
 
+SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) {
+  SymbolLocation SymLoc;
+  URIStorage = Loc.uri.uri();
+  SymLoc.FileURI = URIStorage.c_str();
+  SymLoc.Start.setLine(Loc.range.start.line);
+  SymLoc.Start.setColumn(Loc.range.start.character);
+  SymLoc.End.setLine(Loc.range.end.line);
+  SymLoc.End.setColumn(Loc.range.end.character);
+  return SymLoc;
+}
+
+// Returns the preferred location between an AST location and an index location.
+SymbolLocation getPreferredLocation(const Location &ASTLoc,
+                                    const SymbolLocation &IdxLoc,
+                                    std::string &Scratch) {
+  // Also use a dummy symbol for the index location so that other fields (e.g.
+  // definition) are not factored into the preferrence.
+  Symbol ASTSym, IdxSym;
+  ASTSym.ID = IdxSym.ID = SymbolID("dummy_id");
+  ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch);
+  IdxSym.CanonicalDeclaration = IdxLoc;
+  auto Merged = mergeSymbol(ASTSym, IdxSym);
+  return Merged.CanonicalDeclaration;
+}
+
 struct MacroDecl {
   llvm::StringRef Name;
   const MacroInfo *Info;
 };
 
-struct DeclInfo {
-  const Decl *D;
-  // Indicates the declaration is referenced by an explicit AST node.
-  bool IsReferencedExplicitly = false;
-};
-
 /// Finds declarations locations that a given source location refers to.
 class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
   std::vector<MacroDecl> MacroInfos;
-  // The value of the map indicates whether the declaration has been referenced
-  // explicitly in the code.
-  // True means the declaration is explicitly referenced at least once; false
-  // otherwise.
-  llvm::DenseMap<const Decl *, bool> Decls;
+  llvm::DenseSet<const Decl *> Decls;
   const SourceLocation &SearchedLocation;
   const ASTContext &AST;
   Preprocessor &PP;
@@ -98,22 +127,14 @@
                              ASTContext &AST, Preprocessor &PP)
       : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {}
 
-  // Get all DeclInfo of the found declarations.
-  // The results are sorted by "IsReferencedExplicitly" and declaration
-  // location.
-  std::vector<DeclInfo> getFoundDecls() const {
-    std::vector<DeclInfo> Result;
-    for (auto It : Decls) {
-      Result.emplace_back();
-      Result.back().D = It.first;
-      Result.back().IsReferencedExplicitly = It.second;
-    }
+  // The results are sorted by declaration location.
+  std::vector<const Decl *> getFoundDecls() const {
+    std::vector<const Decl *> Result;
+    for (const Decl *D : Decls)
+      Result.push_back(D);
 
-    // Sort results. Declarations being referenced explicitly come first.
-    llvm::sort(Result, [](const DeclInfo &L, const DeclInfo &R) {
-      if (L.IsReferencedExplicitly != R.IsReferencedExplicitly)
-        return L.IsReferencedExplicitly > R.IsReferencedExplicitly;
-      return L.D->getBeginLoc() < R.D->getBeginLoc();
+    llvm::sort(Result, [](const Decl *L, const Decl *R) {
+      return L->getBeginLoc() < R->getBeginLoc();
     });
     return Result;
   }
@@ -137,29 +158,33 @@
                       llvm::ArrayRef<index::SymbolRelation> Relations,
                       SourceLocation Loc,
                       index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
+    // Skip non-semantic references.
+    if (Roles & static_cast<unsigned>(index::SymbolRole::NameReference))
+      return true;
+
     if (Loc == SearchedLocation) {
-      auto isImplicitExpr = [](const Expr *E) {
+      auto IsImplicitExpr = [](const Expr *E) {
         if (!E)
           return false;
         // We assume that a constructor expression is implict (was inserted by
         // clang) if it has an invalid paren/brace location, since such
         // experssion is impossible to write down.
         if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E))
-          return CtorExpr->getNumArgs() > 0 &&
-                 CtorExpr->getParenOrBraceRange().isInvalid();
+          return CtorExpr->getParenOrBraceRange().isInvalid();
         return isa<ImplicitCastExpr>(E);
       };
 
-      bool IsExplicit = !isImplicitExpr(ASTNode.OrigE);
+      if (IsImplicitExpr(ASTNode.OrigE))
+        return true;
       // Find and add definition declarations (for GoToDefinition).
       // We don't use parameter `D`, as Parameter `D` is the canonical
       // declaration, which is the first declaration of a redeclarable
       // declaration, and it could be a forward declaration.
       if (const auto *Def = getDefinition(D)) {
-        Decls[Def] |= IsExplicit;
+        Decls.insert(Def);
       } else {
         // Couldn't find a definition, fall back to use `D`.
-        Decls[D] |= IsExplicit;
+        Decls.insert(D);
       }
     }
     return true;
@@ -197,7 +222,7 @@
 };
 
 struct IdentifiedSymbol {
-  std::vector<DeclInfo> Decls;
+  std::vector<const Decl *> Decls;
   std::vector<MacroDecl> Macros;
 };
 
@@ -208,6 +233,8 @@
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
   IndexOpts.IndexFunctionLocals = true;
+  IndexOpts.IndexParametersInDeclarations = true;
+  IndexOpts.IndexTemplateParameters = true;
   indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(),
                      AST.getLocalTopLevelDecls(), DeclMacrosFinder, IndexOpts);
 
@@ -241,8 +268,8 @@
 
 } // namespace
 
-std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos,
-                                      const SymbolIndex *Index) {
+std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
+                                          const SymbolIndex *Index) {
   const auto &SM = AST.getASTContext().getSourceManager();
   auto MainFilePath =
       getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
@@ -251,116 +278,99 @@
     return {};
   }
 
-  std::vector<Location> Result;
-  // Handle goto definition for #include.
+  // Treat #included files as symbols, to enable go-to-definition on them.
   for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) {
-    if (!Inc.Resolved.empty() && Inc.R.start.line == Pos.line)
-      Result.push_back(
-          Location{URIForFile::canonicalize(Inc.Resolved, *MainFilePath), {}});
+    if (!Inc.Resolved.empty() && Inc.R.start.line == Pos.line) {
+      LocatedSymbol File;
+      File.Name = llvm::sys::path::filename(Inc.Resolved);
+      File.PreferredDeclaration = {
+          URIForFile::canonicalize(Inc.Resolved, *MainFilePath), Range{}};
+      File.Definition = File.PreferredDeclaration;
+      // We're not going to find any further symbols on #include lines.
+      return {std::move(File)};
+    }
   }
-  if (!Result.empty())
-    return Result;
 
-  // Identified symbols at a specific position.
   SourceLocation SourceLocationBeg =
       getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
   auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg);
 
-  for (auto Item : Symbols.Macros) {
-    auto Loc = Item.Info->getDefinitionLoc();
-    auto L = makeLocation(AST, Loc, *MainFilePath);
-    if (L)
-      Result.push_back(*L);
+  // Macros are simple: there's no declaration/definition distinction.
+  // As a consequence, there's no need to look them up in the index either.
+  std::vector<LocatedSymbol> Result;
+  for (auto M : Symbols.Macros) {
+    if (auto Loc =
+            makeLocation(AST, M.Info->getDefinitionLoc(), *MainFilePath)) {
+      LocatedSymbol Macro;
+      Macro.Name = M.Name;
+      Macro.PreferredDeclaration = *Loc;
+      Macro.Definition = Loc;
+      Result.push_back(std::move(Macro));
+    }
   }
 
-  // Declaration and definition are different terms in C-family languages, and
-  // LSP only defines the "GoToDefinition" specification, so we try to perform
-  // the "most sensible" GoTo operation:
-  //
-  //  - We use the location from AST and index (if available) to provide the
-  //    final results. When there are duplicate results, we prefer AST over
-  //    index because AST is more up-to-date.
-  //
-  //  - For each symbol, we will return a location of the canonical declaration
-  //    (e.g. function declaration in header), and a location of definition if
-  //    they are available.
-  //
-  // So the work flow:
-  //
-  //   1. Identify the symbols being search for by traversing the AST.
-  //   2. Populate one of the locations with the AST location.
-  //   3. Use the AST information to query the index, and populate the index
-  //      location (if available).
-  //   4. Return all populated locations for all symbols, definition first (
-  //      which  we think is the users wants most often).
-  struct CandidateLocation {
-    llvm::Optional<Location> Def;
-    llvm::Optional<Location> Decl;
-  };
-  // We respect the order in Symbols.Decls.
-  llvm::SmallVector<CandidateLocation, 8> ResultCandidates;
-  llvm::DenseMap<SymbolID, size_t> CandidatesIndex;
+  // Decls are more complicated.
+  // The AST contains at least a declaration, maybe a definition.
+  // These are up-to-date, and so generally preferred over index results.
+  // We perform a single batch index lookup to find additional definitions.
+
+  // Results follow the order of Symbols.Decls.
+  // Keep track of SymbolID -> index mapping, to fill in index data later.
+  llvm::DenseMap<SymbolID, size_t> ResultIndex;
 
   // Emit all symbol locations (declaration or definition) from AST.
-  for (const DeclInfo &DI : Symbols.Decls) {
-    const Decl *D = DI.D;
-    // Fake key for symbols don't have USR (no SymbolID).
-    // Ideally, there should be a USR for each identified symbols. Symbols
-    // without USR are rare and unimportant cases, we use the a fake holder to
-    // minimize the invasiveness of these cases.
-    SymbolID Key("");
+  for (const Decl *D : Symbols.Decls) {
+    auto Loc = makeLocation(AST, findNameLoc(D), *MainFilePath);
+    if (!Loc)
+      continue;
+
+    Result.emplace_back();
+    if (auto *ND = dyn_cast<NamedDecl>(D))
+      Result.back().Name = printName(AST.getASTContext(), *ND);
+    Result.back().PreferredDeclaration = *Loc;
+    // DeclInfo.D is always a definition if possible, so this check works.
+    if (getDefinition(D) == D)
+      Result.back().Definition = *Loc;
+
+    // Record SymbolID for index lookup later.
     if (auto ID = getSymbolID(D))
-      Key = *ID;
-
-    auto R = CandidatesIndex.try_emplace(Key, ResultCandidates.size());
-    if (R.second) // new entry
-      ResultCandidates.emplace_back();
-    auto &Candidate = ResultCandidates[R.first->second];
-
-    auto Loc = findNameLoc(D);
-    auto L = makeLocation(AST, Loc, *MainFilePath);
-    // The declaration in the identified symbols is a definition if possible
-    // otherwise it is declaration.
-    bool IsDef = getDefinition(D) == D;
-    // Populate one of the slots with location for the AST.
-    if (!IsDef)
-      Candidate.Decl = L;
-    else
-      Candidate.Def = L;
+      ResultIndex[*ID] = Result.size() - 1;
   }
 
-  if (Index) {
+  // Now query the index for all Symbol IDs we found in the AST.
+  if (Index && !ResultIndex.empty()) {
     LookupRequest QueryRequest;
-    // Build request for index query, using SymbolID.
-    for (auto It : CandidatesIndex)
+    for (auto It : ResultIndex)
       QueryRequest.IDs.insert(It.first);
-    std::string TUPath;
-    const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID());
-    if (auto Path = getCanonicalPath(FE, SM))
-      TUPath = *Path;
-    // Query the index and populate the empty slot.
-    Index->lookup(QueryRequest, [&TUPath, &ResultCandidates,
-                                 &CandidatesIndex](const Symbol &Sym) {
-      auto It = CandidatesIndex.find(Sym.ID);
-      assert(It != CandidatesIndex.end());
-      auto &Value = ResultCandidates[It->second];
+    std::string Scratch;
+    Index->lookup(QueryRequest, [&](const Symbol &Sym) {
+      auto &R = Result[ResultIndex.lookup(Sym.ID)];
 
-      if (!Value.Def)
-        Value.Def = toLSPLocation(Sym.Definition, TUPath);
-      if (!Value.Decl)
-        Value.Decl = toLSPLocation(Sym.CanonicalDeclaration, TUPath);
+      if (R.Definition) { // from AST
+        // Special case: if the AST yielded a definition, then it may not be
+        // the right *declaration*. Prefer the one from the index.
+        if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, *MainFilePath))
+          R.PreferredDeclaration = *Loc;
+
+        // We might still prefer the definition from the index, e.g. for
+        // generated symbols.
+        if (auto Loc = toLSPLocation(
+                getPreferredLocation(*R.Definition, Sym.Definition, Scratch),
+                *MainFilePath))
+          R.Definition = *Loc;
+      } else {
+        R.Definition = toLSPLocation(Sym.Definition, *MainFilePath);
+
+        // Use merge logic to choose AST or index declaration.
+        if (auto Loc = toLSPLocation(
+                getPreferredLocation(R.PreferredDeclaration,
+                                     Sym.CanonicalDeclaration, Scratch),
+                *MainFilePath))
+          R.PreferredDeclaration = *Loc;
+      }
     });
   }
 
-  // Populate the results, definition first.
-  for (const auto &Candidate : ResultCandidates) {
-    if (Candidate.Def)
-      Result.push_back(*Candidate.Def);
-    if (Candidate.Decl &&
-        Candidate.Decl != Candidate.Def) // Decl and Def might be the same
-      Result.push_back(*Candidate.Decl);
-  }
-
   return Result;
 }
 
@@ -424,6 +434,8 @@
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
   IndexOpts.IndexFunctionLocals = true;
+  IndexOpts.IndexParametersInDeclarations = true;
+  IndexOpts.IndexTemplateParameters = true;
   indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(),
                      AST.getLocalTopLevelDecls(), RefFinder, IndexOpts);
   return std::move(RefFinder).take();
@@ -436,11 +448,7 @@
   const SourceManager &SM = AST.getASTContext().getSourceManager();
   auto Symbols = getSymbolAtPosition(
       AST, getBeginningOfIdentifier(AST, Pos, SM.getMainFileID()));
-  std::vector<const Decl *> TargetDecls;
-  for (const DeclInfo &DI : Symbols.Decls) {
-    TargetDecls.push_back(DI.D);
-  }
-  auto References = findRefs(TargetDecls, AST);
+  auto References = findRefs(Symbols.Decls, AST);
 
   std::vector<DocumentHighlight> Result;
   for (const auto &Ref : References) {
@@ -561,13 +569,30 @@
   return H;
 }
 
-/// Generate a \p Hover object given the macro \p MacroInf.
-static Hover getHoverContents(llvm::StringRef MacroName) {
+/// Generate a \p Hover object given the macro \p MacroDecl.
+static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+  SourceManager &SM = AST.getASTContext().getSourceManager();
+  std::string Definition = Decl.Name;
+
+  // Try to get the full definition, not just the name
+  SourceLocation StartLoc = Decl.Info->getDefinitionLoc();
+  SourceLocation EndLoc = Decl.Info->getDefinitionEndLoc();
+  if (EndLoc.isValid()) {
+    EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, SM,
+                                        AST.getASTContext().getLangOpts());
+    bool Invalid;
+    StringRef Buffer = SM.getBufferData(SM.getFileID(StartLoc), &Invalid);
+    if (!Invalid) {
+      unsigned StartOffset = SM.getFileOffset(StartLoc);
+      unsigned EndOffset = SM.getFileOffset(EndLoc);
+      if (EndOffset <= Buffer.size() && StartOffset < EndOffset)
+        Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str();
+    }
+  }
+
   Hover H;
-
-  H.contents.value = "#define ";
-  H.contents.value += MacroName;
-
+  H.contents.kind = MarkupKind::PlainText;
+  H.contents.value = "#define " + Definition;
   return H;
 }
 
@@ -691,10 +716,10 @@
   auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg);
 
   if (!Symbols.Macros.empty())
-    return getHoverContents(Symbols.Macros[0].Name);
+    return getHoverContents(Symbols.Macros[0], AST);
 
   if (!Symbols.Decls.empty())
-    return getHoverContents(Symbols.Decls[0].D);
+    return getHoverContents(Symbols.Decls[0]);
 
   auto DeducedType = getDeducedType(AST, SourceLocationBeg);
   if (DeducedType && !DeducedType->isNull())
@@ -718,15 +743,9 @@
   auto Loc = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
   auto Symbols = getSymbolAtPosition(AST, Loc);
 
-  std::vector<const Decl *> TargetDecls;
-  for (const DeclInfo &DI : Symbols.Decls) {
-    if (DI.IsReferencedExplicitly)
-      TargetDecls.push_back(DI.D);
-  }
-
   // We traverse the AST to find references in the main file.
   // TODO: should we handle macros, too?
-  auto MainFileRefs = findRefs(TargetDecls, AST);
+  auto MainFileRefs = findRefs(Symbols.Decls, AST);
   for (const auto &Ref : MainFileRefs) {
     Location Result;
     Result.range = getTokenRange(AST, Ref.Loc);
@@ -739,7 +758,7 @@
     RefsRequest Req;
     Req.Limit = Limit;
 
-    for (const Decl *D : TargetDecls) {
+    for (const Decl *D : Symbols.Decls) {
       // Not all symbols can be referenced from outside (e.g. function-locals).
       // TODO: we could skip TU-scoped symbols here (e.g. static functions) if
       // we know this file isn't a header. The details might be tricky.
@@ -770,9 +789,9 @@
 
   std::vector<SymbolDetails> Results;
 
-  for (const auto &Sym : Symbols.Decls) {
+  for (const Decl *D : Symbols.Decls) {
     SymbolDetails NewSymbol;
-    if (const NamedDecl *ND = dyn_cast<NamedDecl>(Sym.D)) {
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
       std::string QName = printQualifiedName(*ND);
       std::tie(NewSymbol.containerName, NewSymbol.name) =
           splitQualifiedName(QName);
@@ -784,7 +803,7 @@
       }
     }
     llvm::SmallString<32> USR;
-    if (!index::generateUSRForDecl(Sym.D, USR)) {
+    if (!index::generateUSRForDecl(D, USR)) {
       NewSymbol.USR = USR.str();
       NewSymbol.ID = SymbolID(NewSymbol.USR);
     }
@@ -795,7 +814,8 @@
     SymbolDetails NewMacro;
     NewMacro.name = Macro.Name;
     llvm::SmallString<32> USR;
-    if (!index::generateUSRForMacro(NewMacro.name, Loc, SM, USR)) {
+    if (!index::generateUSRForMacro(NewMacro.name,
+                                    Macro.Info->getDefinitionLoc(), SM, USR)) {
       NewMacro.USR = USR.str();
       NewMacro.ID = SymbolID(NewMacro.USR);
     }
@@ -805,5 +825,171 @@
   return Results;
 }
 
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) {
+  OS << S.Name << ": " << S.PreferredDeclaration;
+  if (S.Definition)
+    OS << " def=" << *S.Definition;
+  return OS;
+}
+
+// FIXME(nridge): Reduce duplication between this function and declToSym().
+static llvm::Optional<TypeHierarchyItem>
+declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
+  auto &SM = Ctx.getSourceManager();
+
+  SourceLocation NameLoc = findNameLoc(&ND);
+  // getFileLoc is a good choice for us, but we also need to make sure
+  // sourceLocToPosition won't switch files, so we call getSpellingLoc on top of
+  // that to make sure it does not switch files.
+  // FIXME: sourceLocToPosition should not switch files!
+  SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  if (NameLoc.isInvalid() || BeginLoc.isInvalid() || EndLoc.isInvalid())
+    return llvm::None;
+
+  Position NameBegin = sourceLocToPosition(SM, NameLoc);
+  Position NameEnd = sourceLocToPosition(
+      SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
+
+  index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
+  // FIXME: this is not classifying constructors, destructors and operators
+  //        correctly (they're all "methods").
+  SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind);
+
+  TypeHierarchyItem THI;
+  THI.name = printName(Ctx, ND);
+  THI.kind = SK;
+  THI.deprecated = ND.isDeprecated();
+  THI.range =
+      Range{sourceLocToPosition(SM, BeginLoc), sourceLocToPosition(SM, EndLoc)};
+  THI.selectionRange = Range{NameBegin, NameEnd};
+  if (!THI.range.contains(THI.selectionRange)) {
+    // 'selectionRange' must be contained in 'range', so in cases where clang
+    // reports unrelated ranges we need to reconcile somehow.
+    THI.range = THI.selectionRange;
+  }
+
+  auto FilePath =
+      getCanonicalPath(SM.getFileEntryForID(SM.getFileID(BeginLoc)), SM);
+  auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
+  if (!FilePath || !TUPath)
+    return llvm::None; // Not useful without a uri.
+  THI.uri = URIForFile::canonicalize(*FilePath, *TUPath);
+
+  return THI;
+}
+
+using RecursionProtectionSet = llvm::SmallSet<const CXXRecordDecl *, 4>;
+
+static Optional<TypeHierarchyItem>
+getTypeAncestors(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
+                 RecursionProtectionSet &RPSet) {
+  Optional<TypeHierarchyItem> Result = declToTypeHierarchyItem(ASTCtx, CXXRD);
+  if (!Result)
+    return Result;
+
+  Result->parents.emplace();
+
+  // typeParents() will replace dependent template specializations
+  // with their class template, so to avoid infinite recursion for
+  // certain types of hierarchies, keep the templates encountered
+  // along the parent chain in a set, and stop the recursion if one
+  // starts to repeat.
+  auto *Pattern = CXXRD.getDescribedTemplate() ? &CXXRD : nullptr;
+  if (Pattern) {
+    if (!RPSet.insert(Pattern).second) {
+      return Result;
+    }
+  }
+
+  for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
+    if (Optional<TypeHierarchyItem> ParentSym =
+            getTypeAncestors(*ParentDecl, ASTCtx, RPSet)) {
+      Result->parents->emplace_back(std::move(*ParentSym));
+    }
+  }
+
+  if (Pattern) {
+    RPSet.erase(Pattern);
+  }
+
+  return Result;
+}
+
+const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) {
+  ASTContext &ASTCtx = AST.getASTContext();
+  const SourceManager &SourceMgr = ASTCtx.getSourceManager();
+  SourceLocation SourceLocationBeg =
+      getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID());
+  IdentifiedSymbol Symbols = getSymbolAtPosition(AST, SourceLocationBeg);
+  if (Symbols.Decls.empty())
+    return nullptr;
+
+  const Decl *D = Symbols.Decls[0];
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    // If this is a variable, use the type of the variable.
+    return VD->getType().getTypePtr()->getAsCXXRecordDecl();
+  }
+
+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+    // If this is a method, use the type of the class.
+    return Method->getParent();
+  }
+
+  // We don't handle FieldDecl because it's not clear what behaviour
+  // the user would expect: the enclosing class type (as with a
+  // method), or the field's type (as with a variable).
+
+  return dyn_cast<CXXRecordDecl>(D);
+}
+
+std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD) {
+  std::vector<const CXXRecordDecl *> Result;
+
+  for (auto Base : CXXRD->bases()) {
+    const CXXRecordDecl *ParentDecl = nullptr;
+
+    const Type *Type = Base.getType().getTypePtr();
+    if (const RecordType *RT = Type->getAs<RecordType>()) {
+      ParentDecl = RT->getAsCXXRecordDecl();
+    }
+
+    if (!ParentDecl) {
+      // Handle a dependent base such as "Base<T>" by using the primary
+      // template.
+      if (const TemplateSpecializationType *TS =
+              Type->getAs<TemplateSpecializationType>()) {
+        TemplateName TN = TS->getTemplateName();
+        if (TemplateDecl *TD = TN.getAsTemplateDecl()) {
+          ParentDecl = dyn_cast<CXXRecordDecl>(TD->getTemplatedDecl());
+        }
+      }
+    }
+
+    if (ParentDecl)
+      Result.push_back(ParentDecl);
+  }
+
+  return Result;
+}
+
+llvm::Optional<TypeHierarchyItem>
+getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels,
+                 TypeHierarchyDirection Direction) {
+  const CXXRecordDecl *CXXRD = findRecordTypeAt(AST, Pos);
+  if (!CXXRD)
+    return llvm::None;
+
+  RecursionProtectionSet RPSet;
+  Optional<TypeHierarchyItem> Result =
+      getTypeAncestors(*CXXRD, AST.getASTContext(), RPSet);
+
+  // FIXME(nridge): Resolve type descendants if direction is Children or Both,
+  // and ResolveLevels > 0.
+
+  return Result;
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/XRefs.h b/clangd/XRefs.h
index 631879d..008bba5 100644
--- a/clangd/XRefs.h
+++ b/clangd/XRefs.h
@@ -1,9 +1,8 @@
 //===--- XRefs.h -------------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -23,9 +22,25 @@
 namespace clang {
 namespace clangd {
 
+// Describes where a symbol is declared and defined (as far as clangd knows).
+// There are three cases:
+//  - a declaration only, no definition is known (e.g. only header seen)
+//  - a declaration and a distinct definition (e.g. function declared in header)
+//  - a declaration and an equal definition (e.g. inline function, or class)
+// For some types of symbol, e.g. macros, definition == declaration always.
+struct LocatedSymbol {
+  // The (unqualified) name of the symbol.
+  std::string Name;
+  // The canonical or best declaration: where most users find its interface.
+  Location PreferredDeclaration;
+  // Where the symbol is defined, if known. May equal PreferredDeclaration.
+  llvm::Optional<Location> Definition;
+};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const LocatedSymbol &);
 /// Get definition of symbol at a specified \p Pos.
-std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos,
-                                      const SymbolIndex *Index = nullptr);
+/// Multiple locations may be returned, corresponding to distinct symbols.
+std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
+                                          const SymbolIndex *Index = nullptr);
 
 /// Returns highlights for all usages of a symbol at \p Pos.
 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
@@ -43,6 +58,17 @@
 /// Get info about symbols at \p Pos.
 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos);
 
+/// Find the record type references at \p Pos.
+const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos);
+
+/// Given a record type declaration, find its base (parent) types.
+std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD);
+
+/// Get type hierarchy information at \p Pos.
+llvm::Optional<TypeHierarchyItem>
+getTypeHierarchy(ParsedAST &AST, Position Pos, int Resolve,
+                 TypeHierarchyDirection Direction);
+
 } // namespace clangd
 } // namespace clang
 
diff --git a/clangd/benchmarks/IndexBenchmark.cpp b/clangd/benchmarks/IndexBenchmark.cpp
index d71f8fe..439ac9c 100644
--- a/clangd/benchmarks/IndexBenchmark.cpp
+++ b/clangd/benchmarks/IndexBenchmark.cpp
@@ -1,9 +1,8 @@
 //===--- IndexBenchmark.cpp - Clangd index benchmarks -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/clients/clangd-vscode/.gitignore b/clangd/clients/clangd-vscode/.gitignore
index 1294fe2..5df8049 100644
--- a/clangd/clients/clangd-vscode/.gitignore
+++ b/clangd/clients/clangd-vscode/.gitignore
@@ -1,3 +1,2 @@
 out
 node_modules
-package-lock.json
diff --git a/clangd/clients/clangd-vscode/package-lock.json b/clangd/clients/clangd-vscode/package-lock.json
new file mode 100644
index 0000000..9068591
--- /dev/null
+++ b/clangd/clients/clangd-vscode/package-lock.json
@@ -0,0 +1,2027 @@
+{
+    "name": "vscode-clangd",
+    "version": "0.0.10",
+    "lockfileVersion": 1,
+    "requires": true,
+    "dependencies": {
+        "@types/mocha": {
+            "version": "2.2.48",
+            "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz",
+            "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==",
+            "dev": true
+        },
+        "@types/node": {
+            "version": "6.14.2",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.2.tgz",
+            "integrity": "sha512-JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q==",
+            "dev": true
+        },
+        "ajv": {
+            "version": "6.8.1",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+            "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
+            "dev": true,
+            "requires": {
+                "fast-deep-equal": "^2.0.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+            }
+        },
+        "ansi-cyan": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
+            "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
+            "dev": true,
+            "requires": {
+                "ansi-wrap": "0.1.0"
+            }
+        },
+        "ansi-red": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
+            "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
+            "dev": true,
+            "requires": {
+                "ansi-wrap": "0.1.0"
+            }
+        },
+        "ansi-wrap": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+            "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+            "dev": true
+        },
+        "append-buffer": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+            "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+            "dev": true,
+            "requires": {
+                "buffer-equal": "^1.0.0"
+            }
+        },
+        "arr-diff": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
+            "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
+            "dev": true,
+            "requires": {
+                "arr-flatten": "^1.0.1",
+                "array-slice": "^0.2.3"
+            }
+        },
+        "arr-flatten": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+            "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+            "dev": true
+        },
+        "arr-union": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
+            "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
+            "dev": true
+        },
+        "array-differ": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+            "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
+            "dev": true
+        },
+        "array-slice": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+            "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+            "dev": true
+        },
+        "array-union": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+            "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+            "dev": true,
+            "requires": {
+                "array-uniq": "^1.0.1"
+            }
+        },
+        "array-uniq": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+            "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+            "dev": true
+        },
+        "arrify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+            "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+            "dev": true
+        },
+        "asn1": {
+            "version": "0.2.4",
+            "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+            "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+            "dev": true,
+            "requires": {
+                "safer-buffer": "~2.1.0"
+            }
+        },
+        "assert-plus": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+            "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+            "dev": true
+        },
+        "asynckit": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+            "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+            "dev": true
+        },
+        "aws-sign2": {
+            "version": "0.7.0",
+            "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+            "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+            "dev": true
+        },
+        "aws4": {
+            "version": "1.8.0",
+            "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+            "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+            "dev": true
+        },
+        "balanced-match": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+            "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+            "dev": true
+        },
+        "bcrypt-pbkdf": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+            "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+            "dev": true,
+            "requires": {
+                "tweetnacl": "^0.14.3"
+            }
+        },
+        "block-stream": {
+            "version": "0.0.9",
+            "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+            "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+            "dev": true,
+            "requires": {
+                "inherits": "~2.0.0"
+            }
+        },
+        "brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dev": true,
+            "requires": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "browser-stdout": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+            "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+            "dev": true
+        },
+        "buffer-crc32": {
+            "version": "0.2.13",
+            "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+            "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+            "dev": true
+        },
+        "buffer-equal": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+            "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+            "dev": true
+        },
+        "buffer-from": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+            "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+            "dev": true
+        },
+        "caseless": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+            "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+            "dev": true
+        },
+        "clone": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+            "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+            "dev": true
+        },
+        "clone-buffer": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+            "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+            "dev": true
+        },
+        "clone-stats": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
+            "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
+            "dev": true
+        },
+        "cloneable-readable": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
+            "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
+            "dev": true,
+            "requires": {
+                "inherits": "^2.0.1",
+                "process-nextick-args": "^2.0.0",
+                "readable-stream": "^2.3.5"
+            }
+        },
+        "combined-stream": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+            "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+            "dev": true,
+            "requires": {
+                "delayed-stream": "~1.0.0"
+            }
+        },
+        "commander": {
+            "version": "2.15.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+            "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+            "dev": true
+        },
+        "concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+            "dev": true
+        },
+        "convert-source-map": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+            "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+            "dev": true,
+            "requires": {
+                "safe-buffer": "~5.1.1"
+            }
+        },
+        "core-util-is": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+            "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+            "dev": true
+        },
+        "dashdash": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+            "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+            "dev": true,
+            "requires": {
+                "assert-plus": "^1.0.0"
+            }
+        },
+        "debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "dev": true,
+            "requires": {
+                "ms": "2.0.0"
+            }
+        },
+        "deep-assign": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz",
+            "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=",
+            "dev": true,
+            "requires": {
+                "is-obj": "^1.0.0"
+            }
+        },
+        "define-properties": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+            "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+            "dev": true,
+            "requires": {
+                "object-keys": "^1.0.12"
+            }
+        },
+        "delayed-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+            "dev": true
+        },
+        "diff": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+            "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+            "dev": true
+        },
+        "duplexer": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+            "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+            "dev": true
+        },
+        "duplexify": {
+            "version": "3.7.1",
+            "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+            "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+            "dev": true,
+            "requires": {
+                "end-of-stream": "^1.0.0",
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "ecc-jsbn": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+            "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+            "dev": true,
+            "requires": {
+                "jsbn": "~0.1.0",
+                "safer-buffer": "^2.1.0"
+            }
+        },
+        "end-of-stream": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+            "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+            "dev": true,
+            "requires": {
+                "once": "^1.4.0"
+            }
+        },
+        "escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+            "dev": true
+        },
+        "event-stream": {
+            "version": "3.3.4",
+            "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+            "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+            "dev": true,
+            "requires": {
+                "duplexer": "~0.1.1",
+                "from": "~0",
+                "map-stream": "~0.1.0",
+                "pause-stream": "0.0.11",
+                "split": "0.3",
+                "stream-combiner": "~0.0.4",
+                "through": "~2.3.1"
+            }
+        },
+        "extend": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+            "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+            "dev": true
+        },
+        "extend-shallow": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
+            "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
+            "dev": true,
+            "requires": {
+                "kind-of": "^1.1.0"
+            }
+        },
+        "extsprintf": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+            "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+            "dev": true
+        },
+        "fast-deep-equal": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+            "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+            "dev": true
+        },
+        "fast-json-stable-stringify": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+            "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+            "dev": true
+        },
+        "fd-slicer": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+            "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+            "dev": true,
+            "requires": {
+                "pend": "~1.2.0"
+            }
+        },
+        "flush-write-stream": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.0.tgz",
+            "integrity": "sha512-6MHED/cmsyux1G4/Cek2Z776y9t7WCNd3h2h/HW91vFeU7pzMhA8XvAlDhHcanG5IWuIh/xcC7JASY4WQpG6xg==",
+            "dev": true,
+            "requires": {
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            },
+            "dependencies": {
+                "readable-stream": {
+                    "version": "3.1.1",
+                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
+                    "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
+                    "dev": true,
+                    "requires": {
+                        "inherits": "^2.0.3",
+                        "string_decoder": "^1.1.1",
+                        "util-deprecate": "^1.0.1"
+                    }
+                }
+            }
+        },
+        "forever-agent": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+            "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+            "dev": true
+        },
+        "form-data": {
+            "version": "2.3.3",
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+            "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+            "dev": true,
+            "requires": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "^1.0.6",
+                "mime-types": "^2.1.12"
+            }
+        },
+        "from": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+            "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
+            "dev": true
+        },
+        "fs-mkdirp-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+            "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
+            "dev": true,
+            "requires": {
+                "graceful-fs": "^4.1.11",
+                "through2": "^2.0.3"
+            }
+        },
+        "fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+            "dev": true
+        },
+        "fstream": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+            "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+            "dev": true,
+            "requires": {
+                "graceful-fs": "^4.1.2",
+                "inherits": "~2.0.0",
+                "mkdirp": ">=0.5 0",
+                "rimraf": "2"
+            }
+        },
+        "function-bind": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+            "dev": true
+        },
+        "getpass": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+            "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+            "dev": true,
+            "requires": {
+                "assert-plus": "^1.0.0"
+            }
+        },
+        "glob": {
+            "version": "7.1.2",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+            "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+            "dev": true,
+            "requires": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.0.4",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            }
+        },
+        "glob-parent": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+            "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+            "dev": true,
+            "requires": {
+                "is-glob": "^3.1.0",
+                "path-dirname": "^1.0.0"
+            }
+        },
+        "glob-stream": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+            "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+            "dev": true,
+            "requires": {
+                "extend": "^3.0.0",
+                "glob": "^7.1.1",
+                "glob-parent": "^3.1.0",
+                "is-negated-glob": "^1.0.0",
+                "ordered-read-streams": "^1.0.0",
+                "pumpify": "^1.3.5",
+                "readable-stream": "^2.1.5",
+                "remove-trailing-separator": "^1.0.1",
+                "to-absolute-glob": "^2.0.0",
+                "unique-stream": "^2.0.2"
+            },
+            "dependencies": {
+                "glob": {
+                    "version": "7.1.3",
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+                    "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+                    "dev": true,
+                    "requires": {
+                        "fs.realpath": "^1.0.0",
+                        "inflight": "^1.0.4",
+                        "inherits": "2",
+                        "minimatch": "^3.0.4",
+                        "once": "^1.3.0",
+                        "path-is-absolute": "^1.0.0"
+                    }
+                },
+                "minimatch": {
+                    "version": "3.0.4",
+                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+                    "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+                    "dev": true,
+                    "requires": {
+                        "brace-expansion": "^1.1.7"
+                    }
+                }
+            }
+        },
+        "graceful-fs": {
+            "version": "4.1.15",
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+            "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+            "dev": true
+        },
+        "growl": {
+            "version": "1.10.5",
+            "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+            "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+            "dev": true
+        },
+        "gulp-chmod": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz",
+            "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=",
+            "dev": true,
+            "requires": {
+                "deep-assign": "^1.0.0",
+                "stat-mode": "^0.2.0",
+                "through2": "^2.0.0"
+            }
+        },
+        "gulp-filter": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.1.0.tgz",
+            "integrity": "sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM=",
+            "dev": true,
+            "requires": {
+                "multimatch": "^2.0.0",
+                "plugin-error": "^0.1.2",
+                "streamfilter": "^1.0.5"
+            }
+        },
+        "gulp-gunzip": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/gulp-gunzip/-/gulp-gunzip-1.0.0.tgz",
+            "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=",
+            "dev": true,
+            "requires": {
+                "through2": "~0.6.5",
+                "vinyl": "~0.4.6"
+            },
+            "dependencies": {
+                "isarray": {
+                    "version": "0.0.1",
+                    "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                    "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+                    "dev": true
+                },
+                "readable-stream": {
+                    "version": "1.0.34",
+                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+                    "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+                    "dev": true,
+                    "requires": {
+                        "core-util-is": "~1.0.0",
+                        "inherits": "~2.0.1",
+                        "isarray": "0.0.1",
+                        "string_decoder": "~0.10.x"
+                    }
+                },
+                "string_decoder": {
+                    "version": "0.10.31",
+                    "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+                    "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+                    "dev": true
+                },
+                "through2": {
+                    "version": "0.6.5",
+                    "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+                    "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+                    "dev": true,
+                    "requires": {
+                        "readable-stream": ">=1.0.33-1 <1.1.0-0",
+                        "xtend": ">=4.0.0 <4.1.0-0"
+                    }
+                }
+            }
+        },
+        "gulp-remote-src-vscode": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/gulp-remote-src-vscode/-/gulp-remote-src-vscode-0.5.1.tgz",
+            "integrity": "sha512-mw4OGjtC/jlCWJFhbcAlel4YPvccChlpsl3JceNiB/DLJi24/UPxXt53/N26lgI3dknEqd4ErfdHrO8sJ5bATQ==",
+            "dev": true,
+            "requires": {
+                "event-stream": "3.3.4",
+                "node.extend": "^1.1.2",
+                "request": "^2.79.0",
+                "through2": "^2.0.3",
+                "vinyl": "^2.0.1"
+            },
+            "dependencies": {
+                "clone": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+                    "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+                    "dev": true
+                },
+                "clone-stats": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+                    "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+                    "dev": true
+                },
+                "vinyl": {
+                    "version": "2.2.0",
+                    "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+                    "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+                    "dev": true,
+                    "requires": {
+                        "clone": "^2.1.1",
+                        "clone-buffer": "^1.0.0",
+                        "clone-stats": "^1.0.0",
+                        "cloneable-readable": "^1.0.0",
+                        "remove-trailing-separator": "^1.0.1",
+                        "replace-ext": "^1.0.0"
+                    }
+                }
+            }
+        },
+        "gulp-untar": {
+            "version": "0.0.7",
+            "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.7.tgz",
+            "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==",
+            "dev": true,
+            "requires": {
+                "event-stream": "~3.3.4",
+                "streamifier": "~0.1.1",
+                "tar": "^2.2.1",
+                "through2": "~2.0.3",
+                "vinyl": "^1.2.0"
+            },
+            "dependencies": {
+                "clone": {
+                    "version": "1.0.4",
+                    "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+                    "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+                    "dev": true
+                },
+                "replace-ext": {
+                    "version": "0.0.1",
+                    "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
+                    "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
+                    "dev": true
+                },
+                "vinyl": {
+                    "version": "1.2.0",
+                    "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
+                    "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
+                    "dev": true,
+                    "requires": {
+                        "clone": "^1.0.0",
+                        "clone-stats": "^0.0.1",
+                        "replace-ext": "0.0.1"
+                    }
+                }
+            }
+        },
+        "gulp-vinyl-zip": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.2.tgz",
+            "integrity": "sha512-wJn09jsb8PyvUeyFF7y7ImEJqJwYy40BqL9GKfJs6UGpaGW9A+N68Q+ajsIpb9AeR6lAdjMbIdDPclIGo1/b7Q==",
+            "dev": true,
+            "requires": {
+                "event-stream": "3.3.4",
+                "queue": "^4.2.1",
+                "through2": "^2.0.3",
+                "vinyl": "^2.0.2",
+                "vinyl-fs": "^3.0.3",
+                "yauzl": "^2.2.1",
+                "yazl": "^2.2.1"
+            },
+            "dependencies": {
+                "clone": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+                    "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+                    "dev": true
+                },
+                "clone-stats": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+                    "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+                    "dev": true
+                },
+                "vinyl": {
+                    "version": "2.2.0",
+                    "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+                    "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+                    "dev": true,
+                    "requires": {
+                        "clone": "^2.1.1",
+                        "clone-buffer": "^1.0.0",
+                        "clone-stats": "^1.0.0",
+                        "cloneable-readable": "^1.0.0",
+                        "remove-trailing-separator": "^1.0.1",
+                        "replace-ext": "^1.0.0"
+                    }
+                }
+            }
+        },
+        "har-schema": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+            "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+            "dev": true
+        },
+        "har-validator": {
+            "version": "5.1.3",
+            "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+            "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+            "dev": true,
+            "requires": {
+                "ajv": "^6.5.5",
+                "har-schema": "^2.0.0"
+            }
+        },
+        "has": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+            "dev": true,
+            "requires": {
+                "function-bind": "^1.1.1"
+            }
+        },
+        "has-flag": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+            "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+            "dev": true
+        },
+        "has-symbols": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+            "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+            "dev": true
+        },
+        "he": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+            "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+            "dev": true
+        },
+        "http-signature": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+            "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+            "dev": true,
+            "requires": {
+                "assert-plus": "^1.0.0",
+                "jsprim": "^1.2.2",
+                "sshpk": "^1.7.0"
+            }
+        },
+        "inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+            "dev": true,
+            "requires": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+            "dev": true
+        },
+        "is": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
+            "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==",
+            "dev": true
+        },
+        "is-absolute": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+            "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+            "dev": true,
+            "requires": {
+                "is-relative": "^1.0.0",
+                "is-windows": "^1.0.1"
+            }
+        },
+        "is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+            "dev": true
+        },
+        "is-extglob": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+            "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+            "dev": true
+        },
+        "is-glob": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+            "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+            "dev": true,
+            "requires": {
+                "is-extglob": "^2.1.0"
+            }
+        },
+        "is-negated-glob": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+            "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+            "dev": true
+        },
+        "is-obj": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+            "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+            "dev": true
+        },
+        "is-relative": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+            "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+            "dev": true,
+            "requires": {
+                "is-unc-path": "^1.0.0"
+            }
+        },
+        "is-typedarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+            "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+            "dev": true
+        },
+        "is-unc-path": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+            "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+            "dev": true,
+            "requires": {
+                "unc-path-regex": "^0.1.2"
+            }
+        },
+        "is-utf8": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+            "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+            "dev": true
+        },
+        "is-valid-glob": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+            "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+            "dev": true
+        },
+        "is-windows": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+            "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+            "dev": true
+        },
+        "isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+            "dev": true
+        },
+        "isstream": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+            "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+            "dev": true
+        },
+        "jsbn": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+            "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+            "dev": true
+        },
+        "json-schema": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+            "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+            "dev": true
+        },
+        "json-schema-traverse": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+            "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+            "dev": true
+        },
+        "json-stable-stringify-without-jsonify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+            "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+            "dev": true
+        },
+        "json-stringify-safe": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+            "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+            "dev": true
+        },
+        "jsprim": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+            "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+            "dev": true,
+            "requires": {
+                "assert-plus": "1.0.0",
+                "extsprintf": "1.3.0",
+                "json-schema": "0.2.3",
+                "verror": "1.10.0"
+            }
+        },
+        "kind-of": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
+            "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
+            "dev": true
+        },
+        "lazystream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+            "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+            "dev": true,
+            "requires": {
+                "readable-stream": "^2.0.5"
+            }
+        },
+        "lead": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+            "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+            "dev": true,
+            "requires": {
+                "flush-write-stream": "^1.0.2"
+            }
+        },
+        "map-stream": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+            "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
+            "dev": true
+        },
+        "mime-db": {
+            "version": "1.37.0",
+            "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+            "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+            "dev": true
+        },
+        "mime-types": {
+            "version": "2.1.21",
+            "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+            "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+            "dev": true,
+            "requires": {
+                "mime-db": "~1.37.0"
+            }
+        },
+        "minimatch": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+            "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+            "dev": true,
+            "requires": {
+                "brace-expansion": "^1.1.7"
+            }
+        },
+        "minimist": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+            "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+            "dev": true
+        },
+        "mkdirp": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+            "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+            "dev": true,
+            "requires": {
+                "minimist": "0.0.8"
+            }
+        },
+        "mocha": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+            "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+            "dev": true,
+            "requires": {
+                "browser-stdout": "1.3.1",
+                "commander": "2.15.1",
+                "debug": "3.1.0",
+                "diff": "3.5.0",
+                "escape-string-regexp": "1.0.5",
+                "glob": "7.1.2",
+                "growl": "1.10.5",
+                "he": "1.1.1",
+                "minimatch": "3.0.4",
+                "mkdirp": "0.5.1",
+                "supports-color": "5.4.0"
+            },
+            "dependencies": {
+                "browser-stdout": {
+                    "version": "1.3.1",
+                    "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+                    "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+                    "dev": true
+                }
+            }
+        },
+        "ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+            "dev": true
+        },
+        "multimatch": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+            "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
+            "dev": true,
+            "requires": {
+                "array-differ": "^1.0.0",
+                "array-union": "^1.0.1",
+                "arrify": "^1.0.0",
+                "minimatch": "^3.0.0"
+            },
+            "dependencies": {
+                "minimatch": {
+                    "version": "3.0.4",
+                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+                    "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+                    "dev": true,
+                    "requires": {
+                        "brace-expansion": "^1.1.7"
+                    }
+                }
+            }
+        },
+        "node.extend": {
+            "version": "1.1.8",
+            "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz",
+            "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==",
+            "dev": true,
+            "requires": {
+                "has": "^1.0.3",
+                "is": "^3.2.1"
+            }
+        },
+        "normalize-path": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+            "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+            "dev": true,
+            "requires": {
+                "remove-trailing-separator": "^1.0.1"
+            }
+        },
+        "now-and-later": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz",
+            "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=",
+            "dev": true,
+            "requires": {
+                "once": "^1.3.2"
+            }
+        },
+        "oauth-sign": {
+            "version": "0.9.0",
+            "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+            "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+            "dev": true
+        },
+        "object-keys": {
+            "version": "1.0.12",
+            "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+            "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+            "dev": true
+        },
+        "object.assign": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+            "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+            "dev": true,
+            "requires": {
+                "define-properties": "^1.1.2",
+                "function-bind": "^1.1.1",
+                "has-symbols": "^1.0.0",
+                "object-keys": "^1.0.11"
+            }
+        },
+        "once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+            "dev": true,
+            "requires": {
+                "wrappy": "1"
+            }
+        },
+        "ordered-read-streams": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+            "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+            "dev": true,
+            "requires": {
+                "readable-stream": "^2.0.1"
+            }
+        },
+        "path-dirname": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+            "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+            "dev": true
+        },
+        "path-is-absolute": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+            "dev": true
+        },
+        "pause-stream": {
+            "version": "0.0.11",
+            "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+            "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+            "dev": true,
+            "requires": {
+                "through": "~2.3"
+            }
+        },
+        "pend": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+            "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+            "dev": true
+        },
+        "performance-now": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+            "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+            "dev": true
+        },
+        "plugin-error": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
+            "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
+            "dev": true,
+            "requires": {
+                "ansi-cyan": "^0.1.1",
+                "ansi-red": "^0.1.1",
+                "arr-diff": "^1.0.1",
+                "arr-union": "^2.0.1",
+                "extend-shallow": "^1.1.2"
+            }
+        },
+        "process-nextick-args": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+            "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+            "dev": true
+        },
+        "psl": {
+            "version": "1.1.31",
+            "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
+            "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
+            "dev": true
+        },
+        "pump": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+            "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+            "dev": true,
+            "requires": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "pumpify": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+            "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+            "dev": true,
+            "requires": {
+                "duplexify": "^3.6.0",
+                "inherits": "^2.0.3",
+                "pump": "^2.0.0"
+            }
+        },
+        "punycode": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+            "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+            "dev": true
+        },
+        "qs": {
+            "version": "6.5.2",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+            "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+            "dev": true
+        },
+        "querystringify": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz",
+            "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==",
+            "dev": true
+        },
+        "queue": {
+            "version": "4.5.1",
+            "resolved": "https://registry.npmjs.org/queue/-/queue-4.5.1.tgz",
+            "integrity": "sha512-AMD7w5hRXcFSb8s9u38acBZ+309u6GsiibP4/0YacJeaurRshogB7v/ZcVPxP5gD5+zIw6ixRHdutiYUJfwKHw==",
+            "dev": true,
+            "requires": {
+                "inherits": "~2.0.0"
+            }
+        },
+        "readable-stream": {
+            "version": "2.3.6",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+            "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+            "dev": true,
+            "requires": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.3",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~2.0.0",
+                "safe-buffer": "~5.1.1",
+                "string_decoder": "~1.1.1",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "remove-bom-buffer": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+            "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+            "dev": true,
+            "requires": {
+                "is-buffer": "^1.1.5",
+                "is-utf8": "^0.2.1"
+            }
+        },
+        "remove-bom-stream": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+            "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+            "dev": true,
+            "requires": {
+                "remove-bom-buffer": "^3.0.0",
+                "safe-buffer": "^5.1.0",
+                "through2": "^2.0.3"
+            }
+        },
+        "remove-trailing-separator": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+            "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+            "dev": true
+        },
+        "replace-ext": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+            "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+            "dev": true
+        },
+        "request": {
+            "version": "2.88.0",
+            "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+            "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+            "dev": true,
+            "requires": {
+                "aws-sign2": "~0.7.0",
+                "aws4": "^1.8.0",
+                "caseless": "~0.12.0",
+                "combined-stream": "~1.0.6",
+                "extend": "~3.0.2",
+                "forever-agent": "~0.6.1",
+                "form-data": "~2.3.2",
+                "har-validator": "~5.1.0",
+                "http-signature": "~1.2.0",
+                "is-typedarray": "~1.0.0",
+                "isstream": "~0.1.2",
+                "json-stringify-safe": "~5.0.1",
+                "mime-types": "~2.1.19",
+                "oauth-sign": "~0.9.0",
+                "performance-now": "^2.1.0",
+                "qs": "~6.5.2",
+                "safe-buffer": "^5.1.2",
+                "tough-cookie": "~2.4.3",
+                "tunnel-agent": "^0.6.0",
+                "uuid": "^3.3.2"
+            }
+        },
+        "requires-port": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+            "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+            "dev": true
+        },
+        "resolve-options": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+            "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+            "dev": true,
+            "requires": {
+                "value-or-function": "^3.0.0"
+            }
+        },
+        "rimraf": {
+            "version": "2.6.3",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+            "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+            "dev": true,
+            "requires": {
+                "glob": "^7.1.3"
+            },
+            "dependencies": {
+                "glob": {
+                    "version": "7.1.3",
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+                    "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+                    "dev": true,
+                    "requires": {
+                        "fs.realpath": "^1.0.0",
+                        "inflight": "^1.0.4",
+                        "inherits": "2",
+                        "minimatch": "^3.0.4",
+                        "once": "^1.3.0",
+                        "path-is-absolute": "^1.0.0"
+                    }
+                },
+                "minimatch": {
+                    "version": "3.0.4",
+                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+                    "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+                    "dev": true,
+                    "requires": {
+                        "brace-expansion": "^1.1.7"
+                    }
+                }
+            }
+        },
+        "safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "dev": true
+        },
+        "safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+            "dev": true
+        },
+        "semver": {
+            "version": "5.6.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+            "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
+        },
+        "source-map": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+            "dev": true
+        },
+        "source-map-support": {
+            "version": "0.5.10",
+            "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
+            "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
+            "dev": true,
+            "requires": {
+                "buffer-from": "^1.0.0",
+                "source-map": "^0.6.0"
+            }
+        },
+        "split": {
+            "version": "0.3.3",
+            "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+            "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
+            "dev": true,
+            "requires": {
+                "through": "2"
+            }
+        },
+        "sshpk": {
+            "version": "1.16.1",
+            "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+            "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+            "dev": true,
+            "requires": {
+                "asn1": "~0.2.3",
+                "assert-plus": "^1.0.0",
+                "bcrypt-pbkdf": "^1.0.0",
+                "dashdash": "^1.12.0",
+                "ecc-jsbn": "~0.1.1",
+                "getpass": "^0.1.1",
+                "jsbn": "~0.1.0",
+                "safer-buffer": "^2.0.2",
+                "tweetnacl": "~0.14.0"
+            }
+        },
+        "stat-mode": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz",
+            "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=",
+            "dev": true
+        },
+        "stream-combiner": {
+            "version": "0.0.4",
+            "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+            "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+            "dev": true,
+            "requires": {
+                "duplexer": "~0.1.1"
+            }
+        },
+        "stream-shift": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+            "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+            "dev": true
+        },
+        "streamfilter": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.7.tgz",
+            "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==",
+            "dev": true,
+            "requires": {
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "streamifier": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz",
+            "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=",
+            "dev": true
+        },
+        "string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dev": true,
+            "requires": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "supports-color": {
+            "version": "5.4.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+            "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+            "dev": true,
+            "requires": {
+                "has-flag": "^3.0.0"
+            },
+            "dependencies": {
+                "has-flag": {
+                    "version": "3.0.0",
+                    "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+                    "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+                    "dev": true
+                }
+            }
+        },
+        "tar": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+            "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+            "dev": true,
+            "requires": {
+                "block-stream": "*",
+                "fstream": "^1.0.2",
+                "inherits": "2"
+            }
+        },
+        "through": {
+            "version": "2.3.8",
+            "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+            "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+            "dev": true
+        },
+        "through2": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+            "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+            "dev": true,
+            "requires": {
+                "readable-stream": "~2.3.6",
+                "xtend": "~4.0.1"
+            }
+        },
+        "through2-filter": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+            "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+            "dev": true,
+            "requires": {
+                "through2": "~2.0.0",
+                "xtend": "~4.0.0"
+            }
+        },
+        "to-absolute-glob": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+            "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+            "dev": true,
+            "requires": {
+                "is-absolute": "^1.0.0",
+                "is-negated-glob": "^1.0.0"
+            }
+        },
+        "to-through": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+            "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+            "dev": true,
+            "requires": {
+                "through2": "^2.0.3"
+            }
+        },
+        "tough-cookie": {
+            "version": "2.4.3",
+            "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+            "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+            "dev": true,
+            "requires": {
+                "psl": "^1.1.24",
+                "punycode": "^1.4.1"
+            },
+            "dependencies": {
+                "punycode": {
+                    "version": "1.4.1",
+                    "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+                    "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+                    "dev": true
+                }
+            }
+        },
+        "tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+            "dev": true,
+            "requires": {
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "tweetnacl": {
+            "version": "0.14.5",
+            "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+            "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+            "dev": true
+        },
+        "typescript": {
+            "version": "2.9.2",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
+            "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
+            "dev": true
+        },
+        "unc-path-regex": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+            "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+            "dev": true
+        },
+        "unique-stream": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+            "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+            "dev": true,
+            "requires": {
+                "json-stable-stringify-without-jsonify": "^1.0.1",
+                "through2-filter": "^3.0.0"
+            }
+        },
+        "uri-js": {
+            "version": "4.2.2",
+            "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+            "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+            "dev": true,
+            "requires": {
+                "punycode": "^2.1.0"
+            }
+        },
+        "url-parse": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz",
+            "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==",
+            "dev": true,
+            "requires": {
+                "querystringify": "^2.0.0",
+                "requires-port": "^1.0.0"
+            }
+        },
+        "util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+            "dev": true
+        },
+        "uuid": {
+            "version": "3.3.2",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+            "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+            "dev": true
+        },
+        "value-or-function": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+            "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
+            "dev": true
+        },
+        "verror": {
+            "version": "1.10.0",
+            "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+            "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+            "dev": true,
+            "requires": {
+                "assert-plus": "^1.0.0",
+                "core-util-is": "1.0.2",
+                "extsprintf": "^1.2.0"
+            }
+        },
+        "vinyl": {
+            "version": "0.4.6",
+            "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+            "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+            "dev": true,
+            "requires": {
+                "clone": "^0.2.0",
+                "clone-stats": "^0.0.1"
+            }
+        },
+        "vinyl-fs": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+            "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+            "dev": true,
+            "requires": {
+                "fs-mkdirp-stream": "^1.0.0",
+                "glob-stream": "^6.1.0",
+                "graceful-fs": "^4.0.0",
+                "is-valid-glob": "^1.0.0",
+                "lazystream": "^1.0.0",
+                "lead": "^1.0.0",
+                "object.assign": "^4.0.4",
+                "pumpify": "^1.3.5",
+                "readable-stream": "^2.3.3",
+                "remove-bom-buffer": "^3.0.0",
+                "remove-bom-stream": "^1.2.0",
+                "resolve-options": "^1.1.0",
+                "through2": "^2.0.0",
+                "to-through": "^2.0.0",
+                "value-or-function": "^3.0.0",
+                "vinyl": "^2.0.0",
+                "vinyl-sourcemap": "^1.1.0"
+            },
+            "dependencies": {
+                "clone": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+                    "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+                    "dev": true
+                },
+                "clone-stats": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+                    "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+                    "dev": true
+                },
+                "vinyl": {
+                    "version": "2.2.0",
+                    "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+                    "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+                    "dev": true,
+                    "requires": {
+                        "clone": "^2.1.1",
+                        "clone-buffer": "^1.0.0",
+                        "clone-stats": "^1.0.0",
+                        "cloneable-readable": "^1.0.0",
+                        "remove-trailing-separator": "^1.0.1",
+                        "replace-ext": "^1.0.0"
+                    }
+                }
+            }
+        },
+        "vinyl-source-stream": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.2.tgz",
+            "integrity": "sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A=",
+            "dev": true,
+            "requires": {
+                "through2": "^2.0.3",
+                "vinyl": "^0.4.3"
+            }
+        },
+        "vinyl-sourcemap": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+            "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+            "dev": true,
+            "requires": {
+                "append-buffer": "^1.0.2",
+                "convert-source-map": "^1.5.0",
+                "graceful-fs": "^4.1.6",
+                "normalize-path": "^2.1.1",
+                "now-and-later": "^2.0.0",
+                "remove-bom-buffer": "^3.0.0",
+                "vinyl": "^2.0.0"
+            },
+            "dependencies": {
+                "clone": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+                    "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+                    "dev": true
+                },
+                "clone-stats": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+                    "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+                    "dev": true
+                },
+                "vinyl": {
+                    "version": "2.2.0",
+                    "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+                    "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+                    "dev": true,
+                    "requires": {
+                        "clone": "^2.1.1",
+                        "clone-buffer": "^1.0.0",
+                        "clone-stats": "^1.0.0",
+                        "cloneable-readable": "^1.0.0",
+                        "remove-trailing-separator": "^1.0.1",
+                        "replace-ext": "^1.0.0"
+                    }
+                }
+            }
+        },
+        "vscode": {
+            "version": "1.1.28",
+            "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.28.tgz",
+            "integrity": "sha512-vxpRMKVa/DgSihyy8I7puRZKiwQm9NK/e5oDTEFDtughhEHrspi0UaXKe795b1DFgO3XJe6KLiXzC8mJonvvWw==",
+            "dev": true,
+            "requires": {
+                "glob": "^7.1.2",
+                "gulp-chmod": "^2.0.0",
+                "gulp-filter": "^5.0.1",
+                "gulp-gunzip": "1.0.0",
+                "gulp-remote-src-vscode": "^0.5.1",
+                "gulp-untar": "^0.0.7",
+                "gulp-vinyl-zip": "^2.1.2",
+                "mocha": "^4.0.1",
+                "request": "^2.88.0",
+                "semver": "^5.4.1",
+                "source-map-support": "^0.5.0",
+                "url-parse": "^1.4.3",
+                "vinyl-fs": "^3.0.3",
+                "vinyl-source-stream": "^1.1.0"
+            },
+            "dependencies": {
+                "commander": {
+                    "version": "2.11.0",
+                    "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+                    "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+                    "dev": true
+                },
+                "debug": {
+                    "version": "3.1.0",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+                    "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+                    "dev": true,
+                    "requires": {
+                        "ms": "2.0.0"
+                    }
+                },
+                "diff": {
+                    "version": "3.3.1",
+                    "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
+                    "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
+                    "dev": true
+                },
+                "escape-string-regexp": {
+                    "version": "1.0.5",
+                    "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+                    "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+                    "dev": true
+                },
+                "glob": {
+                    "version": "7.1.3",
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+                    "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+                    "dev": true,
+                    "requires": {
+                        "fs.realpath": "^1.0.0",
+                        "inflight": "^1.0.4",
+                        "inherits": "2",
+                        "minimatch": "^3.0.4",
+                        "once": "^1.3.0",
+                        "path-is-absolute": "^1.0.0"
+                    }
+                },
+                "growl": {
+                    "version": "1.10.3",
+                    "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
+                    "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
+                    "dev": true
+                },
+                "minimatch": {
+                    "version": "3.0.4",
+                    "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+                    "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+                    "dev": true,
+                    "requires": {
+                        "brace-expansion": "^1.1.7"
+                    }
+                },
+                "mocha": {
+                    "version": "4.1.0",
+                    "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
+                    "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
+                    "dev": true,
+                    "requires": {
+                        "browser-stdout": "1.3.0",
+                        "commander": "2.11.0",
+                        "debug": "3.1.0",
+                        "diff": "3.3.1",
+                        "escape-string-regexp": "1.0.5",
+                        "glob": "7.1.2",
+                        "growl": "1.10.3",
+                        "he": "1.1.1",
+                        "mkdirp": "0.5.1",
+                        "supports-color": "4.4.0"
+                    },
+                    "dependencies": {
+                        "glob": {
+                            "version": "7.1.2",
+                            "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+                            "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+                            "dev": true,
+                            "requires": {
+                                "fs.realpath": "^1.0.0",
+                                "inflight": "^1.0.4",
+                                "inherits": "2",
+                                "minimatch": "^3.0.4",
+                                "once": "^1.3.0",
+                                "path-is-absolute": "^1.0.0"
+                            }
+                        }
+                    }
+                },
+                "ms": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+                    "dev": true
+                },
+                "supports-color": {
+                    "version": "4.4.0",
+                    "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+                    "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+                    "dev": true,
+                    "requires": {
+                        "has-flag": "^2.0.0"
+                    }
+                }
+            }
+        },
+        "vscode-jsonrpc": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
+            "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg=="
+        },
+        "vscode-languageclient": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz",
+            "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==",
+            "requires": {
+                "semver": "^5.5.0",
+                "vscode-languageserver-protocol": "3.14.1"
+            }
+        },
+        "vscode-languageserver": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz",
+            "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==",
+            "requires": {
+                "vscode-languageserver-protocol": "3.14.1",
+                "vscode-uri": "^1.0.6"
+            }
+        },
+        "vscode-languageserver-protocol": {
+            "version": "3.14.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
+            "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
+            "requires": {
+                "vscode-jsonrpc": "^4.0.0",
+                "vscode-languageserver-types": "3.14.0"
+            }
+        },
+        "vscode-languageserver-types": {
+            "version": "3.14.0",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
+            "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A=="
+        },
+        "vscode-uri": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz",
+            "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww=="
+        },
+        "wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+            "dev": true
+        },
+        "xtend": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+            "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+            "dev": true
+        },
+        "yauzl": {
+            "version": "2.10.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+            "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+            "dev": true,
+            "requires": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer": "~1.1.0"
+            }
+        },
+        "yazl": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+            "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+            "dev": true,
+            "requires": {
+                "buffer-crc32": "~0.2.3"
+            }
+        }
+    }
+}
diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json
index 89b61ff..b812580 100644
--- a/clangd/clients/clangd-vscode/package.json
+++ b/clangd/clients/clangd-vscode/package.json
@@ -2,11 +2,11 @@
     "name": "vscode-clangd",
     "displayName": "vscode-clangd",
     "description": "Clang Language Server",
-    "version": "0.0.9",
+    "version": "0.0.12",
     "publisher": "llvm-vs-code-extensions",
     "homepage": "https://clang.llvm.org/extra/clangd.html",
     "engines": {
-        "vscode": "^1.27.0"
+        "vscode": "^1.30.0"
     },
     "categories": [
         "Programming Languages",
@@ -21,8 +21,11 @@
         "LLVM"
     ],
     "activationEvents": [
+        "onLanguage:c",
         "onLanguage:cpp",
-        "onLanguage:c"
+        "onLanguage:objective-c",
+        "onLanguage:objective-cpp",
+        "onCommand:clangd-vscode.activate"
     ],
     "main": "./out/src/extension",
     "scripts": {
@@ -32,15 +35,15 @@
         "test": "node ./node_modules/vscode/bin/test"
     },
     "dependencies": {
-        "vscode-languageclient": "^5.1.0",
-        "vscode-languageserver": "^5.1.0"
+        "vscode-languageclient": "^5.2.0",
+        "vscode-languageserver": "^5.2.0"
     },
     "devDependencies": {
-        "typescript": "^2.0.3",
-        "vscode": "^1.1.0",
-        "mocha": "^2.3.3",
+        "@types/mocha": "^2.2.32",
         "@types/node": "^6.0.40",
-        "@types/mocha": "^2.2.32"
+        "mocha": "^5.2.0",
+        "typescript": "^2.0.3",
+        "vscode": "^1.1.0"
     },
     "repository": {
         "type": "svn",
@@ -79,6 +82,10 @@
             {
                 "command": "clangd-vscode.switchheadersource",
                 "title": "Switch between Source/Header"
+            },
+            {
+                "command": "clangd-vscode.activate",
+                "title": "Manually activate clangd extension"
             }
         ],
         "keybindings": [
diff --git a/clangd/clients/clangd-vscode/src/extension.ts b/clangd/clients/clangd-vscode/src/extension.ts
index cad6a3a..2cb97d9 100644
--- a/clangd/clients/clangd-vscode/src/extension.ts
+++ b/clangd/clients/clangd-vscode/src/extension.ts
@@ -40,6 +40,11 @@
         this.statusBarItem.show();
     }
 
+    clear() {
+        this.statuses.clear();
+        this.statusBarItem.hide();
+    }
+
     dispose() {
         this.statusBarItem.dispose();
     }
@@ -63,8 +68,18 @@
     }
     const serverOptions: vscodelc.ServerOptions = clangd;
 
+    // Note that CUDA ('.cu') files are special. When opening files of all other
+    // extensions, VSCode would load clangd automatically. This is achieved by
+    // having a corresponding 'onLanguage:...' activation event in package.json.
+    // However, VSCode does not have CUDA as a supported language yet, so we
+    // cannot add a corresponding activationEvent for CUDA files and clangd will
+    // *not* load itself automatically on '.cu' files. When any of the files
+    // with other extensions are open, clangd will load itself and will also
+    // work on '.cu' files.
     const filePattern: string = '**/*.{' +
-        ['cpp', 'c', 'cc', 'cxx', 'c++', 'm', 'mm', 'h', 'hh', 'hpp', 'hxx', 'inc'].join() + '}';
+        ['cpp', 'c', 'cc', 'cu', 'cxx', 'c++', 'm', 'mm',
+            'h', 'hh', 'hpp', 'hxx', 'inc'].join()
+        + '}';
     const clientOptions: vscodelc.LanguageClientOptions = {
         // Register the server for C/C++ files
         documentSelector: [{ scheme: 'file', pattern: filePattern }],
@@ -87,34 +102,45 @@
         revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never
     };
 
-  const clangdClient = new vscodelc.LanguageClient('Clang Language Server', serverOptions, clientOptions);
-  console.log('Clang Language Server is now active!');
-  context.subscriptions.push(clangdClient.start());
-  context.subscriptions.push(vscode.commands.registerCommand(
-      'clangd-vscode.switchheadersource', async () => {
-        const uri =
-            vscode.Uri.file(vscode.window.activeTextEditor.document.fileName);
-        if (!uri) {
-          return;
-        }
-        const docIdentifier =
-            vscodelc.TextDocumentIdentifier.create(uri.toString());
-        const sourceUri = await clangdClient.sendRequest(
-            SwitchSourceHeaderRequest.type, docIdentifier);
-        if (!sourceUri) {
-          return;
-        }
-        const doc = await vscode.workspace.openTextDocument(
-            vscode.Uri.parse(sourceUri));
-        vscode.window.showTextDocument(doc);
-      }));
+    const clangdClient = new vscodelc.LanguageClient('Clang Language Server',serverOptions, clientOptions);
+    console.log('Clang Language Server is now active!');
+    context.subscriptions.push(clangdClient.start());
+    context.subscriptions.push(vscode.commands.registerCommand(
+        'clangd-vscode.switchheadersource', async () => {
+            const uri =
+                vscode.Uri.file(vscode.window.activeTextEditor.document.fileName);
+            if (!uri) {
+                return;
+            }
+            const docIdentifier =
+                vscodelc.TextDocumentIdentifier.create(uri.toString());
+            const sourceUri = await clangdClient.sendRequest(
+                SwitchSourceHeaderRequest.type, docIdentifier);
+            if (!sourceUri) {
+                return;
+            }
+            const doc = await vscode.workspace.openTextDocument(
+                vscode.Uri.parse(sourceUri));
+            vscode.window.showTextDocument(doc);
+        }));
     const status = new FileStatus();
     context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(() => {
         status.updateStatus();
     }));
-    clangdClient.onReady().then(() => {
-        clangdClient.onNotification(
-            'textDocument/clangd.fileStatus',
-            (fileStatus) => { status.onFileUpdated(fileStatus); });
-    })
+    clangdClient.onDidChangeState(
+        ({ newState }) => {
+            if (newState == vscodelc.State.Running) {
+                // clangd starts or restarts after crash.
+                clangdClient.onNotification(
+                    'textDocument/clangd.fileStatus',
+                    (fileStatus) => { status.onFileUpdated(fileStatus); });
+            } else if (newState == vscodelc.State.Stopped) {
+                // Clear all cached statuses when clangd crashes.
+                status.clear();
+            }
+        })
+    // An empty place holder for the activate command, otherwise we'll get an
+    // "command is not registered" error.
+    context.subscriptions.push(vscode.commands.registerCommand(
+            'clangd-vscode.activate', async () => {}));
 }
diff --git a/clangd/fuzzer/CMakeLists.txt b/clangd/fuzzer/CMakeLists.txt
index ca76c97..28191a3 100644
--- a/clangd/fuzzer/CMakeLists.txt
+++ b/clangd/fuzzer/CMakeLists.txt
@@ -1,14 +1,15 @@
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..
+  ${CMAKE_CURRENT_BINARY_DIR}/..)
 
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS
+  FuzzMutate
+  Support
+  )
 
-if(LLVM_USE_SANITIZE_COVERAGE)
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
-endif()
-
-add_clang_executable(clangd-fuzzer
-  EXCLUDE_FROM_ALL
-  ClangdFuzzer.cpp
+# This fuzzer runs on oss-fuzz, so keep it around even if it looks unreferenced.
+add_llvm_fuzzer(clangd-fuzzer
+  clangd-fuzzer.cpp
+  DUMMY_MAIN DummyClangdMain.cpp
   )
 
 target_link_libraries(clangd-fuzzer
@@ -20,5 +21,4 @@
   clangSema
   clangTooling
   clangToolingCore
-  ${LLVM_LIB_FUZZING_ENGINE}
   )
diff --git a/clangd/fuzzer/DummyClangdMain.cpp b/clangd/fuzzer/DummyClangdMain.cpp
new file mode 100644
index 0000000..cd5a612
--- /dev/null
+++ b/clangd/fuzzer/DummyClangdMain.cpp
@@ -0,0 +1,18 @@
+//===---- DummyClangdMain.cpp - Entry point to sanity check the fuzzer ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of main so we can build and test without linking libFuzzer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/FuzzMutate/FuzzerCLI.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+int main(int argc, char *argv[]) {
+  return llvm::runFuzzerOnInputs(argc, argv, LLVMFuzzerTestOneInput);
+}
diff --git a/clangd/fuzzer/ClangdFuzzer.cpp b/clangd/fuzzer/clangd-fuzzer.cpp
similarity index 70%
rename from clangd/fuzzer/ClangdFuzzer.cpp
rename to clangd/fuzzer/clangd-fuzzer.cpp
index 7afd079..5e7de77 100644
--- a/clangd/fuzzer/ClangdFuzzer.cpp
+++ b/clangd/fuzzer/clangd-fuzzer.cpp
@@ -1,9 +1,8 @@
 //===-- ClangdFuzzer.cpp - Fuzz clangd ------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -16,6 +15,7 @@
 #include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "CodeComplete.h"
+#include "FSProvider.h"
 #include <cstdio>
 #include <sstream>
 
@@ -29,13 +29,15 @@
   std::FILE *In = fmemopen(data, size, "r");
   auto Transport = newJSONTransport(In, llvm::nulls(),
                                     /*InMirror=*/nullptr, /*Pretty=*/false,
-                                    /*Style=*/JSONStreamStyle::Standard);
+                                    /*Style=*/JSONStreamStyle::Delimited);
+  RealFileSystemProvider FS;
   CodeCompleteOptions CCOpts;
   CCOpts.EnableSnippets = false;
   ClangdServer::Options Opts;
 
   // Initialize and run ClangdLSPServer.
-  ClangdLSPServer LSPServer(*Transport, CCOpts, llvm::None, false, Opts);
+  ClangdLSPServer LSPServer(*Transport, FS, CCOpts, llvm::None, false,
+                            llvm::None, Opts);
   LSPServer.run();
   return 0;
 }
diff --git a/clangd/include-mapping/gen_std.py b/clangd/include-mapping/gen_std.py
new file mode 100755
index 0000000..bfa6d0d
--- /dev/null
+++ b/clangd/include-mapping/gen_std.py
@@ -0,0 +1,252 @@
+#!/usr/bin/env python
+#===- gen_std.py -  ------------------------------------------*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===------------------------------------------------------------------------===#
+
+"""gen_std.py is a tool to generate a lookup table (from qualified names to
+include headers) for C++ Standard Library symbols by parsing archieved HTML
+files from cppreference.
+
+Caveats and FIXMEs:
+  - only symbols directly in "std" namespace are added, we should also add std's
+    subnamespace symbols (e.g. chrono).
+  - symbols with multiple variants or defined in multiple headers aren't added,
+    e.g. std::move, std::swap
+
+Usage:
+  1. Install BeautifulSoup dependency, see instruction:
+       https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup
+  2. Download cppreference offline HTML files (e.g. html_book_20181028.zip) at
+       https://en.cppreference.com/w/Cppreference:Archives
+  3. Unzip the zip file from step 2 to directory </cppreference>, you should
+     get a "reference" directory in </cppreference>
+  4. Run the command:
+       gen_std.py -cppreference </cppreference/reference> > StdSymbolMap.inc
+"""
+
+from bs4 import BeautifulSoup, NavigableString
+
+import argparse
+import collections
+import datetime
+import multiprocessing
+import os
+import re
+import signal
+import sys
+
+STDGEN_CODE_PREFIX = """\
+//===-- gen_std.py generated file -------------------------------*- C++ -*-===//
+//
+// Used to build a lookup table (qualified names => include headers) for C++
+// Standard Library symbols.
+//
+// Automatically generated file, DO NOT EDIT!
+//
+// Generated from cppreference offline HTML book (modified on %s).
+//===----------------------------------------------------------------------===//
+"""
+
+def HasClass(tag, *classes):
+  for c in tag.get('class', []):
+    if c in classes:
+      return True
+  return False
+
+def ParseSymbolPage(symbol_page_html, symbol_name):
+  """Parse symbol page and retrieve the include header defined in this page.
+  The symbol page provides header for the symbol, specifically in
+  "Defined in header <header>" section. An example:
+
+  <tr class="t-dsc-header">
+    <td colspan="2"> <div>Defined in header <code>&lt;ratio&gt;</code> </div>
+  </td></tr>
+
+  Returns a list of headers.
+  """
+  headers = set()
+  all_headers = set()
+
+  soup = BeautifulSoup(symbol_page_html, "html.parser")
+  # Rows in table are like:
+  #   Defined in header <foo>      .t-dsc-header
+  #   Defined in header <bar>      .t-dsc-header
+  #   decl1                        .t-dcl
+  #   Defined in header <baz>      .t-dsc-header
+  #   decl2                        .t-dcl
+  for table in soup.select('table.t-dcl-begin, table.t-dsc-begin'):
+    current_headers = []
+    was_decl = False
+    for row in table.select('tr'):
+      if HasClass(row, 't-dcl', 't-dsc'):
+        was_decl = True
+        # Declaration is in the first cell.
+        text = row.find('td').text
+        # Decl may not be for the symbol name we're looking for.
+        if not re.search("\\b%s\\b" % symbol_name, text):
+          continue
+        headers.update(current_headers)
+      elif HasClass(row, 't-dsc-header'):
+        # If we saw a decl since the last header, this is a new block of headers
+        # for a new block of decls.
+        if was_decl:
+          current_headers = []
+        was_decl = False
+        # There are also .t-dsc-header for "defined in namespace".
+        if not "Defined in header " in row.text:
+          continue
+        # The interesting header content (e.g. <cstdlib>) is wrapped in <code>.
+        for header_code in row.find_all("code"):
+          current_headers.append(header_code.text)
+          all_headers.add(header_code.text)
+  # If the symbol was never named, consider all named headers.
+  return headers or all_headers
+
+
+def ParseIndexPage(index_page_html):
+  """Parse index page.
+  The index page lists all std symbols and hrefs to their detailed pages
+  (which contain the defined header). An example:
+
+  <a href="abs.html" title="abs"><tt>abs()</tt></a> (int) <br>
+  <a href="acos.html" title="acos"><tt>acos()</tt></a> <br>
+
+  Returns a list of tuple (symbol_name, relative_path_to_symbol_page, variant).
+  """
+  symbols = []
+  soup = BeautifulSoup(index_page_html, "html.parser")
+  for symbol_href in soup.select("a[title]"):
+    # Ignore annotated symbols like "acos<>() (std::complex)".
+    # These tend to be overloads, and we the primary is more useful.
+    # This accidentally accepts begin/end despite the (iterator) caption: the
+    # (since C++11) note is first. They are good symbols, so the bug is unfixed.
+    caption = symbol_href.next_sibling
+    variant = isinstance(caption, NavigableString) and "(" in caption
+    symbol_tt = symbol_href.find("tt")
+    if symbol_tt:
+      symbols.append((symbol_tt.text.rstrip("<>()"), # strip any trailing <>()
+                      symbol_href["href"], variant))
+  return symbols
+
+class Symbol:
+
+  def __init__(self, name, namespace, headers):
+    # unqualifed symbol name, e.g. "move"
+    self.name = name
+    # namespace of the symbol (with trailing "::"), e.g. "std::"
+    self.namespace = namespace
+    # a list of corresponding headers
+    self.headers = headers
+
+
+def ReadSymbolPage(path, name):
+  with open(path) as f:
+    return ParseSymbolPage(f.read(), name)
+
+
+def GetSymbols(pool, root_dir, index_page_name, namespace):
+  """Get all symbols listed in the index page. All symbols should be in the
+  given namespace.
+
+  Returns a list of Symbols.
+  """
+
+  # Workflow steps:
+  #   1. Parse index page which lists all symbols to get symbol
+  #      name (unqualified name) and its href link to the symbol page which
+  #      contains the defined header.
+  #   2. Parse the symbol page to get the defined header.
+  index_page_path = os.path.join(root_dir, index_page_name)
+  with open(index_page_path, "r") as f:
+    # Read each symbol page in parallel.
+    results = [] # (symbol_name, promise of [header...])
+    for symbol_name, symbol_page_path, variant in ParseIndexPage(f.read()):
+      # Variant symbols (e.g. the std::locale version of isalpha) add ambiguity.
+      # FIXME: use these as a fallback rather than ignoring entirely.
+      if variant:
+        continue
+      path = os.path.join(root_dir, symbol_page_path)
+      results.append((symbol_name,
+                      pool.apply_async(ReadSymbolPage, (path, symbol_name))))
+
+    # Build map from symbol name to a set of headers.
+    symbol_headers = collections.defaultdict(set)
+    for symbol_name, lazy_headers in results:
+      symbol_headers[symbol_name].update(lazy_headers.get())
+
+  symbols = []
+  for name, headers in sorted(symbol_headers.items(), key=lambda t : t[0]):
+    symbols.append(Symbol(name, namespace, list(headers)))
+  return symbols
+
+
+def ParseArg():
+  parser = argparse.ArgumentParser(description='Generate StdGen file')
+  parser.add_argument('-cppreference', metavar='PATH',
+                      default='',
+                      help='path to the cppreference offline HTML directory',
+                      required=True
+                      )
+  return parser.parse_args()
+
+
+def main():
+  args = ParseArg()
+  cpp_root = os.path.join(args.cppreference, "en", "cpp")
+  symbol_index_root = os.path.join(cpp_root, "symbol_index")
+  if not os.path.exists(symbol_index_root):
+    exit("Path %s doesn't exist!" % symbol_index_root)
+
+  parse_pages =  [
+    (cpp_root, "symbol_index.html", "std::"),
+    # std sub-namespace symbols have separated pages.
+    # We don't index std literal operators (e.g.
+    # std::literals::chrono_literals::operator""d), these symbols can't be
+    # accessed by std::<symbol_name>.
+    # FIXME: index std::placeholders symbols, placeholders.html page is
+    # different (which contains one entry for _1, _2, ..., _N), we need special
+    # handling.
+    (symbol_index_root, "chrono.html", "std::chrono::"),
+    (symbol_index_root, "filesystem.html", "std::filesystem::"),
+    (symbol_index_root, "pmr.html", "std::pmr::"),
+    (symbol_index_root, "regex_constants.html", "std::regex_constants::"),
+    (symbol_index_root, "this_thread.html", "std::this_thread::"),
+  ]
+
+  symbols = []
+  # Run many workers to process individual symbol pages under the symbol index.
+  # Don't allow workers to capture Ctrl-C.
+  pool = multiprocessing.Pool(
+      initializer=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))
+  try:
+    for root_dir, page_name, namespace in parse_pages:
+      symbols.extend(GetSymbols(pool, root_dir, page_name, namespace))
+  finally:
+    pool.terminate()
+    pool.join()
+
+  # We don't have version information from the unzipped offline HTML files.
+  # so we use the modified time of the symbol_index.html as the version.
+  index_page_path = os.path.join(cpp_root, "symbol_index.html")
+  cppreference_modified_date = datetime.datetime.fromtimestamp(
+    os.stat(index_page_path).st_mtime).strftime('%Y-%m-%d')
+  print STDGEN_CODE_PREFIX % cppreference_modified_date
+  for symbol in symbols:
+    if len(symbol.headers) == 1:
+      # SYMBOL(unqualified_name, namespace, header)
+      print "SYMBOL(%s, %s, %s)" % (symbol.name, symbol.namespace,
+                                    symbol.headers[0])
+    elif len(symbol.headers) == 0:
+      sys.stderr.write("No header found for symbol %s\n" % symbol.name)
+    else:
+      # FIXME: support symbols with multiple headers (e.g. std::move).
+      sys.stderr.write("Ambiguous header for symbol %s: %s\n" % (
+          symbol.name, ', '.join(symbol.headers)))
+
+
+if __name__ == '__main__':
+  main()
diff --git a/clangd/include-mapping/test.py b/clangd/include-mapping/test.py
new file mode 100755
index 0000000..1072576
--- /dev/null
+++ b/clangd/include-mapping/test.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#===- test.py -  ---------------------------------------------*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===------------------------------------------------------------------------===#
+
+from gen_std import ParseSymbolPage, ParseIndexPage
+
+import unittest
+
+class TestStdGen(unittest.TestCase):
+
+  def testParseIndexPage(self):
+    html = """
+ <a href="abs.html" title="abs"><tt>abs()</tt></a> (int) <br>
+ <a href="complex/abs.html" title="abs"><tt>abs&lt;&gt;()</tt></a> (std::complex) <br>
+ <a href="acos.html" title="acos"><tt>acos()</tt></a> <br>
+ <a href="acosh.html" title="acosh"><tt>acosh()</tt></a> <span class="t-mark-rev">(since C++11)</span> <br>
+ <a href="as_bytes.html" title="as bytes"><tt>as_bytes&lt;&gt;()</tt></a> <span class="t-mark-rev t-since-cxx20">(since C++20)</span> <br>
+ """
+
+    actual = ParseIndexPage(html)
+    expected = [
+      ("abs", "abs.html", True),
+      ("abs", "complex/abs.html", True),
+      ("acos", "acos.html", False),
+      ("acosh", "acosh.html", False),
+      ("as_bytes", "as_bytes.html", False),
+    ]
+    self.assertEqual(len(actual), len(expected))
+    for i in range(0, len(actual)):
+      self.assertEqual(expected[i][0], actual[i][0])
+      self.assertTrue(actual[i][1].endswith(expected[i][1]))
+      self.assertEqual(expected[i][2], actual[i][2])
+
+
+  def testParseSymbolPage_SingleHeader(self):
+    # Defined in header <cmath>
+    html = """
+ <table class="t-dcl-begin"><tbody>
+  <tr class="t-dsc-header">
+  <td> <div>Defined in header <code><a href="cmath.html" title="cmath">&lt;cmath&gt;</a></code>
+   </div></td>
+  <td></td>
+  <td></td>
+  </tr>
+  <tr class="t-dcl">
+    <td>void foo()</td>
+    <td>this is matched</td>
+  </tr>
+</tbody></table>
+"""
+    self.assertEqual(ParseSymbolPage(html, 'foo'), set(['<cmath>']))
+
+
+  def testParseSymbolPage_MulHeaders(self):
+    #  Defined in header <cstddef>
+    #  Defined in header <cstdio>
+    #  Defined in header <cstdlib>
+    html = """
+<table class="t-dcl-begin"><tbody>
+  <tr class="t-dsc-header">
+    <td> <div>Defined in header <code><a href="cstddef.html" title="cstddef">&lt;cstddef&gt;</a></code>
+     </div></td>
+     <td></td>
+    <td></td>
+  </tr>
+  <tr class="t-dcl">
+    <td>void bar()</td>
+    <td>this mentions foo, but isn't matched</td>
+  </tr>
+  <tr class="t-dsc-header">
+    <td> <div>Defined in header <code><a href="cstdio.html" title="cstdio">&lt;cstdio&gt;</a></code>
+     </div></td>
+    <td></td>
+    <td></td>
+  </tr>
+  <tr class="t-dsc-header">
+    <td> <div>Defined in header <code><a href=".cstdlib.html" title="ccstdlib">&lt;cstdlib&gt;</a></code>
+     </div></td>
+    <td></td>
+    <td></td>
+  </tr>
+  <tr class="t-dcl">
+    <td>void foo()</td>
+    <td>this is matched</td>
+  </tr>
+</tbody></table>
+"""
+    self.assertEqual(ParseSymbolPage(html, "foo"),
+                     set(['<cstdio>', '<cstdlib>']))
+
+
+  def testParseSymbolPage_MulHeadersInSameDiv(self):
+    # Multile <code> blocks in a Div.
+    # Defined in header <algorithm>
+    # Defined in header <utility>
+    html = """
+<table class="t-dcl-begin"><tbody>
+<tr class="t-dsc-header">
+<td><div>
+     Defined in header <code><a href="../header/algorithm.html" title="cpp/header/algorithm">&lt;algorithm&gt;</a></code><br>
+     Defined in header <code><a href="../header/utility.html" title="cpp/header/utility">&lt;utility&gt;</a></code>
+</div></td>
+<td></td>
+</tr>
+<tr class="t-dcl">
+  <td>void foo()</td>
+  <td>this is matched</td>
+</tr>
+</tbody></table>
+"""
+    self.assertEqual(ParseSymbolPage(html, "foo"),
+                     set(['<algorithm>', '<utility>']))
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp
index b9b945c..0746a35 100644
--- a/clangd/index/Background.cpp
+++ b/clangd/index/Background.cpp
@@ -1,9 +1,8 @@
 //===-- Background.cpp - Build an index in a background thread ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 #include "Compiler.h"
 #include "Logger.h"
 #include "SourceCode.h"
+#include "Symbol.h"
 #include "Threading.h"
 #include "Trace.h"
 #include "URI.h"
@@ -26,7 +26,9 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/SHA1.h"
+#include "llvm/Support/Threading.h"
 
+#include <atomic>
 #include <chrono>
 #include <memory>
 #include <numeric>
@@ -38,6 +40,9 @@
 namespace clang {
 namespace clangd {
 namespace {
+
+static std::atomic<bool> PreventStarvation = {false};
+
 // Resolves URI to file paths with cache.
 class URIToFileCache {
 public:
@@ -121,19 +126,19 @@
   } else {
     AbsolutePath = Cmd.Directory;
     llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+    llvm::sys::path::remove_dots(AbsolutePath, true);
   }
   return AbsolutePath;
 }
 } // namespace
 
 BackgroundIndex::BackgroundIndex(
-    Context BackgroundContext, llvm::StringRef ResourceDir,
-    const FileSystemProvider &FSProvider, const GlobalCompilationDatabase &CDB,
+    Context BackgroundContext, const FileSystemProvider &FSProvider,
+    const GlobalCompilationDatabase &CDB,
     BackgroundIndexStorage::Factory IndexStorageFactory,
     size_t BuildIndexPeriodMs, size_t ThreadPoolSize)
-    : SwapIndex(llvm::make_unique<MemIndex>()), ResourceDir(ResourceDir),
-      FSProvider(FSProvider), CDB(CDB),
-      BackgroundContext(std::move(BackgroundContext)),
+    : SwapIndex(llvm::make_unique<MemIndex>()), FSProvider(FSProvider),
+      CDB(CDB), BackgroundContext(std::move(BackgroundContext)),
       BuildIndexPeriodMs(BuildIndexPeriodMs),
       SymbolsUpdatedSinceLastIndex(false),
       IndexStorageFactory(std::move(IndexStorageFactory)),
@@ -172,7 +177,7 @@
   WithContext Background(BackgroundContext.clone());
   while (true) {
     llvm::Optional<Task> Task;
-    ThreadPriority Priority;
+    llvm::ThreadPriority Priority;
     {
       std::unique_lock<std::mutex> Lock(QueueMu);
       QueueCV.wait(Lock, [&] { return ShouldStop || !Queue.empty(); });
@@ -186,11 +191,11 @@
       Queue.pop_front();
     }
 
-    if (Priority != ThreadPriority::Normal)
-      setCurrentThreadPriority(Priority);
+    if (Priority != llvm::ThreadPriority::Default && !PreventStarvation.load())
+      llvm::set_thread_priority(Priority);
     (*Task)();
-    if (Priority != ThreadPriority::Normal)
-      setCurrentThreadPriority(ThreadPriority::Normal);
+    if (Priority != llvm::ThreadPriority::Default)
+      llvm::set_thread_priority(llvm::ThreadPriority::Default);
 
     {
       std::unique_lock<std::mutex> Lock(QueueMu);
@@ -223,14 +228,13 @@
         for (auto &Elem : NeedsReIndexing)
           enqueue(std::move(Elem.first), Elem.second);
       },
-      ThreadPriority::Normal);
+      llvm::ThreadPriority::Default);
 }
 
 void BackgroundIndex::enqueue(tooling::CompileCommand Cmd,
                               BackgroundIndexStorage *Storage) {
   enqueueTask(Bind(
                   [this, Storage](tooling::CompileCommand Cmd) {
-                    Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);
                     // We can't use llvm::StringRef here since we are going to
                     // move from Cmd during the call below.
                     const std::string FileName = Cmd.Filename;
@@ -239,10 +243,10 @@
                            std::move(Error));
                   },
                   std::move(Cmd)),
-              ThreadPriority::Low);
+              llvm::ThreadPriority::Background);
 }
 
-void BackgroundIndex::enqueueTask(Task T, ThreadPriority Priority) {
+void BackgroundIndex::enqueueTask(Task T, llvm::ThreadPriority Priority) {
   {
     std::lock_guard<std::mutex> Lock(QueueMu);
     auto I = Queue.end();
@@ -250,10 +254,11 @@
     // Then we store low priority tasks. Normal priority tasks are pretty rare,
     // they should not grow beyond single-digit numbers, so it is OK to do
     // linear search and insert after that.
-    if (Priority == ThreadPriority::Normal) {
-      I = llvm::find_if(Queue, [](const std::pair<Task, ThreadPriority> &Elem) {
-        return Elem.second == ThreadPriority::Low;
-      });
+    if (Priority == llvm::ThreadPriority::Default) {
+      I = llvm::find_if(
+          Queue, [](const std::pair<Task, llvm::ThreadPriority> &Elem) {
+            return Elem.second == llvm::ThreadPriority::Background;
+          });
     }
     Queue.insert(I, {std::move(T), Priority});
   }
@@ -375,7 +380,9 @@
     // extra index build.
     reset(
         IndexedSymbols.buildIndex(IndexType::Heavy, DuplicateHandling::Merge));
-    log("BackgroundIndex: rebuilt symbol index.");
+    log("BackgroundIndex: rebuilt symbol index with estimated memory {0} "
+        "bytes.",
+        estimateMemoryUsage());
   }
 }
 
@@ -398,7 +405,7 @@
     DigestsSnapshot = IndexedFileDigests;
   }
 
-  log("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
+  vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
   ParseInputs Inputs;
   Inputs.FS = std::move(FS);
   Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory);
@@ -408,9 +415,8 @@
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "Couldn't build compiler invocation");
   IgnoreDiagnostics IgnoreDiags;
-  auto Clang = prepareCompilerInstance(
-      std::move(CI), /*Preamble=*/nullptr, std::move(*Buf),
-      std::make_shared<PCHContainerOperations>(), Inputs.FS, IgnoreDiags);
+  auto Clang = prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr,
+                                       std::move(*Buf), Inputs.FS, IgnoreDiags);
   if (!Clang)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "Couldn't build compiler instance");
@@ -604,10 +610,16 @@
     }
   }
   vlog("Loaded all shards");
-  reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge));
-
+  reset(IndexedSymbols.buildIndex(IndexType::Heavy, DuplicateHandling::Merge));
+  vlog("BackgroundIndex: built symbol index with estimated memory {0} "
+       "bytes.",
+       estimateMemoryUsage());
   return NeedsReIndexing;
 }
 
+void BackgroundIndex::preventThreadStarvationInTests() {
+  PreventStarvation.store(true);
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/index/Background.h b/clangd/index/Background.h
index 1a1fee6..2132e57 100644
--- a/clangd/index/Background.h
+++ b/clangd/index/Background.h
@@ -1,9 +1,8 @@
 //===--- Background.h - Build an index in a background thread ----*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -55,7 +54,7 @@
       llvm::unique_function<BackgroundIndexStorage *(llvm::StringRef)>;
 
   // Creates an Index Storage that saves shards into disk. Index storage uses
-  // CDBDirectory + ".clangd-index/" as the folder to save shards.
+  // CDBDirectory + ".clangd/index/" as the folder to save shards.
   static Factory createDiskBackedStorageFactory();
 };
 
@@ -68,13 +67,12 @@
   /// If BuildIndexPeriodMs is greater than 0, the symbol index will only be
   /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is
   /// rebuilt for each indexed file.
-  // FIXME: resource-dir injection should be hoisted somewhere common.
-  BackgroundIndex(Context BackgroundContext, llvm::StringRef ResourceDir,
-                  const FileSystemProvider &,
-                  const GlobalCompilationDatabase &CDB,
-                  BackgroundIndexStorage::Factory IndexStorageFactory,
-                  size_t BuildIndexPeriodMs = 0,
-                  size_t ThreadPoolSize = llvm::hardware_concurrency());
+  BackgroundIndex(
+      Context BackgroundContext, const FileSystemProvider &,
+      const GlobalCompilationDatabase &CDB,
+      BackgroundIndexStorage::Factory IndexStorageFactory,
+      size_t BuildIndexPeriodMs = 0,
+      size_t ThreadPoolSize = llvm::heavyweight_hardware_concurrency());
   ~BackgroundIndex(); // Blocks while the current task finishes.
 
   // Enqueue translation units for indexing.
@@ -90,6 +88,10 @@
   LLVM_NODISCARD bool
   blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
 
+  // Disables thread priority lowering in background index to make sure it can
+  // progress on loaded systems. Only affects tasks that run after the call.
+  static void preventThreadStarvationInTests();
+
 private:
   /// Given index results from a TU, only update symbols coming from files with
   /// different digests than \p DigestsSnapshot. Also stores new index
@@ -99,7 +101,6 @@
               BackgroundIndexStorage *IndexStorage);
 
   // configuration
-  std::string ResourceDir;
   const FileSystemProvider &FSProvider;
   const GlobalCompilationDatabase &CDB;
   Context BackgroundContext;
@@ -137,14 +138,14 @@
   // queue management
   using Task = std::function<void()>;
   void run(); // Main loop executed by Thread. Runs tasks from Queue.
-  void enqueueTask(Task T, ThreadPriority Prioirty);
+  void enqueueTask(Task T, llvm::ThreadPriority Prioirty);
   void enqueueLocked(tooling::CompileCommand Cmd,
                      BackgroundIndexStorage *IndexStorage);
   std::mutex QueueMu;
   unsigned NumActiveTasks = 0; // Only idle when queue is empty *and* no tasks.
   std::condition_variable QueueCV;
   bool ShouldStop = false;
-  std::deque<std::pair<Task, ThreadPriority>> Queue;
+  std::deque<std::pair<Task, llvm::ThreadPriority>> Queue;
   std::vector<std::thread> ThreadPool; // FIXME: Abstract this away.
   GlobalCompilationDatabase::CommandChanged::Subscription CommandsChanged;
 };
diff --git a/clangd/index/BackgroundIndexStorage.cpp b/clangd/index/BackgroundIndexStorage.cpp
index a83bec6..42db1dc 100644
--- a/clangd/index/BackgroundIndexStorage.cpp
+++ b/clangd/index/BackgroundIndexStorage.cpp
@@ -1,9 +1,8 @@
 //== BackgroundIndexStorage.cpp - Provide caching support to BackgroundIndex ==/
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -64,19 +63,19 @@
 }
 
 // Uses disk as a storage for index shards. Creates a directory called
-// ".clangd-index/" under the path provided during construction.
+// ".clangd/index/" under the path provided during construction.
 class DiskBackedIndexStorage : public BackgroundIndexStorage {
   std::string DiskShardRoot;
 
 public:
-  // Sets DiskShardRoot to (Directory + ".clangd-index/") which is the base
+  // Sets DiskShardRoot to (Directory + ".clangd/index/") which is the base
   // directory for all shard files.
   DiskBackedIndexStorage(llvm::StringRef Directory) {
     llvm::SmallString<128> CDBDirectory(Directory);
-    llvm::sys::path::append(CDBDirectory, ".clangd-index/");
+    llvm::sys::path::append(CDBDirectory, ".clangd", "index");
     DiskShardRoot = CDBDirectory.str();
     std::error_code OK;
-    std::error_code EC = llvm::sys::fs::create_directory(DiskShardRoot);
+    std::error_code EC = llvm::sys::fs::create_directories(DiskShardRoot);
     if (EC != OK) {
       elog("Failed to create directory {0} for index storage: {1}",
            DiskShardRoot, EC.message());
@@ -138,9 +137,6 @@
     return IndexStorage.get();
   }
 
-  // Creates or fetches to storage from cache for the specified CDB.
-  BackgroundIndexStorage *createStorage(llvm::StringRef CDBDirectory);
-
 private:
   std::unique_ptr<BackgroundIndexStorage> create(llvm::StringRef CDBDirectory) {
     if (CDBDirectory.empty())
diff --git a/clangd/index/CanonicalIncludes.cpp b/clangd/index/CanonicalIncludes.cpp
index 7351b86..25bbffb 100644
--- a/clangd/index/CanonicalIncludes.cpp
+++ b/clangd/index/CanonicalIncludes.cpp
@@ -1,9 +1,8 @@
 //===-- CanonicalIncludes.h - remap #inclue headers--------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,31 +37,12 @@
 }
 
 llvm::StringRef
-CanonicalIncludes::mapHeader(llvm::ArrayRef<std::string> Headers,
+CanonicalIncludes::mapHeader(llvm::StringRef Header,
                              llvm::StringRef QualifiedName) const {
-  assert(!Headers.empty());
+  assert(!Header.empty());
   auto SE = SymbolMapping.find(QualifiedName);
   if (SE != SymbolMapping.end())
     return SE->second;
-  // Find the first header such that the extension is not '.inc', and isn't a
-  // recognized non-header file
-  auto I = llvm::find_if(Headers, [](llvm::StringRef Include) {
-    // Skip .inc file whose including header file should
-    // be #included instead.
-    return !Include.endswith(".inc");
-  });
-  if (I == Headers.end())
-    return Headers[0]; // Fallback to the declaring header.
-  llvm::StringRef Header = *I;
-  // If Header is not expected be included (e.g. .cc file), we fall back to
-  // the declaring header.
-  llvm::StringRef Ext = llvm::sys::path::extension(Header).trim('.');
-  // Include-able headers must have precompile type. Treat files with
-  // non-recognized extenstions (TY_INVALID) as headers.
-  auto ExtType = driver::types::lookupTypeForExtension(Ext);
-  if ((ExtType != driver::types::TY_INVALID) &&
-      !driver::types::onlyPrecompileType(ExtType))
-    return Headers[0];
 
   auto MapIt = FullPathMapping.find(Header);
   if (MapIt != FullPathMapping.end())
@@ -108,57 +88,30 @@
 
 void addSystemHeadersMapping(CanonicalIncludes *Includes) {
   static const std::vector<std::pair<const char *, const char *>> SymbolMap = {
-      {"std::addressof", "<memory>"},
       // Map symbols in <iosfwd> to their preferred includes.
       {"std::basic_filebuf", "<fstream>"},
-      {"std::basic_fstream", "<fstream>"},
-      {"std::basic_ifstream", "<fstream>"},
-      {"std::basic_ofstream", "<fstream>"},
       {"std::filebuf", "<fstream>"},
-      {"std::fstream", "<fstream>"},
-      {"std::ifstream", "<fstream>"},
-      {"std::ofstream", "<fstream>"},
       {"std::wfilebuf", "<fstream>"},
-      {"std::wfstream", "<fstream>"},
-      {"std::wifstream", "<fstream>"},
-      {"std::wofstream", "<fstream>"},
-      {"std::basic_ios", "<ios>"},
-      {"std::ios", "<ios>"},
-      {"std::wios", "<ios>"},
-      {"std::basic_iostream", "<iostream>"},
-      {"std::iostream", "<iostream>"},
-      {"std::wiostream", "<iostream>"},
       {"std::basic_istream", "<istream>"},
       {"std::istream", "<istream>"},
       {"std::wistream", "<istream>"},
-      {"std::istreambuf_iterator", "<iterator>"},
-      {"std::ostreambuf_iterator", "<iterator>"},
       {"std::basic_ostream", "<ostream>"},
       {"std::ostream", "<ostream>"},
       {"std::wostream", "<ostream>"},
-      {"std::basic_istringstream", "<sstream>"},
-      {"std::basic_ostringstream", "<sstream>"},
-      {"std::basic_stringbuf", "<sstream>"},
-      {"std::basic_stringstream", "<sstream>"},
-      {"std::istringstream", "<sstream>"},
-      {"std::ostringstream", "<sstream>"},
-      {"std::string", "<string>"},
-      {"std::stringbuf", "<sstream>"},
-      {"std::stringstream", "<sstream>"},
-      {"std::wistringstream", "<sstream>"},
-      {"std::wostringstream", "<sstream>"},
-      {"std::wstringbuf", "<sstream>"},
-      {"std::wstringstream", "<sstream>"},
-      {"std::basic_streambuf", "<streambuf>"},
-      {"std::streambuf", "<streambuf>"},
-      {"std::wstreambuf", "<streambuf>"},
       {"std::uint_least16_t", "<cstdint>"}, // <type_traits> redeclares these
       {"std::uint_least32_t", "<cstdint>"},
-      {"std::declval", "<utility>"},
+#define SYMBOL(Name, NameSpace, Header) { #NameSpace#Name, #Header },
+      #include "StdSymbolMap.inc"
+#undef SYMBOL
   };
   for (const auto &Pair : SymbolMap)
     Includes->addSymbolMapping(Pair.first, Pair.second);
 
+  // FIXME: remove the std header mapping once we support ambiguous symbols, now
+  // it serves as a fallback to disambiguate:
+  //   - symbols with mulitiple headers (e.g. std::move)
+  //   - symbols with a primary template in one header and a specialization in
+  //     another (std::abs)
   static const std::vector<std::pair<const char *, const char *>>
       SystemHeaderMap = {
           {"include/__stddef_max_align_t.h", "<cstddef>"},
diff --git a/clangd/index/CanonicalIncludes.h b/clangd/index/CanonicalIncludes.h
index 3751b00..f85b76b 100644
--- a/clangd/index/CanonicalIncludes.h
+++ b/clangd/index/CanonicalIncludes.h
@@ -1,9 +1,8 @@
 //===-- CanonicalIncludes.h - remap #include header -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -51,9 +50,9 @@
                         llvm::StringRef CanonicalPath);
 
   /// Returns the canonical include for symbol with \p QualifiedName.
-  /// \p Headers is the include stack: Headers.front() is the file declaring the
-  /// symbol, and Headers.back() is the main file.
-  llvm::StringRef mapHeader(llvm::ArrayRef<std::string> Headers,
+  /// \p Header is the file the declaration was reachable from.
+  /// Header itself will be returned if there is no relevant mapping.
+  llvm::StringRef mapHeader(llvm::StringRef Header,
                             llvm::StringRef QualifiedName) const;
 
 private:
diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp
index d3e3596..7eca85e 100644
--- a/clangd/index/FileIndex.cpp
+++ b/clangd/index/FileIndex.cpp
@@ -1,9 +1,8 @@
 //===--- FileIndex.cpp - Indexes for files. ------------------------ C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,9 +10,11 @@
 #include "ClangdUnit.h"
 #include "Logger.h"
 #include "SymbolCollector.h"
+#include "index/CanonicalIncludes.h"
 #include "index/Index.h"
 #include "index/MemIndex.h"
 #include "index/Merge.h"
+#include "index/SymbolOrigin.h"
 #include "index/dex/Dex.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Lex/MacroInfo.h"
@@ -29,14 +30,11 @@
 
 static std::pair<SymbolSlab, RefSlab>
 indexSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
-             llvm::ArrayRef<Decl *> DeclsToIndex, bool IsIndexMainAST) {
+             llvm::ArrayRef<Decl *> DeclsToIndex,
+             const CanonicalIncludes &Includes, bool IsIndexMainAST) {
   SymbolCollector::Options CollectorOpts;
-  // FIXME(ioeric): we might also want to collect include headers. We would need
-  // to make sure all includes are canonicalized (with CanonicalIncludes), which
-  // is not trivial given the current way of collecting symbols: we only have
-  // AST at this point, but we also need preprocessor callbacks (e.g.
-  // CommentHandler for IWYU pragma) to canonicalize includes.
-  CollectorOpts.CollectIncludePath = false;
+  CollectorOpts.CollectIncludePath = true;
+  CollectorOpts.Includes = &Includes;
   CollectorOpts.CountReferences = false;
   CollectorOpts.Origin = SymbolOrigin::Dynamic;
 
@@ -48,9 +46,13 @@
   if (IsIndexMainAST) {
     // We only collect refs when indexing main AST.
     CollectorOpts.RefFilter = RefKind::All;
-  }else {
+    // Comments for main file can always be obtained from sema, do not store
+    // them in the index.
+    CollectorOpts.StoreAllDocumentation = false;
+  } else {
     IndexOpts.IndexMacrosInPreprocessor = true;
     CollectorOpts.CollectMacro = true;
+    CollectorOpts.StoreAllDocumentation = true;
   }
 
   SymbolCollector Collector(std::move(CollectorOpts));
@@ -73,16 +75,16 @@
 
 std::pair<SymbolSlab, RefSlab> indexMainDecls(ParsedAST &AST) {
   return indexSymbols(AST.getASTContext(), AST.getPreprocessorPtr(),
-                      AST.getLocalTopLevelDecls(),
+                      AST.getLocalTopLevelDecls(), AST.getCanonicalIncludes(),
                       /*IsIndexMainAST=*/true);
 }
 
-SymbolSlab indexHeaderSymbols(ASTContext &AST,
-                              std::shared_ptr<Preprocessor> PP) {
+SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
+                              const CanonicalIncludes &Includes) {
   std::vector<Decl *> DeclsToIndex(
       AST.getTranslationUnitDecl()->decls().begin(),
       AST.getTranslationUnitDecl()->decls().end());
-  return indexSymbols(AST, std::move(PP), DeclsToIndex,
+  return indexSymbols(AST, std::move(PP), DeclsToIndex, Includes,
                       /*IsIndexMainAST=*/false)
       .first;
 }
@@ -196,8 +198,9 @@
       MainFileIndex(llvm::make_unique<MemIndex>()) {}
 
 void FileIndex::updatePreamble(PathRef Path, ASTContext &AST,
-                               std::shared_ptr<Preprocessor> PP) {
-  auto Symbols = indexHeaderSymbols(AST, std::move(PP));
+                               std::shared_ptr<Preprocessor> PP,
+                               const CanonicalIncludes &Includes) {
+  auto Symbols = indexHeaderSymbols(AST, std::move(PP), Includes);
   PreambleSymbols.update(Path,
                          llvm::make_unique<SymbolSlab>(std::move(Symbols)),
                          llvm::make_unique<RefSlab>());
diff --git a/clangd/index/FileIndex.h b/clangd/index/FileIndex.h
index 92e3b2b..d9bee88 100644
--- a/clangd/index/FileIndex.h
+++ b/clangd/index/FileIndex.h
@@ -1,9 +1,8 @@
 //===--- FileIndex.h - Index for files. ---------------------------- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -20,6 +19,8 @@
 #include "Index.h"
 #include "MemIndex.h"
 #include "Merge.h"
+#include "index/CanonicalIncludes.h"
+#include "index/Symbol.h"
 #include "clang/Lex/Preprocessor.h"
 #include <memory>
 
@@ -85,7 +86,8 @@
   /// Update preamble symbols of file \p Path with all declarations in \p AST
   /// and macros in \p PP.
   void updatePreamble(PathRef Path, ASTContext &AST,
-                      std::shared_ptr<Preprocessor> PP);
+                      std::shared_ptr<Preprocessor> PP,
+                      const CanonicalIncludes &Includes);
 
   /// Update symbols and references from main file \p Path with
   /// `indexMainDecls`.
@@ -125,8 +127,8 @@
 
 /// Idex declarations from \p AST and macros from \p PP that are declared in
 /// included headers.
-SymbolSlab indexHeaderSymbols(ASTContext &AST,
-                              std::shared_ptr<Preprocessor> PP);
+SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
+                              const CanonicalIncludes &Includes);
 
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp
index 4036d67..a5bfc67 100644
--- a/clangd/index/Index.cpp
+++ b/clangd/index/Index.cpp
@@ -1,9 +1,8 @@
 //===--- Index.cpp -----------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,152 +12,11 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/raw_ostream.h"
+#include <limits>
 
 namespace clang {
 namespace clangd {
 
-constexpr uint32_t SymbolLocation::Position::MaxLine;
-constexpr uint32_t SymbolLocation::Position::MaxColumn;
-void SymbolLocation::Position::setLine(uint32_t L) {
-  if (L > MaxLine) {
-    Line = MaxLine;
-    return;
-  }
-  Line = L;
-}
-void SymbolLocation::Position::setColumn(uint32_t Col) {
-  if (Col > MaxColumn) {
-    Column = MaxColumn;
-    return;
-  }
-  Column = Col;
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolLocation &L) {
-  if (!L)
-    return OS << "(none)";
-  return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column()
-            << "-" << L.End.line() << ":" << L.End.column() << ")";
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) {
-  if (O == SymbolOrigin::Unknown)
-    return OS << "unknown";
-  constexpr static char Sigils[] = "ADSM4567";
-  for (unsigned I = 0; I < sizeof(Sigils); ++I)
-    if (static_cast<uint8_t>(O) & 1u << I)
-      OS << Sigils[I];
-  return OS;
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) {
-  if (F == Symbol::None)
-    return OS << "None";
-  std::string s;
-  if (F & Symbol::Deprecated)
-    s += "deprecated|";
-  if (F & Symbol::IndexedForCodeCompletion)
-    s += "completion|";
-  return OS << llvm::StringRef(s).rtrim('|');
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
-  return OS << S.Scope << S.Name;
-}
-
-float quality(const Symbol &S) {
-  // This avoids a sharp gradient for tail symbols, and also neatly avoids the
-  // question of whether 0 references means a bad symbol or missing data.
-  if (S.References < 3)
-    return 1;
-  return std::log(S.References);
-}
-
-SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const {
-  auto It = std::lower_bound(
-      Symbols.begin(), Symbols.end(), ID,
-      [](const Symbol &S, const SymbolID &I) { return S.ID < I; });
-  if (It != Symbols.end() && It->ID == ID)
-    return It;
-  return Symbols.end();
-}
-
-// Copy the underlying data of the symbol into the owned arena.
-static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
-  visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); });
-}
-
-void SymbolSlab::Builder::insert(const Symbol &S) {
-  auto R = SymbolIndex.try_emplace(S.ID, Symbols.size());
-  if (R.second) {
-    Symbols.push_back(S);
-    own(Symbols.back(), UniqueStrings);
-  } else {
-    auto &Copy = Symbols[R.first->second] = S;
-    own(Copy, UniqueStrings);
-  }
-}
-
-SymbolSlab SymbolSlab::Builder::build() && {
-  Symbols = {Symbols.begin(), Symbols.end()}; // Force shrink-to-fit.
-  // Sort symbols so the slab can binary search over them.
-  llvm::sort(Symbols,
-             [](const Symbol &L, const Symbol &R) { return L.ID < R.ID; });
-  // We may have unused strings from overwritten symbols. Build a new arena.
-  llvm::BumpPtrAllocator NewArena;
-  llvm::UniqueStringSaver Strings(NewArena);
-  for (auto &S : Symbols)
-    own(S, Strings);
-  return SymbolSlab(std::move(NewArena), std::move(Symbols));
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) {
-  if (K == RefKind::Unknown)
-    return OS << "Unknown";
-  static const std::vector<const char *> Messages = {"Decl", "Def", "Ref"};
-  bool VisitedOnce = false;
-  for (unsigned I = 0; I < Messages.size(); ++I) {
-    if (static_cast<uint8_t>(K) & 1u << I) {
-      if (VisitedOnce)
-        OS << ", ";
-      OS << Messages[I];
-      VisitedOnce = true;
-    }
-  }
-  return OS;
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) {
-  return OS << R.Location << ":" << R.Kind;
-}
-
-void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) {
-  auto &M = Refs[ID];
-  M.push_back(S);
-  M.back().Location.FileURI =
-      UniqueStrings.save(M.back().Location.FileURI).data();
-}
-
-RefSlab RefSlab::Builder::build() && {
-  // We can reuse the arena, as it only has unique strings and we need them all.
-  // Reallocate refs on the arena to reduce waste and indirections when reading.
-  std::vector<std::pair<SymbolID, llvm::ArrayRef<Ref>>> Result;
-  Result.reserve(Refs.size());
-  size_t NumRefs = 0;
-  for (auto &Sym : Refs) {
-    auto &SymRefs = Sym.second;
-    llvm::sort(SymRefs);
-    // FIXME: do we really need to dedup?
-    SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end());
-
-    NumRefs += SymRefs.size();
-    auto *Array = Arena.Allocate<Ref>(SymRefs.size());
-    std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array);
-    Result.emplace_back(Sym.first, llvm::ArrayRef<Ref>(Array, SymRefs.size()));
-  }
-  return RefSlab(std::move(Result), std::move(Arena), NumRefs);
-}
-
 void SwapIndex::reset(std::unique_ptr<SymbolIndex> Index) {
   // Keep the old index alive, so we don't destroy it under lock (may be slow).
   std::shared_ptr<SymbolIndex> Pin;
@@ -180,7 +38,8 @@
       O && O.map("Query", Request.Query) && O.map("Scopes", Request.Scopes) &&
       O.map("AnyScope", Request.AnyScope) && O.map("Limit", Limit) &&
       O.map("RestrictForCodeCompletion", Request.RestrictForCodeCompletion) &&
-      O.map("ProximityPaths", Request.ProximityPaths);
+      O.map("ProximityPaths", Request.ProximityPaths) &&
+      O.map("PreferredTypes", Request.PreferredTypes);
   if (OK && Limit <= std::numeric_limits<uint32_t>::max())
     Request.Limit = Limit;
   return OK;
@@ -194,6 +53,7 @@
       {"Limit", Request.Limit},
       {"RestrictForCodeCompletion", Request.RestrictForCodeCompletion},
       {"ProximityPaths", llvm::json::Array{Request.ProximityPaths}},
+      {"PreferredTypes", llvm::json::Array{Request.PreferredTypes}},
   };
 }
 
diff --git a/clangd/index/Index.h b/clangd/index/Index.h
index cc4cf2a..0a271a7 100644
--- a/clangd/index/Index.h
+++ b/clangd/index/Index.h
@@ -1,438 +1,27 @@
 //===--- Index.h -------------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 
-#include "ExpectedTypes.h"
+#include "Ref.h"
+#include "Symbol.h"
 #include "SymbolID.h"
-#include "clang/Index/IndexSymbol.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/JSON.h"
-#include "llvm/Support/StringSaver.h"
-#include <array>
-#include <limits>
 #include <mutex>
 #include <string>
-#include <tuple>
 
 namespace clang {
 namespace clangd {
 
-struct SymbolLocation {
-  // Specify a position (Line, Column) of symbol. Using Line/Column allows us to
-  // build LSP responses without reading the file content.
-  //
-  // Position is encoded into 32 bits to save space.
-  // If Line/Column overflow, the value will be their maximum value.
-  struct Position {
-    Position() : Line(0), Column(0) {}
-    void setLine(uint32_t Line);
-    uint32_t line() const { return Line; }
-    void setColumn(uint32_t Column);
-    uint32_t column() const { return Column; }
-
-    bool hasOverflow() const {
-      return Line >= MaxLine || Column >= MaxColumn;
-    }
-
-    static constexpr uint32_t MaxLine = (1 << 20) - 1;
-    static constexpr uint32_t MaxColumn = (1 << 12) - 1;
-
-  private:
-    uint32_t Line : 20; // 0-based
-    // Using UTF-16 code units.
-    uint32_t Column : 12; // 0-based
-  };
-
-  /// The symbol range, using half-open range [Start, End).
-  Position Start;
-  Position End;
-
-  explicit operator bool() const { return !StringRef(FileURI).empty(); }
-
-  // The URI of the source file where a symbol occurs.
-  // The string must be null-terminated.
-  //
-  // We avoid using llvm::StringRef here to save memory.
-  // WARNING: unless you know what you are doing, it is recommended to use it
-  // via llvm::StringRef.
-  const char *FileURI = "";
-};
-inline bool operator==(const SymbolLocation::Position &L,
-                       const SymbolLocation::Position &R) {
-  return std::make_tuple(L.line(), L.column()) ==
-         std::make_tuple(R.line(), R.column());
-}
-inline bool operator<(const SymbolLocation::Position &L,
-                      const SymbolLocation::Position &R) {
-  return std::make_tuple(L.line(), L.column()) <
-         std::make_tuple(R.line(), R.column());
-}
-inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) {
-  assert(L.FileURI && R.FileURI);
-  return !std::strcmp(L.FileURI, R.FileURI) &&
-         std::tie(L.Start, L.End) == std::tie(R.Start, R.End);
-}
-inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) {
-  assert(L.FileURI && R.FileURI);
-  int Cmp = std::strcmp(L.FileURI, R.FileURI);
-  if (Cmp != 0)
-    return Cmp < 0;
-  return std::tie(L.Start, L.End) < std::tie(R.Start, R.End);
-}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
-
-} // namespace clangd
-} // namespace clang
-namespace llvm {
-// Support SymbolIDs as DenseMap keys.
-template <> struct DenseMapInfo<clang::clangd::SymbolID> {
-  static inline clang::clangd::SymbolID getEmptyKey() {
-    static clang::clangd::SymbolID EmptyKey("EMPTYKEY");
-    return EmptyKey;
-  }
-  static inline clang::clangd::SymbolID getTombstoneKey() {
-    static clang::clangd::SymbolID TombstoneKey("TOMBSTONEKEY");
-    return TombstoneKey;
-  }
-  static unsigned getHashValue(const clang::clangd::SymbolID &Sym) {
-    return hash_value(Sym);
-  }
-  static bool isEqual(const clang::clangd::SymbolID &LHS,
-                      const clang::clangd::SymbolID &RHS) {
-    return LHS == RHS;
-  }
-};
-} // namespace llvm
-namespace clang {
-namespace clangd {
-
-// Describes the source of information about a symbol.
-// Mainly useful for debugging, e.g. understanding code completion reuslts.
-// This is a bitfield as information can be combined from several sources.
-enum class SymbolOrigin : uint8_t {
-  Unknown = 0,
-  AST = 1 << 0,     // Directly from the AST (indexes should not set this).
-  Dynamic = 1 << 1, // From the dynamic index of opened files.
-  Static = 1 << 2,  // From the static, externally-built index.
-  Merge = 1 << 3,   // A non-trivial index merge was performed.
-  // Remaining bits reserved for index implementations.
-};
-inline SymbolOrigin operator|(SymbolOrigin A, SymbolOrigin B) {
-  return static_cast<SymbolOrigin>(static_cast<uint8_t>(A) |
-                                   static_cast<uint8_t>(B));
-}
-inline SymbolOrigin &operator|=(SymbolOrigin &A, SymbolOrigin B) {
-  return A = A | B;
-}
-inline SymbolOrigin operator&(SymbolOrigin A, SymbolOrigin B) {
-  return static_cast<SymbolOrigin>(static_cast<uint8_t>(A) &
-                                   static_cast<uint8_t>(B));
-}
-raw_ostream &operator<<(raw_ostream &, SymbolOrigin);
-
-// The class presents a C++ symbol, e.g. class, function.
-//
-// WARNING: Symbols do not own much of their underlying data - typically strings
-// are owned by a SymbolSlab. They should be treated as non-owning references.
-// Copies are shallow.
-// When adding new unowned data fields to Symbol, remember to update:
-//   - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage.
-//   - mergeSymbol in Merge.cpp, to properly combine two Symbols.
-//
-// A fully documented symbol can be split as:
-// size_type std::map<k, t>::count(const K& key) const
-// | Return  |     Scope     |Name|    Signature     |
-// We split up these components to allow display flexibility later.
-struct Symbol {
-  // The ID of the symbol.
-  SymbolID ID;
-  // The symbol information, like symbol kind.
-  index::SymbolInfo SymInfo;
-  // The unqualified name of the symbol, e.g. "bar" (for ns::bar).
-  llvm::StringRef Name;
-  // The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
-  llvm::StringRef Scope;
-  // The location of the symbol's definition, if one was found.
-  // This just covers the symbol name (e.g. without class/function body).
-  SymbolLocation Definition;
-  // The location of the preferred declaration of the symbol.
-  // This just covers the symbol name.
-  // This may be the same as Definition.
-  //
-  // A C++ symbol may have multiple declarations, and we pick one to prefer.
-  //   * For classes, the canonical declaration should be the definition.
-  //   * For non-inline functions, the canonical declaration typically appears
-  //     in the ".h" file corresponding to the definition.
-  SymbolLocation CanonicalDeclaration;
-  // The number of translation units that reference this symbol from their main
-  // file. This number is only meaningful if aggregated in an index.
-  unsigned References = 0;
-  /// Where this symbol came from. Usually an index provides a constant value.
-  SymbolOrigin Origin = SymbolOrigin::Unknown;
-  /// A brief description of the symbol that can be appended in the completion
-  /// candidate list. For example, "(X x, Y y) const" is a function signature.
-  /// Only set when the symbol is indexed for completion.
-  llvm::StringRef Signature;
-  /// What to insert when completing this symbol, after the symbol name.
-  /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function).
-  /// (When snippets are disabled, the symbol name alone is used).
-  /// Only set when the symbol is indexed for completion.
-  llvm::StringRef CompletionSnippetSuffix;
-  /// Documentation including comment for the symbol declaration.
-  llvm::StringRef Documentation;
-  /// Type when this symbol is used in an expression. (Short display form).
-  /// e.g. return type of a function, or type of a variable.
-  /// Only set when the symbol is indexed for completion.
-  llvm::StringRef ReturnType;
-
-  /// Raw representation of the OpaqueType of the symbol, used for scoring
-  /// purposes.
-  /// Only set when the symbol is indexed for completion.
-  llvm::StringRef Type;
-
-  struct IncludeHeaderWithReferences {
-    IncludeHeaderWithReferences() = default;
-
-    IncludeHeaderWithReferences(llvm::StringRef IncludeHeader,
-                                unsigned References)
-        : IncludeHeader(IncludeHeader), References(References) {}
-
-    /// This can be either a URI of the header to be #include'd
-    /// for this symbol, or a literal header quoted with <> or "" that is
-    /// suitable to be included directly. When it is a URI, the exact #include
-    /// path needs to be calculated according to the URI scheme.
-    ///
-    /// Note that the include header is a canonical include for the symbol and
-    /// can be different from FileURI in the CanonicalDeclaration.
-    llvm::StringRef IncludeHeader = "";
-    /// The number of translation units that reference this symbol and include
-    /// this header. This number is only meaningful if aggregated in an index.
-    unsigned References = 0;
-  };
-  /// One Symbol can potentially be incuded via different headers.
-  ///   - If we haven't seen a definition, this covers all declarations.
-  ///   - If we have seen a definition, this covers declarations visible from
-  ///   any definition.
-  /// Only set when the symbol is indexed for completion.
-  llvm::SmallVector<IncludeHeaderWithReferences, 1> IncludeHeaders;
-
-  enum SymbolFlag : uint8_t {
-    None = 0,
-    /// Whether or not this symbol is meant to be used for the code completion.
-    /// See also isIndexedForCodeCompletion().
-    /// Note that we don't store completion information (signature, snippet,
-    /// type, inclues) if the symbol is not indexed for code completion.
-    IndexedForCodeCompletion = 1 << 0,
-    /// Indicates if the symbol is deprecated.
-    Deprecated = 1 << 1,
-    // Symbol is an implementation detail.
-    ImplementationDetail = 1 << 2,
-    // Symbol is visible to other files (not e.g. a static helper function).
-    VisibleOutsideFile = 1 << 3,
-  };
-
-  SymbolFlag Flags = SymbolFlag::None;
-  /// FIXME: also add deprecation message and fixit?
-};
-inline Symbol::SymbolFlag  operator|(Symbol::SymbolFlag A, Symbol::SymbolFlag  B) {
-  return static_cast<Symbol::SymbolFlag>(static_cast<uint8_t>(A) |
-                                         static_cast<uint8_t>(B));
-}
-inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A, Symbol::SymbolFlag B) {
-  return A = A | B;
-}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S);
-raw_ostream &operator<<(raw_ostream &, Symbol::SymbolFlag);
-
-// Invokes Callback with each StringRef& contained in the Symbol.
-// Useful for deduplicating backing strings.
-template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
-  CB(S.Name);
-  CB(S.Scope);
-  CB(S.Signature);
-  CB(S.CompletionSnippetSuffix);
-  CB(S.Documentation);
-  CB(S.ReturnType);
-  CB(S.Type);
-  auto RawCharPointerCB = [&CB](const char *&P) {
-    llvm::StringRef S(P);
-    CB(S);
-    assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated");
-    P = S.data();
-  };
-  RawCharPointerCB(S.CanonicalDeclaration.FileURI);
-  RawCharPointerCB(S.Definition.FileURI);
-
-  for (auto &Include : S.IncludeHeaders)
-    CB(Include.IncludeHeader);
-}
-
-// Computes query-independent quality score for a Symbol.
-// This currently falls in the range [1, ln(#indexed documents)].
-// FIXME: this should probably be split into symbol -> signals
-//        and signals -> score, so it can be reused for Sema completions.
-float quality(const Symbol &S);
-
-// An immutable symbol container that stores a set of symbols.
-// The container will maintain the lifetime of the symbols.
-class SymbolSlab {
-public:
-  using const_iterator = std::vector<Symbol>::const_iterator;
-  using iterator = const_iterator;
-  using value_type = Symbol;
-
-  SymbolSlab() = default;
-
-  const_iterator begin() const { return Symbols.begin(); }
-  const_iterator end() const { return Symbols.end(); }
-  const_iterator find(const SymbolID &SymID) const;
-
-  size_t size() const { return Symbols.size(); }
-  bool empty() const { return Symbols.empty(); }
-  // Estimates the total memory usage.
-  size_t bytes() const {
-    return sizeof(*this) + Arena.getTotalMemory() +
-           Symbols.capacity() * sizeof(Symbol);
-  }
-
-  // SymbolSlab::Builder is a mutable container that can 'freeze' to SymbolSlab.
-  // The frozen SymbolSlab will use less memory.
-  class Builder {
-  public:
-    Builder() : UniqueStrings(Arena) {}
-
-    // Adds a symbol, overwriting any existing one with the same ID.
-    // This is a deep copy: underlying strings will be owned by the slab.
-    void insert(const Symbol &S);
-
-    // Returns the symbol with an ID, if it exists. Valid until next insert().
-    const Symbol *find(const SymbolID &ID) {
-      auto I = SymbolIndex.find(ID);
-      return I == SymbolIndex.end() ? nullptr : &Symbols[I->second];
-    }
-
-    // Consumes the builder to finalize the slab.
-    SymbolSlab build() &&;
-
-  private:
-    llvm::BumpPtrAllocator Arena;
-    // Intern table for strings. Contents are on the arena.
-    llvm::UniqueStringSaver UniqueStrings;
-    std::vector<Symbol> Symbols;
-    // Values are indices into Symbols vector.
-    llvm::DenseMap<SymbolID, size_t> SymbolIndex;
-  };
-
-private:
-  SymbolSlab(llvm::BumpPtrAllocator Arena, std::vector<Symbol> Symbols)
-      : Arena(std::move(Arena)), Symbols(std::move(Symbols)) {}
-
-  llvm::BumpPtrAllocator Arena; // Owns Symbol data that the Symbols do not.
-  std::vector<Symbol> Symbols;  // Sorted by SymbolID to allow lookup.
-};
-
-// Describes the kind of a cross-reference.
-//
-// This is a bitfield which can be combined from different kinds.
-enum class RefKind : uint8_t {
-  Unknown = 0,
-  Declaration = static_cast<uint8_t>(index::SymbolRole::Declaration),
-  Definition = static_cast<uint8_t>(index::SymbolRole::Definition),
-  Reference = static_cast<uint8_t>(index::SymbolRole::Reference),
-  All = Declaration | Definition | Reference,
-};
-inline RefKind operator|(RefKind L, RefKind R) {
-  return static_cast<RefKind>(static_cast<uint8_t>(L) |
-                              static_cast<uint8_t>(R));
-}
-inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; }
-inline RefKind operator&(RefKind A, RefKind B) {
-  return static_cast<RefKind>(static_cast<uint8_t>(A) &
-                              static_cast<uint8_t>(B));
-}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
-
-// Represents a symbol occurrence in the source file.
-// Despite the name, it could be a declaration/definition/reference.
-//
-// WARNING: Location does not own the underlying data - Copies are shallow.
-struct Ref {
-  // The source location where the symbol is named.
-  SymbolLocation Location;
-  RefKind Kind = RefKind::Unknown;
-};
-inline bool operator<(const Ref &L, const Ref &R) {
-  return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind);
-}
-inline bool operator==(const Ref &L, const Ref &R) {
-  return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind);
-}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &);
-
-// An efficient structure of storing large set of symbol references in memory.
-// Filenames are deduplicated.
-class RefSlab {
-public:
-  using value_type = std::pair<SymbolID, llvm::ArrayRef<Ref>>;
-  using const_iterator = std::vector<value_type>::const_iterator;
-  using iterator = const_iterator;
-
-  RefSlab() = default;
-  RefSlab(RefSlab &&Slab) = default;
-  RefSlab &operator=(RefSlab &&RHS) = default;
-
-  const_iterator begin() const { return Refs.begin(); }
-  const_iterator end() const { return Refs.end(); }
-  /// Gets the number of symbols.
-  size_t size() const { return Refs.size(); }
-  size_t numRefs() const { return NumRefs; }
-  bool empty() const { return Refs.empty(); }
-
-  size_t bytes() const {
-    return sizeof(*this) + Arena.getTotalMemory() +
-           sizeof(value_type) * Refs.size();
-  }
-
-  // RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
-  class Builder {
-  public:
-    Builder() : UniqueStrings(Arena) {}
-    // Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
-    void insert(const SymbolID &ID, const Ref &S);
-    // Consumes the builder to finalize the slab.
-    RefSlab build() &&;
-
-  private:
-    llvm::BumpPtrAllocator Arena;
-    llvm::UniqueStringSaver UniqueStrings; // Contents on the arena.
-    llvm::DenseMap<SymbolID, std::vector<Ref>> Refs;
-  };
-
-private:
-  RefSlab(std::vector<value_type> Refs, llvm::BumpPtrAllocator Arena,
-          size_t NumRefs)
-      : Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {}
-
-  llvm::BumpPtrAllocator Arena;
-  std::vector<value_type> Refs;
-  // Number of all references.
-  size_t NumRefs = 0;
-};
-
 struct FuzzyFindRequest {
   /// \brief A query string for the fuzzy find. This is matched against symbols'
   /// un-qualified identifiers and should not contain qualifiers like "::".
@@ -455,14 +44,15 @@
   /// Contextually relevant files (e.g. the file we're code-completing in).
   /// Paths should be absolute.
   std::vector<std::string> ProximityPaths;
-
-  // FIXME(ibiryukov): add expected type to the request.
+  /// Preferred types of symbols. These are raw representation of `OpaqueType`.
+  std::vector<std::string> PreferredTypes;
 
   bool operator==(const FuzzyFindRequest &Req) const {
     return std::tie(Query, Scopes, Limit, RestrictForCodeCompletion,
-                    ProximityPaths) ==
+                    ProximityPaths, PreferredTypes) ==
            std::tie(Req.Query, Req.Scopes, Req.Limit,
-                    Req.RestrictForCodeCompletion, Req.ProximityPaths);
+                    Req.RestrictForCodeCompletion, Req.ProximityPaths,
+                    Req.PreferredTypes);
   }
   bool operator!=(const FuzzyFindRequest &Req) const { return !(*this == Req); }
 };
@@ -513,9 +103,6 @@
                     llvm::function_ref<void(const Ref &)> Callback) const = 0;
 
   /// Returns estimated size of index (in bytes).
-  // FIXME(kbobyrev): Currently, this only returns the size of index itself
-  // excluding the size of actual symbol slab index refers to. We should include
-  // both.
   virtual size_t estimateMemoryUsage() const = 0;
 };
 
diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp
index a6df64b..120f6b0 100644
--- a/clangd/index/IndexAction.cpp
+++ b/clangd/index/IndexAction.cpp
@@ -1,6 +1,14 @@
+//===--- IndexAction.cpp -----------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
 #include "IndexAction.h"
+#include "index/SymbolOrigin.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Tooling/Tooling.h"
 
@@ -127,6 +135,11 @@
   bool BeginInvocation(CompilerInstance &CI) override {
     // We want all comments, not just the doxygen ones.
     CI.getLangOpts().CommentOpts.ParseAllComments = true;
+    // Index the whole file even if there are warnings and -Werror is set.
+    // Avoids some analyses too. Set in two places as we're late to the party.
+    CI.getDiagnosticOpts().IgnoreWarnings = true;
+    CI.getDiagnostics().setIgnoreAllWarnings(true);
+
     return WrapperFrontendAction::BeginInvocation(CI);
   }
 
@@ -174,7 +187,9 @@
       index::IndexingOptions::SystemSymbolFilterKind::All;
   Opts.CollectIncludePath = true;
   Opts.CountReferences = true;
-  Opts.Origin = SymbolOrigin::Static;
+  if (Opts.Origin == SymbolOrigin::Unknown)
+    Opts.Origin = SymbolOrigin::Static;
+  Opts.StoreAllDocumentation = false;
   if (RefsCallback != nullptr) {
     Opts.RefFilter = RefKind::All;
     Opts.RefsInHeaders = true;
diff --git a/clangd/index/IndexAction.h b/clangd/index/IndexAction.h
index f2c5298..f2b45de 100644
--- a/clangd/index/IndexAction.h
+++ b/clangd/index/IndexAction.h
@@ -1,9 +1,8 @@
 //===--- IndexAction.h - Run the indexer as a frontend action ----*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,7 +22,7 @@
 //   - include paths are always collected, and canonicalized appropriately
 //   - references are always counted
 //   - all references are collected (if RefsCallback is non-null)
-//   - the symbol origin is always Static
+//   - the symbol origin is set to Static if not specified by caller
 std::unique_ptr<FrontendAction> createStaticIndexingAction(
     SymbolCollector::Options Opts,
     std::function<void(SymbolSlab)> SymbolsCallback,
diff --git a/clangd/index/MemIndex.cpp b/clangd/index/MemIndex.cpp
index e4dc56c..582091f 100644
--- a/clangd/index/MemIndex.cpp
+++ b/clangd/index/MemIndex.cpp
@@ -1,9 +1,8 @@
 //===--- MemIndex.cpp - Dynamic in-memory symbol index. ----------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===-------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 #include "Logger.h"
 #include "Quality.h"
 #include "Trace.h"
+#include "clang/Index/IndexSymbol.h"
 
 namespace clang {
 namespace clangd {
diff --git a/clangd/index/MemIndex.h b/clangd/index/MemIndex.h
index 24f2ba1..47227fd 100644
--- a/clangd/index/MemIndex.h
+++ b/clangd/index/MemIndex.h
@@ -1,9 +1,8 @@
 //===--- MemIndex.h - Dynamic in-memory symbol index. -------------- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp
index 52f54e3..a5945a7 100644
--- a/clangd/index/Merge.cpp
+++ b/clangd/index/Merge.cpp
@@ -1,18 +1,23 @@
 //===--- Merge.cpp -----------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "Merge.h"
 #include "Logger.h"
 #include "Trace.h"
+#include "index/Symbol.h"
+#include "index/SymbolLocation.h"
+#include "index/SymbolOrigin.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <iterator>
 
 namespace clang {
 namespace clangd {
@@ -103,7 +108,6 @@
     Callback(O);
     --Remaining;
   });
-  assert(Remaining >= 0);
   if (Remaining == 0)
     return;
   // We return less than Req.Limit if static index returns more refs for dirty
@@ -116,6 +120,23 @@
   });
 }
 
+// Returns true if \p L is (strictly) preferred to \p R (e.g. by file paths). If
+// neither is preferred, this returns false.
+bool prefer(const SymbolLocation &L, const SymbolLocation &R) {
+  if (!L)
+    return false;
+  if (!R)
+    return true;
+  auto HasCodeGenSuffix = [](const SymbolLocation &Loc) {
+    constexpr static const char *CodegenSuffixes[] = {".proto"};
+    return std::any_of(std::begin(CodegenSuffixes), std::end(CodegenSuffixes),
+                       [&](llvm::StringRef Suffix) {
+                         return llvm::StringRef(Loc.FileURI).endswith(Suffix);
+                       });
+  };
+  return HasCodeGenSuffix(L) && !HasCodeGenSuffix(R);
+}
+
 Symbol mergeSymbol(const Symbol &L, const Symbol &R) {
   assert(L.ID == R.ID);
   // We prefer information from TUs that saw the definition.
@@ -130,12 +151,11 @@
   Symbol S = PreferR ? R : L;        // The target symbol we're merging into.
   const Symbol &O = PreferR ? L : R; // The "other" less-preferred symbol.
 
-  // For each optional field, fill it from O if missing in S.
-  // (It might be missing in O too, but that's a no-op).
-  if (!S.Definition)
-    S.Definition = O.Definition;
-  if (!S.CanonicalDeclaration)
+  // Only use locations in \p O if it's (strictly) preferred.
+  if (prefer(O.CanonicalDeclaration, S.CanonicalDeclaration))
     S.CanonicalDeclaration = O.CanonicalDeclaration;
+  if (prefer(O.Definition, S.Definition))
+    S.Definition = O.Definition;
   S.References += O.References;
   if (S.Signature == "")
     S.Signature = O.Signature;
diff --git a/clangd/index/Merge.h b/clangd/index/Merge.h
index 7569c7a..5954b6b 100644
--- a/clangd/index/Merge.h
+++ b/clangd/index/Merge.h
@@ -1,9 +1,8 @@
 //===--- Merge.h -------------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/Ref.cpp b/clangd/index/Ref.cpp
new file mode 100644
index 0000000..2b21f3c
--- /dev/null
+++ b/clangd/index/Ref.cpp
@@ -0,0 +1,59 @@
+//===--- Ref.cpp -------------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Ref.h"
+
+namespace clang {
+namespace clangd {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) {
+  if (K == RefKind::Unknown)
+    return OS << "Unknown";
+  static const std::vector<const char *> Messages = {"Decl", "Def", "Ref"};
+  bool VisitedOnce = false;
+  for (unsigned I = 0; I < Messages.size(); ++I) {
+    if (static_cast<uint8_t>(K) & 1u << I) {
+      if (VisitedOnce)
+        OS << ", ";
+      OS << Messages[I];
+      VisitedOnce = true;
+    }
+  }
+  return OS;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) {
+  return OS << R.Location << ":" << R.Kind;
+}
+
+void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) {
+  auto &M = Refs[ID];
+  if (M.count(S))
+    return;
+  Ref R = S;
+  R.Location.FileURI =
+      UniqueStrings.save(R.Location.FileURI).data();
+  M.insert(std::move(R));
+}
+
+RefSlab RefSlab::Builder::build() && {
+  // We can reuse the arena, as it only has unique strings and we need them all.
+  // Reallocate refs on the arena to reduce waste and indirections when reading.
+  std::vector<std::pair<SymbolID, llvm::ArrayRef<Ref>>> Result;
+  Result.reserve(Refs.size());
+  size_t NumRefs = 0;
+  for (auto &Sym : Refs) {
+    std::vector<Ref> SymRefs(Sym.second.begin(), Sym.second.end());
+    NumRefs += SymRefs.size();
+    Result.emplace_back(Sym.first, llvm::ArrayRef<Ref>(SymRefs).copy(Arena));
+  }
+  return RefSlab(std::move(Result), std::move(Arena), NumRefs);
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/index/Ref.h b/clangd/index/Ref.h
new file mode 100644
index 0000000..4d6ae16
--- /dev/null
+++ b/clangd/index/Ref.h
@@ -0,0 +1,121 @@
+//===--- Ref.h ---------------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
+
+#include "SymbolID.h"
+#include "SymbolLocation.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <set>
+#include <utility>
+
+namespace clang {
+namespace clangd {
+
+/// Describes the kind of a cross-reference.
+///
+/// This is a bitfield which can be combined from different kinds.
+enum class RefKind : uint8_t {
+  Unknown = 0,
+  Declaration = static_cast<uint8_t>(index::SymbolRole::Declaration),
+  Definition = static_cast<uint8_t>(index::SymbolRole::Definition),
+  Reference = static_cast<uint8_t>(index::SymbolRole::Reference),
+  All = Declaration | Definition | Reference,
+};
+
+inline RefKind operator|(RefKind L, RefKind R) {
+  return static_cast<RefKind>(static_cast<uint8_t>(L) |
+                              static_cast<uint8_t>(R));
+}
+inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; }
+inline RefKind operator&(RefKind A, RefKind B) {
+  return static_cast<RefKind>(static_cast<uint8_t>(A) &
+                              static_cast<uint8_t>(B));
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
+
+/// Represents a symbol occurrence in the source file.
+/// Despite the name, it could be a declaration/definition/reference.
+///
+/// WARNING: Location does not own the underlying data - Copies are shallow.
+struct Ref {
+  /// The source location where the symbol is named.
+  SymbolLocation Location;
+  RefKind Kind = RefKind::Unknown;
+};
+
+inline bool operator<(const Ref &L, const Ref &R) {
+  return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind);
+}
+inline bool operator==(const Ref &L, const Ref &R) {
+  return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind);
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &);
+
+/// An efficient structure of storing large set of symbol references in memory.
+/// Filenames are deduplicated.
+class RefSlab {
+public:
+  // Refs are stored in order.
+  using value_type = std::pair<SymbolID, llvm::ArrayRef<Ref>>;
+  using const_iterator = std::vector<value_type>::const_iterator;
+  using iterator = const_iterator;
+
+  RefSlab() = default;
+  RefSlab(RefSlab &&Slab) = default;
+  RefSlab &operator=(RefSlab &&RHS) = default;
+
+  const_iterator begin() const { return Refs.begin(); }
+  const_iterator end() const { return Refs.end(); }
+  /// Gets the number of symbols.
+  size_t size() const { return Refs.size(); }
+  size_t numRefs() const { return NumRefs; }
+  bool empty() const { return Refs.empty(); }
+
+  size_t bytes() const {
+    return sizeof(*this) + Arena.getTotalMemory() +
+           sizeof(value_type) * Refs.capacity();
+  }
+
+  /// RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
+  class Builder {
+  public:
+    Builder() : UniqueStrings(Arena) {}
+    /// Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
+    void insert(const SymbolID &ID, const Ref &S);
+    /// Consumes the builder to finalize the slab.
+    RefSlab build() &&;
+
+  private:
+    llvm::BumpPtrAllocator Arena;
+    llvm::UniqueStringSaver UniqueStrings; // Contents on the arena.
+    llvm::DenseMap<SymbolID, std::set<Ref>> Refs;
+  };
+
+private:
+  RefSlab(std::vector<value_type> Refs, llvm::BumpPtrAllocator Arena,
+          size_t NumRefs)
+      : Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {}
+
+  llvm::BumpPtrAllocator Arena;
+  std::vector<value_type> Refs;
+  /// Number of all references.
+  size_t NumRefs = 0;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
diff --git a/clangd/index/Serialization.cpp b/clangd/index/Serialization.cpp
index a4f99b1..62eb3fc 100644
--- a/clangd/index/Serialization.cpp
+++ b/clangd/index/Serialization.cpp
@@ -1,16 +1,16 @@
 //===-- Serialization.cpp - Binary serialization of index data ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "Serialization.h"
-#include "Index.h"
 #include "Logger.h"
 #include "RIFF.h"
+#include "SymbolLocation.h"
+#include "SymbolOrigin.h"
 #include "Trace.h"
 #include "dex/Dex.h"
 #include "llvm/Support/Compression.h"
@@ -106,9 +106,9 @@
 };
 
 void write32(uint32_t I, llvm::raw_ostream &OS) {
-  char buf[4];
-  llvm::support::endian::write32le(buf, I);
-  OS.write(buf, sizeof(buf));
+  char Buf[4];
+  llvm::support::endian::write32le(Buf, I);
+  OS.write(Buf, sizeof(Buf));
 }
 
 void writeVar(uint32_t I, llvm::raw_ostream &OS) {
@@ -282,6 +282,7 @@
   OS.write(static_cast<uint8_t>(Sym.SymInfo.Lang));
   writeVar(Strings.index(Sym.Name), OS);
   writeVar(Strings.index(Sym.Scope), OS);
+  writeVar(Strings.index(Sym.TemplateSpecializationArgs), OS);
   writeLocation(Sym.Definition, Strings, OS);
   writeLocation(Sym.CanonicalDeclaration, Strings, OS);
   writeVar(Sym.References, OS);
@@ -309,11 +310,12 @@
   Sym.SymInfo.Lang = static_cast<index::SymbolLanguage>(Data.consume8());
   Sym.Name = Data.consumeString(Strings);
   Sym.Scope = Data.consumeString(Strings);
+  Sym.TemplateSpecializationArgs = Data.consumeString(Strings);
   Sym.Definition = readLocation(Data, Strings);
   Sym.CanonicalDeclaration = readLocation(Data, Strings);
   Sym.References = Data.consumeVar();
-  Sym.Flags = static_cast<Symbol::SymbolFlag>(Data.consumeVar());
-  Sym.Origin = static_cast<SymbolOrigin>(Data.consumeVar());
+  Sym.Flags = static_cast<Symbol::SymbolFlag>(Data.consume8());
+  Sym.Origin = static_cast<SymbolOrigin>(Data.consume8());
   Sym.Signature = Data.consumeString(Strings);
   Sym.CompletionSnippetSuffix = Data.consumeString(Strings);
   Sym.Documentation = Data.consumeString(Strings);
@@ -368,7 +370,7 @@
 // The current versioning scheme is simple - non-current versions are rejected.
 // If you make a breaking change, bump this version number to invalidate stored
 // data. Later we may want to support some backward compatibility.
-constexpr static uint32_t Version = 8;
+constexpr static uint32_t Version = 9;
 
 llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data) {
   auto RIFF = riff::readFile(Data);
diff --git a/clangd/index/Serialization.h b/clangd/index/Serialization.h
index c403b95..3788693 100644
--- a/clangd/index/Serialization.h
+++ b/clangd/index/Serialization.h
@@ -1,9 +1,8 @@
 //===--- Serialization.h - Binary serialization of index data ----*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -24,8 +23,10 @@
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RIFF_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RIFF_H
+
 #include "Headers.h"
 #include "Index.h"
+#include "index/Symbol.h"
 #include "llvm/Support/Error.h"
 
 namespace clang {
diff --git a/clangd/index/Symbol.cpp b/clangd/index/Symbol.cpp
new file mode 100644
index 0000000..137f90d
--- /dev/null
+++ b/clangd/index/Symbol.cpp
@@ -0,0 +1,71 @@
+//===--- Symbol.cpp ----------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Symbol.h"
+
+namespace clang {
+namespace clangd {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) {
+  if (F == Symbol::None)
+    return OS << "None";
+  std::string S;
+  if (F & Symbol::Deprecated)
+    S += "deprecated|";
+  if (F & Symbol::IndexedForCodeCompletion)
+    S += "completion|";
+  return OS << llvm::StringRef(S).rtrim('|');
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
+  return OS << S.Scope << S.Name;
+}
+
+float quality(const Symbol &S) {
+  // This avoids a sharp gradient for tail symbols, and also neatly avoids the
+  // question of whether 0 references means a bad symbol or missing data.
+  if (S.References < 3)
+    return 1;
+  return std::log(S.References);
+}
+
+SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const {
+  auto It =
+      llvm::bsearch(Symbols, [&](const Symbol &S) { return !(S.ID < ID); });
+  if (It != Symbols.end() && It->ID == ID)
+    return It;
+  return Symbols.end();
+}
+
+// Copy the underlying data of the symbol into the owned arena.
+static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
+  visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); });
+}
+
+void SymbolSlab::Builder::insert(const Symbol &S) {
+  own(Symbols[S.ID] = S, UniqueStrings);
+}
+
+SymbolSlab SymbolSlab::Builder::build() && {
+  // Sort symbols into vector so the slab can binary search over them.
+  std::vector<Symbol> SortedSymbols;
+  SortedSymbols.reserve(Symbols.size());
+  for (auto &Entry : Symbols)
+    SortedSymbols.push_back(std::move(Entry.second));
+  llvm::sort(SortedSymbols,
+             [](const Symbol &L, const Symbol &R) { return L.ID < R.ID; });
+  // We may have unused strings from overwritten symbols. Build a new arena.
+  llvm::BumpPtrAllocator NewArena;
+  llvm::UniqueStringSaver Strings(NewArena);
+  for (auto &S : SortedSymbols)
+    own(S, Strings);
+  return SymbolSlab(std::move(NewArena), std::move(SortedSymbols));
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/index/Symbol.h b/clangd/index/Symbol.h
new file mode 100644
index 0000000..65ca826
--- /dev/null
+++ b/clangd/index/Symbol.h
@@ -0,0 +1,238 @@
+//===--- Symbol.h ------------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
+
+#include "SymbolID.h"
+#include "SymbolLocation.h"
+#include "SymbolOrigin.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/StringSaver.h"
+
+namespace clang {
+namespace clangd {
+
+/// The class presents a C++ symbol, e.g. class, function.
+///
+/// WARNING: Symbols do not own much of their underlying data - typically
+/// strings are owned by a SymbolSlab. They should be treated as non-owning
+/// references. Copies are shallow.
+///
+/// When adding new unowned data fields to Symbol, remember to update:
+///   - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage.
+///   - mergeSymbol in Merge.cpp, to properly combine two Symbols.
+///
+/// A fully documented symbol can be split as:
+/// size_type std::map<k, t>::count(const K& key) const
+/// | Return  |     Scope     |Name|    Signature     |
+/// We split up these components to allow display flexibility later.
+struct Symbol {
+  /// The ID of the symbol.
+  SymbolID ID;
+  /// The symbol information, like symbol kind.
+  index::SymbolInfo SymInfo = index::SymbolInfo();
+  /// The unqualified name of the symbol, e.g. "bar" (for ns::bar).
+  llvm::StringRef Name;
+  /// The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
+  llvm::StringRef Scope;
+  /// The location of the symbol's definition, if one was found.
+  /// This just covers the symbol name (e.g. without class/function body).
+  SymbolLocation Definition;
+  /// The location of the preferred declaration of the symbol.
+  /// This just covers the symbol name.
+  /// This may be the same as Definition.
+  ///
+  /// A C++ symbol may have multiple declarations, and we pick one to prefer.
+  ///   * For classes, the canonical declaration should be the definition.
+  ///   * For non-inline functions, the canonical declaration typically appears
+  ///     in the ".h" file corresponding to the definition.
+  SymbolLocation CanonicalDeclaration;
+  /// The number of translation units that reference this symbol from their main
+  /// file. This number is only meaningful if aggregated in an index.
+  unsigned References = 0;
+  /// Where this symbol came from. Usually an index provides a constant value.
+  SymbolOrigin Origin = SymbolOrigin::Unknown;
+  /// A brief description of the symbol that can be appended in the completion
+  /// candidate list. For example, "(X x, Y y) const" is a function signature.
+  /// Only set when the symbol is indexed for completion.
+  llvm::StringRef Signature;
+  /// Argument list in human-readable format, will be displayed to help
+  /// disambiguate between different specializations of a template. Empty for
+  /// non-specializations. Example: "<int, bool, 3>"
+  llvm::StringRef TemplateSpecializationArgs;
+  /// What to insert when completing this symbol, after the symbol name.
+  /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function).
+  /// (When snippets are disabled, the symbol name alone is used).
+  /// Only set when the symbol is indexed for completion.
+  llvm::StringRef CompletionSnippetSuffix;
+  /// Documentation including comment for the symbol declaration.
+  llvm::StringRef Documentation;
+  /// Type when this symbol is used in an expression. (Short display form).
+  /// e.g. return type of a function, or type of a variable.
+  /// Only set when the symbol is indexed for completion.
+  llvm::StringRef ReturnType;
+
+  /// Raw representation of the OpaqueType of the symbol, used for scoring
+  /// purposes.
+  /// Only set when the symbol is indexed for completion.
+  llvm::StringRef Type;
+
+  struct IncludeHeaderWithReferences {
+    IncludeHeaderWithReferences() = default;
+
+    IncludeHeaderWithReferences(llvm::StringRef IncludeHeader,
+                                unsigned References)
+        : IncludeHeader(IncludeHeader), References(References) {}
+
+    /// This can be either a URI of the header to be #include'd
+    /// for this symbol, or a literal header quoted with <> or "" that is
+    /// suitable to be included directly. When it is a URI, the exact #include
+    /// path needs to be calculated according to the URI scheme.
+    ///
+    /// Note that the include header is a canonical include for the symbol and
+    /// can be different from FileURI in the CanonicalDeclaration.
+    llvm::StringRef IncludeHeader = "";
+    /// The number of translation units that reference this symbol and include
+    /// this header. This number is only meaningful if aggregated in an index.
+    unsigned References = 0;
+  };
+  /// One Symbol can potentially be incuded via different headers.
+  ///   - If we haven't seen a definition, this covers all declarations.
+  ///   - If we have seen a definition, this covers declarations visible from
+  ///   any definition.
+  /// Only set when the symbol is indexed for completion.
+  llvm::SmallVector<IncludeHeaderWithReferences, 1> IncludeHeaders;
+
+  enum SymbolFlag : uint8_t {
+    None = 0,
+    /// Whether or not this symbol is meant to be used for the code completion.
+    /// See also isIndexedForCodeCompletion().
+    /// Note that we don't store completion information (signature, snippet,
+    /// type, inclues) if the symbol is not indexed for code completion.
+    IndexedForCodeCompletion = 1 << 0,
+    /// Indicates if the symbol is deprecated.
+    Deprecated = 1 << 1,
+    /// Symbol is an implementation detail.
+    ImplementationDetail = 1 << 2,
+    /// Symbol is visible to other files (not e.g. a static helper function).
+    VisibleOutsideFile = 1 << 3,
+  };
+
+  SymbolFlag Flags = SymbolFlag::None;
+  /// FIXME: also add deprecation message and fixit?
+};
+
+inline Symbol::SymbolFlag operator|(Symbol::SymbolFlag A,
+                                    Symbol::SymbolFlag B) {
+  return static_cast<Symbol::SymbolFlag>(static_cast<uint8_t>(A) |
+                                         static_cast<uint8_t>(B));
+}
+inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A,
+                                      Symbol::SymbolFlag B) {
+  return A = A | B;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag);
+
+/// Invokes Callback with each StringRef& contained in the Symbol.
+/// Useful for deduplicating backing strings.
+template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
+  CB(S.Name);
+  CB(S.Scope);
+  CB(S.TemplateSpecializationArgs);
+  CB(S.Signature);
+  CB(S.CompletionSnippetSuffix);
+  CB(S.Documentation);
+  CB(S.ReturnType);
+  CB(S.Type);
+  auto RawCharPointerCB = [&CB](const char *&P) {
+    llvm::StringRef S(P);
+    CB(S);
+    assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated");
+    P = S.data();
+  };
+  RawCharPointerCB(S.CanonicalDeclaration.FileURI);
+  RawCharPointerCB(S.Definition.FileURI);
+
+  for (auto &Include : S.IncludeHeaders)
+    CB(Include.IncludeHeader);
+}
+
+/// Computes query-independent quality score for a Symbol.
+/// This currently falls in the range [1, ln(#indexed documents)].
+/// FIXME: this should probably be split into symbol -> signals
+///        and signals -> score, so it can be reused for Sema completions.
+float quality(const Symbol &S);
+
+/// An immutable symbol container that stores a set of symbols.
+/// The container will maintain the lifetime of the symbols.
+class SymbolSlab {
+public:
+  using const_iterator = std::vector<Symbol>::const_iterator;
+  using iterator = const_iterator;
+  using value_type = Symbol;
+
+  SymbolSlab() = default;
+
+  const_iterator begin() const { return Symbols.begin(); }
+  const_iterator end() const { return Symbols.end(); }
+  const_iterator find(const SymbolID &SymID) const;
+
+  size_t size() const { return Symbols.size(); }
+  bool empty() const { return Symbols.empty(); }
+  // Estimates the total memory usage.
+  size_t bytes() const {
+    return sizeof(*this) + Arena.getTotalMemory() +
+           Symbols.capacity() * sizeof(Symbol);
+  }
+
+  /// SymbolSlab::Builder is a mutable container that can 'freeze' to
+  /// SymbolSlab. The frozen SymbolSlab will use less memory.
+  class Builder {
+  public:
+    Builder() : UniqueStrings(Arena) {}
+
+    /// Adds a symbol, overwriting any existing one with the same ID.
+    /// This is a deep copy: underlying strings will be owned by the slab.
+    void insert(const Symbol &S);
+
+    /// Removes the symbol with an ID, if it exists.
+    void erase(const SymbolID &ID) { Symbols.erase(ID); }
+
+    /// Returns the symbol with an ID, if it exists. Valid until insert/remove.
+    const Symbol *find(const SymbolID &ID) {
+      auto I = Symbols.find(ID);
+      return I == Symbols.end() ? nullptr : &I->second;
+    }
+
+    /// Consumes the builder to finalize the slab.
+    SymbolSlab build() &&;
+
+  private:
+    llvm::BumpPtrAllocator Arena;
+    /// Intern table for strings. Contents are on the arena.
+    llvm::UniqueStringSaver UniqueStrings;
+    /// Values are indices into Symbols vector.
+    llvm::DenseMap<SymbolID, Symbol> Symbols;
+  };
+
+private:
+  SymbolSlab(llvm::BumpPtrAllocator Arena, std::vector<Symbol> Symbols)
+      : Arena(std::move(Arena)), Symbols(std::move(Symbols)) {}
+
+  llvm::BumpPtrAllocator Arena; // Owns Symbol data that the Symbols do not.
+  std::vector<Symbol> Symbols;  // Sorted by SymbolID to allow lookup.
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp
index d3ce771..af1938d 100644
--- a/clangd/index/SymbolCollector.cpp
+++ b/clangd/index/SymbolCollector.cpp
@@ -1,9 +1,8 @@
 //===--- SymbolCollector.cpp -------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,8 +11,10 @@
 #include "CanonicalIncludes.h"
 #include "CodeComplete.h"
 #include "CodeCompletionStrings.h"
+#include "ExpectedTypes.h"
 #include "Logger.h"
 #include "SourceCode.h"
+#include "SymbolLocation.h"
 #include "URI.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
@@ -23,7 +24,9 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Index/IndexSymbol.h"
+#include "clang/Index/IndexingAction.h"
 #include "clang/Index/USRGeneration.h"
+#include "clang/Lex/Preprocessor.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -126,36 +129,6 @@
   }
 }
 
-/// Gets a canonical include (URI of the header or <header>  or "header") for
-/// header of \p Loc.
-/// Returns None if fails to get include header for \p Loc.
-llvm::Optional<std::string>
-getIncludeHeader(llvm::StringRef QName, const SourceManager &SM,
-                 SourceLocation Loc, const SymbolCollector::Options &Opts) {
-  std::vector<std::string> Headers;
-  // Collect the #include stack.
-  while (true) {
-    if (!Loc.isValid())
-      break;
-    auto FilePath = SM.getFilename(Loc);
-    if (FilePath.empty())
-      break;
-    Headers.push_back(FilePath);
-    if (SM.isInMainFile(Loc))
-      break;
-    Loc = SM.getIncludeLoc(SM.getFileID(Loc));
-  }
-  if (Headers.empty())
-    return None;
-  llvm::StringRef Header = Headers[0];
-  if (Opts.Includes) {
-    Header = Opts.Includes->mapHeader(Headers, QName);
-    if (Header.startswith("<") || Header.startswith("\""))
-      return Header.str();
-  }
-  return toURI(SM, Header, Opts);
-}
-
 // Return the symbol range of the token at \p TokLoc.
 std::pair<SymbolLocation::Position, SymbolLocation::Position>
 getTokenRange(SourceLocation TokLoc, const SourceManager &SM,
@@ -210,7 +183,7 @@
 // the first seen declaration as canonical declaration is not a good enough
 // heuristic.
 bool isPreferredDeclaration(const NamedDecl &ND, index::SymbolRoleSet Roles) {
-  const auto& SM = ND.getASTContext().getSourceManager();
+  const auto &SM = ND.getASTContext().getSourceManager();
   return (Roles & static_cast<unsigned>(index::SymbolRole::Definition)) &&
          isa<TagDecl>(&ND) &&
          !SM.isWrittenInMainFile(SM.getExpansionLoc(ND.getLocation()));
@@ -220,13 +193,6 @@
   return static_cast<RefKind>(static_cast<unsigned>(RefKind::All) & Roles);
 }
 
-template <class T> bool explicitTemplateSpecialization(const NamedDecl &ND) {
-  if (const auto *TD = dyn_cast<T>(&ND))
-    if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
-      return true;
-  return false;
-}
-
 } // namespace
 
 SymbolCollector::SymbolCollector(Options Opts) : Opts(std::move(Opts)) {}
@@ -242,8 +208,6 @@
                                           const ASTContext &ASTCtx,
                                           const Options &Opts,
                                           bool IsMainFileOnly) {
-  if (ND.isImplicit())
-    return false;
   // Skip anonymous declarations, e.g (anonymous enum/class/struct).
   if (ND.getDeclName().isEmpty())
     return false;
@@ -278,10 +242,6 @@
     if (!isa<RecordDecl>(DeclCtx))
       return false;
   }
-  if (explicitTemplateSpecialization<FunctionDecl>(ND) ||
-      explicitTemplateSpecialization<CXXRecordDecl>(ND) ||
-      explicitTemplateSpecialization<VarDecl>(ND))
-    return false;
 
   // Avoid indexing internal symbols in protobuf generated headers.
   if (isPrivateProtoDecl(ND))
@@ -297,6 +257,11 @@
   assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set.");
   assert(CompletionAllocator && CompletionTUInfo);
   assert(ASTNode.OrigD);
+  // Indexing API puts cannonical decl into D, which might not have a valid
+  // source location for implicit/built-in decls. Fallback to original decl in
+  // such cases.
+  if (D->getLocation().isInvalid())
+    D = ASTNode.OrigD;
   // If OrigD is an declaration associated with a friend declaration and it's
   // not a definition, skip it. Note that OrigD is the occurrence that the
   // collector is currently visiting.
@@ -304,6 +269,10 @@
        Decl::FriendObjectKind::FOK_None) &&
       !(Roles & static_cast<unsigned>(index::SymbolRole::Definition)))
     return true;
+  // Skip non-semantic references, we should start processing these when we
+  // decide to implement renaming with index support.
+  if ((Roles & static_cast<unsigned>(index::SymbolRole::NameReference)))
+    return true;
   // A declaration created for a friend declaration should not be used as the
   // canonical declaration in the index. Use OrigD instead, unless we've already
   // picked a replacement for D
@@ -332,9 +301,11 @@
 
   // ND is the canonical (i.e. first) declaration. If it's in the main file,
   // then no public declaration was visible, so assume it's main-file only.
-  bool IsMainFileOnly = SM.isWrittenInMainFile(SM.getExpansionLoc(
-    ND->getBeginLoc()));
-  if (!shouldCollectSymbol(*ND, *ASTCtx, Opts, IsMainFileOnly))
+  bool IsMainFileOnly =
+      SM.isWrittenInMainFile(SM.getExpansionLoc(ND->getBeginLoc()));
+  // In C, printf is a redecl of an implicit builtin! So check OrigD instead.
+  if (ASTNode.OrigD->isImplicit() ||
+      !shouldCollectSymbol(*ND, *ASTCtx, Opts, IsMainFileOnly))
     return true;
   // Do not store references to main-file symbols.
   if (CollectRef && !IsMainFileOnly && !isa<NamespaceDecl>(ND) &&
@@ -348,19 +319,25 @@
   if (!ID)
     return true;
 
-  const NamedDecl &OriginalDecl = *cast<NamedDecl>(ASTNode.OrigD);
+  // FIXME: ObjCPropertyDecl are not properly indexed here:
+  // - ObjCPropertyDecl may have an OrigD of ObjCPropertyImplDecl, which is
+  // not a NamedDecl.
+  auto *OriginalDecl = dyn_cast<NamedDecl>(ASTNode.OrigD);
+  if (!OriginalDecl)
+    return true;
+
   const Symbol *BasicSymbol = Symbols.find(*ID);
   if (!BasicSymbol) // Regardless of role, ND is the canonical declaration.
     BasicSymbol = addDeclaration(*ND, std::move(*ID), IsMainFileOnly);
-  else if (isPreferredDeclaration(OriginalDecl, Roles))
+  else if (isPreferredDeclaration(*OriginalDecl, Roles))
     // If OriginalDecl is preferred, replace the existing canonical
     // declaration (e.g. a class forward declaration). There should be at most
     // one duplicate as we expect to see only one preferred declaration per
     // TU, because in practice they are definitions.
-    BasicSymbol = addDeclaration(OriginalDecl, std::move(*ID), IsMainFileOnly);
+    BasicSymbol = addDeclaration(*OriginalDecl, std::move(*ID), IsMainFileOnly);
 
   if (Roles & static_cast<unsigned>(index::SymbolRole::Definition))
-    addDefinition(OriginalDecl, *BasicSymbol);
+    addDefinition(*OriginalDecl, *BasicSymbol);
   return true;
 }
 
@@ -374,11 +351,18 @@
 
   const auto &SM = PP->getSourceManager();
   auto DefLoc = MI->getDefinitionLoc();
-  if (SM.isInMainFile(SM.getExpansionLoc(DefLoc)))
+
+  // Builtin macros don't have useful locations and aren't needed in completion.
+  if (MI->isBuiltinMacro())
     return true;
-  // Header guards are not interesting in index. Builtin macros don't have
-  // useful locations and are not needed for code completions.
-  if (MI->isUsedForHeaderGuard() || MI->isBuiltinMacro())
+
+  // Skip main-file symbols if we are not collecting them.
+  bool IsMainFileSymbol = SM.isInMainFile(SM.getExpansionLoc(DefLoc));
+  if (IsMainFileSymbol && !Opts.CollectMainFileSymbols)
+    return false;
+
+  // Also avoid storing predefined macros like __DBL_MIN__.
+  if (SM.isWrittenInBuiltinFile(DefLoc))
     return true;
 
   // Mark the macro as referenced if this is a reference coming from the main
@@ -405,7 +389,10 @@
   Symbol S;
   S.ID = std::move(*ID);
   S.Name = Name->getName();
-  S.Flags |= Symbol::IndexedForCodeCompletion;
+  if (!IsMainFileSymbol) {
+    S.Flags |= Symbol::IndexedForCodeCompletion;
+    S.Flags |= Symbol::VisibleOutsideFile;
+  }
   S.SymInfo = index::getSymbolInfoForMacro(*MI);
   std::string FileURI;
   // FIXME: use the result to filter out symbols.
@@ -420,22 +407,25 @@
   std::string Signature;
   std::string SnippetSuffix;
   getSignature(*CCS, &Signature, &SnippetSuffix);
-
-  std::string Include;
-  if (Opts.CollectIncludePath && shouldCollectIncludePath(S.SymInfo.Kind)) {
-    if (auto Header = getIncludeHeader(Name->getName(), SM,
-                                       SM.getExpansionLoc(DefLoc), Opts))
-      Include = std::move(*Header);
-  }
   S.Signature = Signature;
   S.CompletionSnippetSuffix = SnippetSuffix;
-  if (!Include.empty())
-    S.IncludeHeaders.emplace_back(Include, 1);
 
+  IndexedMacros.insert(Name);
+  setIncludeLocation(S, DefLoc);
   Symbols.insert(S);
   return true;
 }
 
+void SymbolCollector::setIncludeLocation(const Symbol &S,
+                                         SourceLocation Loc) {
+  if (Opts.CollectIncludePath)
+    if (shouldCollectIncludePath(S.SymInfo.Kind))
+      // Use the expansion location to get the #include header since this is
+      // where the symbol is exposed.
+      IncludeFiles[S.ID] =
+          PP->getSourceManager().getDecomposedExpansionLoc(Loc).first;
+}
+
 void SymbolCollector::finish() {
   // At the end of the TU, add 1 to the refcount of all referenced symbols.
   auto IncRef = [this](const SymbolID &ID) {
@@ -452,6 +442,14 @@
   }
   if (Opts.CollectMacro) {
     assert(PP);
+    // First, drop header guards. We can't identify these until EOF.
+    for (const IdentifierInfo *II : IndexedMacros) {
+      if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
+        if (auto ID = getSymbolID(*II, MI, PP->getSourceManager()))
+          if (MI->isUsedForHeaderGuard())
+            Symbols.erase(*ID);
+    }
+    // Now increment refcounts.
     for (const IdentifierInfo *II : ReferencedMacros) {
       if (const auto *MI = PP->getMacroDefinition(II).getMacroInfo())
         if (auto ID = getSymbolID(*II, MI, PP->getSourceManager()))
@@ -459,6 +457,21 @@
     }
   }
 
+  // Fill in IncludeHeaders.
+  // We delay this until end of TU so header guards are all resolved.
+  // Symbols in slabs aren' mutable, so insert() has to walk all the strings :-(
+  llvm::SmallString<256> QName;
+  for (const auto &Entry : IncludeFiles)
+    if (const Symbol *S = Symbols.find(Entry.first)) {
+      QName = S->Scope;
+      QName.append(S->Name);
+      if (auto Header = getIncludeHeader(QName, Entry.second)) {
+        Symbol NewSym = *S;
+        NewSym.IncludeHeaders.push_back({*Header, 1});
+        Symbols.insert(NewSym);
+      }
+    }
+
   const auto &SM = ASTCtx->getSourceManager();
   llvm::DenseMap<FileID, std::string> URICache;
   auto GetURI = [&](FileID FID) -> llvm::Optional<std::string> {
@@ -476,7 +489,7 @@
     }
     return Found->second;
   };
-
+  // Populate Refs slab from DeclRefs.
   if (auto MainFileURI = GetURI(SM.getMainFileID())) {
     for (const auto &It : DeclRefs) {
       if (auto ID = getSymbolID(It.first)) {
@@ -503,10 +516,11 @@
   ReferencedMacros.clear();
   DeclRefs.clear();
   FilesToIndexCache.clear();
+  HeaderIsSelfContainedCache.clear();
+  IncludeFiles.clear();
 }
 
-const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND,
-                                              SymbolID ID,
+const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID,
                                               bool IsMainFileOnly) {
   auto &Ctx = ND.getASTContext();
   auto &SM = Ctx.getSourceManager();
@@ -514,9 +528,11 @@
   Symbol S;
   S.ID = std::move(ID);
   std::string QName = printQualifiedName(ND);
-  std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
   // FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
   // for consistency with CodeCompletionString and a clean name/signature split.
+  std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
+  std::string TemplateSpecializationArgs = printTemplateSpecializationArgs(ND);
+  S.TemplateSpecializationArgs = TemplateSpecializationArgs;
 
   // We collect main-file symbols, but do not use them for code completion.
   if (!IsMainFileOnly && isIndexedForCodeCompletion(ND, Ctx))
@@ -528,6 +544,7 @@
   S.SymInfo = index::getSymbolInfo(&ND);
   std::string FileURI;
   auto Loc = findNameLoc(&ND);
+  assert(Loc.isValid() && "Invalid source location for NamedDecl");
   // FIXME: use the result to filter out symbols.
   shouldIndexFile(SM, SM.getFileID(Loc), Opts, &FilesToIndexCache);
   if (auto DeclLoc =
@@ -550,18 +567,13 @@
   std::string Documentation =
       formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion,
                                               /*CommentsFromHeaders=*/true));
-  // For symbols not indexed for completion (class members), we also store their
-  // docs in the index, because Sema doesn't load the docs from the preamble, we
-  // rely on the index to get the docs.
-  // FIXME: this can be optimized by only storing the docs in dynamic index --
-  // dynamic index should index these symbols when Sema completes a member
-  // completion.
-  S.Documentation = Documentation;
   if (!(S.Flags & Symbol::IndexedForCodeCompletion)) {
+    if (Opts.StoreAllDocumentation)
+      S.Documentation = Documentation;
     Symbols.insert(S);
     return Symbols.find(S.ID);
   }
-
+  S.Documentation = Documentation;
   std::string Signature;
   std::string SnippetSuffix;
   getSignature(*CCS, &Signature, &SnippetSuffix);
@@ -570,17 +582,6 @@
   std::string ReturnType = getReturnType(*CCS);
   S.ReturnType = ReturnType;
 
-  std::string Include;
-  if (Opts.CollectIncludePath && shouldCollectIncludePath(S.SymInfo.Kind)) {
-    // Use the expansion location to get the #include header since this is
-    // where the symbol is exposed.
-    if (auto Header = getIncludeHeader(
-            QName, SM, SM.getExpansionLoc(ND.getLocation()), Opts))
-      Include = std::move(*Header);
-  }
-  if (!Include.empty())
-    S.IncludeHeaders.emplace_back(Include, 1);
-
   llvm::Optional<OpaqueType> TypeStorage;
   if (S.Flags & Symbol::IndexedForCodeCompletion) {
     TypeStorage = OpaqueType::fromCompletionResult(*ASTCtx, SymbolCompletion);
@@ -589,6 +590,7 @@
   }
 
   Symbols.insert(S);
+  setIncludeLocation(S, ND.getLocation());
   return Symbols.find(S.ID);
 }
 
@@ -611,5 +613,90 @@
   Symbols.insert(S);
 }
 
+/// Gets a canonical include (URI of the header or <header> or "header") for
+/// header of \p FID (which should usually be the *expansion* file).
+/// Returns None if includes should not be inserted for this file.
+llvm::Optional<std::string>
+SymbolCollector::getIncludeHeader(llvm::StringRef QName, FileID FID) {
+  const SourceManager &SM = ASTCtx->getSourceManager();
+  const FileEntry *FE = SM.getFileEntryForID(FID);
+  if (!FE || FE->getName().empty())
+    return llvm::None;
+  llvm::StringRef Filename = FE->getName();
+  // If a file is mapped by canonical headers, use that mapping, regardless
+  // of whether it's an otherwise-good header (header guards etc).
+  if (Opts.Includes) {
+    llvm::StringRef Canonical = Opts.Includes->mapHeader(Filename, QName);
+    // If we had a mapping, always use it.
+    if (Canonical.startswith("<") || Canonical.startswith("\""))
+      return Canonical.str();
+    if (Canonical != Filename)
+      return toURI(SM, Canonical, Opts);
+  }
+  if (!isSelfContainedHeader(FID)) {
+    // A .inc or .def file is often included into a real header to define
+    // symbols (e.g. LLVM tablegen files).
+    if (Filename.endswith(".inc") || Filename.endswith(".def"))
+      return getIncludeHeader(QName, SM.getFileID(SM.getIncludeLoc(FID)));
+    // Conservatively refuse to insert #includes to files without guards.
+    return llvm::None;
+  }
+  // Standard case: just insert the file itself.
+  return toURI(SM, Filename, Opts);
+}
+
+bool SymbolCollector::isSelfContainedHeader(FileID FID) {
+  // The real computation (which will be memoized).
+  auto Compute = [&] {
+    const SourceManager &SM = ASTCtx->getSourceManager();
+    const FileEntry *FE = SM.getFileEntryForID(FID);
+    if (!FE)
+      return false;
+    if (!PP->getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE))
+      return false;
+    // This pattern indicates that a header can't be used without
+    // particular preprocessor state, usually set up by another header.
+    if (isDontIncludeMeHeader(SM.getBufferData(FID)))
+      return false;
+    return true;
+  };
+
+  auto R = HeaderIsSelfContainedCache.try_emplace(FID, false);
+  if (R.second)
+    R.first->second = Compute();
+  return R.first->second;
+}
+
+// Is Line an #if or #ifdef directive?
+static bool isIf(llvm::StringRef Line) {
+  Line = Line.ltrim();
+  if (!Line.consume_front("#"))
+    return false;
+  Line = Line.ltrim();
+  return Line.startswith("if");
+}
+// Is Line an #error directive mentioning includes?
+static bool isErrorAboutInclude(llvm::StringRef Line) {
+  Line = Line.ltrim();
+  if (!Line.consume_front("#"))
+    return false;
+  Line = Line.ltrim();
+  if (! Line.startswith("error"))
+    return false;
+  return Line.contains_lower("includ"); // Matches "include" or "including".
+}
+
+bool SymbolCollector::isDontIncludeMeHeader(llvm::StringRef Content) {
+  llvm::StringRef Line;
+  // Only sniff up to 100 lines or 10KB.
+  Content = Content.take_front(100*100);
+  for (unsigned I = 0; I < 100 && !Content.empty(); ++I) {
+    std::tie(Line, Content) = Content.split('\n');
+    if (isIf(Line) && isErrorAboutInclude(Content.split('\n').first))
+      return true;
+  }
+  return false;
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h
index 157735d..f746002 100644
--- a/clangd/index/SymbolCollector.h
+++ b/clangd/index/SymbolCollector.h
@@ -1,9 +1,8 @@
 //===--- SymbolCollector.h ---------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_COLLECTOR_H
@@ -11,6 +10,7 @@
 
 #include "CanonicalIncludes.h"
 #include "Index.h"
+#include "SymbolOrigin.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/SourceLocation.h"
@@ -19,6 +19,7 @@
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Regex.h"
 #include <functional>
 
 namespace clang {
@@ -76,6 +77,10 @@
     /// Collect symbols local to main-files, such as static functions
     /// and symbols inside an anonymous namespace.
     bool CollectMainFileSymbols = true;
+    /// If set to true, SymbolCollector will collect doc for all symbols.
+    /// Note that documents of symbols being indexed for completion will always
+    /// be collected regardless of this option.
+    bool StoreAllDocumentation = false;
     /// If this is set, only collect symbols/references from a file if
     /// `FileFilter(SM, FID)` is true. If not set, all files are indexed.
     std::function<bool(const SourceManager &, FileID)> FileFilter = nullptr;
@@ -109,11 +114,23 @@
   void finish() override;
 
 private:
-  const Symbol *addDeclaration(const NamedDecl &, SymbolID, bool IsMainFileSymbol);
+  const Symbol *addDeclaration(const NamedDecl &, SymbolID,
+                               bool IsMainFileSymbol);
   void addDefinition(const NamedDecl &, const Symbol &DeclSymbol);
 
+  llvm::Optional<std::string> getIncludeHeader(llvm::StringRef QName, FileID);
+  bool isSelfContainedHeader(FileID);
+  // Heuristically headers that only want to be included via an umbrella.
+  static bool isDontIncludeMeHeader(llvm::StringRef);
+
   // All Symbols collected from the AST.
   SymbolSlab::Builder Symbols;
+  // File IDs for Symbol.IncludeHeaders.
+  // The final spelling is calculated in finish().
+  llvm::DenseMap<SymbolID, FileID> IncludeFiles;
+  void setIncludeLocation(const Symbol &S, SourceLocation);
+  // Indexed macros, to be erased if they turned out to be include guards.
+  llvm::DenseSet<const IdentifierInfo *> IndexedMacros;
   // All refs collected from the AST.
   // Only symbols declared in preamble (from #include) and referenced from the
   // main file will be included.
@@ -136,8 +153,10 @@
   llvm::DenseMap<const Decl *, const Decl *> CanonicalDecls;
   // Cache whether to index a file or not.
   llvm::DenseMap<FileID, bool> FilesToIndexCache;
+  llvm::DenseMap<FileID, bool> HeaderIsSelfContainedCache;
 };
 
 } // namespace clangd
 } // namespace clang
+
 #endif
diff --git a/clangd/index/SymbolID.cpp b/clangd/index/SymbolID.cpp
index 1fd4274..b97103d 100644
--- a/clangd/index/SymbolID.cpp
+++ b/clangd/index/SymbolID.cpp
@@ -1,9 +1,8 @@
 //===--- SymbolID.cpp --------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -50,7 +49,8 @@
 
 llvm::hash_code hash_value(const SymbolID &ID) {
   // We already have a good hash, just return the first bytes.
-  assert(sizeof(size_t) <= SymbolID::RawSize && "size_t longer than SHA1!");
+  static_assert(sizeof(size_t) <= SymbolID::RawSize,
+                "size_t longer than SHA1!");
   size_t Result;
   memcpy(&Result, ID.raw().data(), sizeof(size_t));
   return llvm::hash_code(Result);
diff --git a/clangd/index/SymbolID.h b/clangd/index/SymbolID.h
index aa8208c..d715f4d 100644
--- a/clangd/index/SymbolID.h
+++ b/clangd/index/SymbolID.h
@@ -1,15 +1,15 @@
 //===--- SymbolID.h ----------------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
@@ -62,4 +62,25 @@
 } // namespace clangd
 } // namespace clang
 
+namespace llvm {
+// Support SymbolIDs as DenseMap keys.
+template <> struct DenseMapInfo<clang::clangd::SymbolID> {
+  static inline clang::clangd::SymbolID getEmptyKey() {
+    static clang::clangd::SymbolID EmptyKey("EMPTYKEY");
+    return EmptyKey;
+  }
+  static inline clang::clangd::SymbolID getTombstoneKey() {
+    static clang::clangd::SymbolID TombstoneKey("TOMBSTONEKEY");
+    return TombstoneKey;
+  }
+  static unsigned getHashValue(const clang::clangd::SymbolID &Sym) {
+    return hash_value(Sym);
+  }
+  static bool isEqual(const clang::clangd::SymbolID &LHS,
+                      const clang::clangd::SymbolID &RHS) {
+    return LHS == RHS;
+  }
+};
+} // namespace llvm
+
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H
diff --git a/clangd/index/SymbolLocation.cpp b/clangd/index/SymbolLocation.cpp
new file mode 100644
index 0000000..aac5570
--- /dev/null
+++ b/clangd/index/SymbolLocation.cpp
@@ -0,0 +1,40 @@
+//===--- SymbolLocation.cpp --------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolLocation.h"
+
+namespace clang {
+namespace clangd {
+
+constexpr uint32_t SymbolLocation::Position::MaxLine;
+constexpr uint32_t SymbolLocation::Position::MaxColumn;
+
+void SymbolLocation::Position::setLine(uint32_t L) {
+  if (L > MaxLine) {
+    Line = MaxLine;
+    return;
+  }
+  Line = L;
+}
+void SymbolLocation::Position::setColumn(uint32_t Col) {
+  if (Col > MaxColumn) {
+    Column = MaxColumn;
+    return;
+  }
+  Column = Col;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolLocation &L) {
+  if (!L)
+    return OS << "(none)";
+  return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column()
+            << "-" << L.End.line() << ":" << L.End.column() << ")";
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/index/SymbolLocation.h b/clangd/index/SymbolLocation.h
new file mode 100644
index 0000000..9b50354
--- /dev/null
+++ b/clangd/index/SymbolLocation.h
@@ -0,0 +1,94 @@
+//===--- SymbolLocation.h ----------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+namespace clang {
+namespace clangd {
+
+struct SymbolLocation {
+  // Specify a position (Line, Column) of symbol. Using Line/Column allows us to
+  // build LSP responses without reading the file content.
+  //
+  // clangd uses the following definitions, which differ slightly from LSP:
+  //  - Line is the number of newline characters (\n) before the point.
+  //  - Column is (by default) the number of UTF-16 code between the last \n
+  //    (or start of file) and the point.
+  //    If the `offsetEncoding` protocol extension is used to negotiate UTF-8,
+  //    then it is instead the number of *bytes* since the last \n.
+  //
+  // Position is encoded into 32 bits to save space.
+  // If Line/Column overflow, the value will be their maximum value.
+  struct Position {
+    Position() : Line(0), Column(0) {}
+    void setLine(uint32_t Line);
+    uint32_t line() const { return Line; }
+    void setColumn(uint32_t Column);
+    uint32_t column() const { return Column; }
+
+    bool hasOverflow() const {
+      return Line >= MaxLine || Column >= MaxColumn;
+    }
+
+    static constexpr uint32_t MaxLine = (1 << 20) - 1;
+    static constexpr uint32_t MaxColumn = (1 << 12) - 1;
+
+  private:
+    uint32_t Line : 20;   // 0-based
+    uint32_t Column : 12; // 0-based
+  };
+
+  /// The symbol range, using half-open range [Start, End).
+  Position Start;
+  Position End;
+
+  explicit operator bool() const { return !llvm::StringRef(FileURI).empty(); }
+
+  // The URI of the source file where a symbol occurs.
+  // The string must be null-terminated.
+  //
+  // We avoid using llvm::StringRef here to save memory.
+  // WARNING: unless you know what you are doing, it is recommended to use it
+  // via llvm::StringRef.
+  const char *FileURI = "";
+};
+
+inline bool operator==(const SymbolLocation::Position &L,
+                       const SymbolLocation::Position &R) {
+  return std::make_tuple(L.line(), L.column()) ==
+         std::make_tuple(R.line(), R.column());
+}
+inline bool operator<(const SymbolLocation::Position &L,
+                      const SymbolLocation::Position &R) {
+  return std::make_tuple(L.line(), L.column()) <
+         std::make_tuple(R.line(), R.column());
+}
+inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) {
+  assert(L.FileURI && R.FileURI);
+  return !std::strcmp(L.FileURI, R.FileURI) &&
+         std::tie(L.Start, L.End) == std::tie(R.Start, R.End);
+}
+inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) {
+  assert(L.FileURI && R.FileURI);
+  int Cmp = std::strcmp(L.FileURI, R.FileURI);
+  if (Cmp != 0)
+    return Cmp < 0;
+  return std::tie(L.Start, L.End) < std::tie(R.Start, R.End);
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H
diff --git a/clangd/index/SymbolOrigin.cpp b/clangd/index/SymbolOrigin.cpp
new file mode 100644
index 0000000..e98308a
--- /dev/null
+++ b/clangd/index/SymbolOrigin.cpp
@@ -0,0 +1,25 @@
+//===--- SymbolOrigin.cpp ----------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolOrigin.h"
+
+namespace clang {
+namespace clangd {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) {
+  if (O == SymbolOrigin::Unknown)
+    return OS << "unknown";
+  constexpr static char Sigils[] = "ADSMI567";
+  for (unsigned I = 0; I < sizeof(Sigils); ++I)
+    if (static_cast<uint8_t>(O) & 1u << I)
+      OS << Sigils[I];
+  return OS;
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/index/SymbolOrigin.h b/clangd/index/SymbolOrigin.h
new file mode 100644
index 0000000..953f871
--- /dev/null
+++ b/clangd/index/SymbolOrigin.h
@@ -0,0 +1,48 @@
+//===--- SymbolOrigin.h ------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+namespace clang {
+namespace clangd {
+
+// Describes the source of information about a symbol.
+// Mainly useful for debugging, e.g. understanding code completion reuslts.
+// This is a bitfield as information can be combined from several sources.
+enum class SymbolOrigin : uint8_t {
+  Unknown = 0,
+  AST = 1 << 0,        // Directly from the AST (indexes should not set this).
+  Dynamic = 1 << 1,    // From the dynamic index of opened files.
+  Static = 1 << 2,     // From the static, externally-built index.
+  Merge = 1 << 3,      // A non-trivial index merge was performed.
+  Identifier = 1 << 4, // Raw identifiers in file.
+  // Remaining bits reserved for index implementations.
+};
+
+inline SymbolOrigin operator|(SymbolOrigin A, SymbolOrigin B) {
+  return static_cast<SymbolOrigin>(static_cast<uint8_t>(A) |
+                                   static_cast<uint8_t>(B));
+}
+inline SymbolOrigin &operator|=(SymbolOrigin &A, SymbolOrigin B) {
+  return A = A | B;
+}
+inline SymbolOrigin operator&(SymbolOrigin A, SymbolOrigin B) {
+  return static_cast<SymbolOrigin>(static_cast<uint8_t>(A) &
+                                   static_cast<uint8_t>(B));
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, SymbolOrigin);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H
diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp
index 7eb5b4c..6bf0cb7 100644
--- a/clangd/index/YAMLSerialization.cpp
+++ b/clangd/index/YAMLSerialization.cpp
@@ -1,9 +1,8 @@
-//===--- SymbolYAML.cpp ------------------------------------------*- C++-*-===//
+//===-- YAMLSerialization.cpp ------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -15,6 +14,8 @@
 
 #include "Index.h"
 #include "Serialization.h"
+#include "SymbolLocation.h"
+#include "SymbolOrigin.h"
 #include "Trace.h"
 #include "dex/Dex.h"
 #include "llvm/ADT/Optional.h"
@@ -192,6 +193,8 @@
     IO.mapOptional("Origin", NSymbolOrigin->Origin);
     IO.mapOptional("Flags", NSymbolFlag->Flag);
     IO.mapOptional("Signature", Sym.Signature);
+    IO.mapOptional("TemplateSpecializationArgs",
+                   Sym.TemplateSpecializationArgs);
     IO.mapOptional("CompletionSnippetSuffix", Sym.CompletionSnippetSuffix);
     IO.mapOptional("Documentation", Sym.Documentation);
     IO.mapOptional("ReturnType", Sym.ReturnType);
diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp
index c38706c..d767bb5 100644
--- a/clangd/index/dex/Dex.cpp
+++ b/clangd/index/dex/Dex.cpp
@@ -1,9 +1,8 @@
 //===--- Dex.cpp - Dex Symbol Index Implementation --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -43,7 +42,6 @@
 // Returns the tokens which are given symbols's characteristics. For example,
 // trigrams and scopes.
 // FIXME(kbobyrev): Support more token types:
-// * Types
 // * Namespace proximity
 std::vector<Token> generateSearchTokens(const Symbol &Sym) {
   std::vector<Token> Result = generateIdentifierTrigrams(Sym.Name);
@@ -55,49 +53,11 @@
       Result.emplace_back(Token::Kind::ProximityURI, ProximityURI);
   if (Sym.Flags & Symbol::IndexedForCodeCompletion)
     Result.emplace_back(RestrictedForCodeCompletion);
+  if (!Sym.Type.empty())
+    Result.emplace_back(Token::Kind::Type, Sym.Type);
   return Result;
 }
 
-// Constructs BOOST iterators for Path Proximities.
-std::unique_ptr<Iterator> createFileProximityIterator(
-    llvm::ArrayRef<std::string> ProximityPaths,
-    const llvm::DenseMap<Token, PostingList> &InvertedIndex,
-    const Corpus &Corpus) {
-  std::vector<std::unique_ptr<Iterator>> BoostingIterators;
-  // Deduplicate parent URIs extracted from the ProximityPaths.
-  llvm::StringSet<> ParentURIs;
-  llvm::StringMap<SourceParams> Sources;
-  for (const auto &Path : ProximityPaths) {
-    Sources[Path] = SourceParams();
-    auto PathURI = URI::create(Path);
-    const auto PathProximityURIs = generateProximityURIs(PathURI.toString());
-    for (const auto &ProximityURI : PathProximityURIs)
-      ParentURIs.insert(ProximityURI);
-  }
-  // Use SymbolRelevanceSignals for symbol relevance evaluation: use defaults
-  // for all parameters except for Proximity Path distance signal.
-  SymbolRelevanceSignals PathProximitySignals;
-  // DistanceCalculator will find the shortest distance from ProximityPaths to
-  // any URI extracted from the ProximityPaths.
-  URIDistance DistanceCalculator(Sources);
-  PathProximitySignals.FileProximityMatch = &DistanceCalculator;
-  // Try to build BOOST iterator for each Proximity Path provided by
-  // ProximityPaths. Boosting factor should depend on the distance to the
-  // Proximity Path: the closer processed path is, the higher boosting factor.
-  for (const auto &ParentURI : ParentURIs.keys()) {
-    Token Tok(Token::Kind::ProximityURI, ParentURI);
-    const auto It = InvertedIndex.find(Tok);
-    if (It != InvertedIndex.end()) {
-      // FIXME(kbobyrev): Append LIMIT on top of every BOOST iterator.
-      PathProximitySignals.SymbolURI = ParentURI;
-      BoostingIterators.push_back(Corpus.boost(
-          It->second.iterator(&It->first), PathProximitySignals.evaluate()));
-    }
-  }
-  BoostingIterators.push_back(Corpus.all());
-  return Corpus.unionOf(std::move(BoostingIterators));
-}
-
 } // namespace
 
 void Dex::buildIndex() {
@@ -142,6 +102,57 @@
                                    : It->second.iterator(&It->first);
 }
 
+// Constructs BOOST iterators for Path Proximities.
+std::unique_ptr<Iterator> Dex::createFileProximityIterator(
+    llvm::ArrayRef<std::string> ProximityPaths) const {
+  std::vector<std::unique_ptr<Iterator>> BoostingIterators;
+  // Deduplicate parent URIs extracted from the ProximityPaths.
+  llvm::StringSet<> ParentURIs;
+  llvm::StringMap<SourceParams> Sources;
+  for (const auto &Path : ProximityPaths) {
+    Sources[Path] = SourceParams();
+    auto PathURI = URI::create(Path);
+    const auto PathProximityURIs = generateProximityURIs(PathURI.toString());
+    for (const auto &ProximityURI : PathProximityURIs)
+      ParentURIs.insert(ProximityURI);
+  }
+  // Use SymbolRelevanceSignals for symbol relevance evaluation: use defaults
+  // for all parameters except for Proximity Path distance signal.
+  SymbolRelevanceSignals PathProximitySignals;
+  // DistanceCalculator will find the shortest distance from ProximityPaths to
+  // any URI extracted from the ProximityPaths.
+  URIDistance DistanceCalculator(Sources);
+  PathProximitySignals.FileProximityMatch = &DistanceCalculator;
+  // Try to build BOOST iterator for each Proximity Path provided by
+  // ProximityPaths. Boosting factor should depend on the distance to the
+  // Proximity Path: the closer processed path is, the higher boosting factor.
+  for (const auto &ParentURI : ParentURIs.keys()) {
+    // FIXME(kbobyrev): Append LIMIT on top of every BOOST iterator.
+    auto It = iterator(Token(Token::Kind::ProximityURI, ParentURI));
+    if (It->kind() != Iterator::Kind::False) {
+      PathProximitySignals.SymbolURI = ParentURI;
+      BoostingIterators.push_back(
+          Corpus.boost(std::move(It), PathProximitySignals.evaluate()));
+    }
+  }
+  BoostingIterators.push_back(Corpus.all());
+  return Corpus.unionOf(std::move(BoostingIterators));
+}
+
+// Constructs BOOST iterators for preferred types.
+std::unique_ptr<Iterator>
+Dex::createTypeBoostingIterator(llvm::ArrayRef<std::string> Types) const {
+  std::vector<std::unique_ptr<Iterator>> BoostingIterators;
+  SymbolRelevanceSignals PreferredTypeSignals;
+  PreferredTypeSignals.TypeMatchesPreferred = true;
+  auto Boost = PreferredTypeSignals.evaluate();
+  for (const auto &T : Types)
+    BoostingIterators.push_back(
+        Corpus.boost(iterator(Token(Token::Kind::Type, T)), Boost));
+  BoostingIterators.push_back(Corpus.all());
+  return Corpus.unionOf(std::move(BoostingIterators));
+}
+
 /// Constructs iterators over tokens extracted from the query and exhausts it
 /// while applying Callback to each symbol in the order of decreasing quality
 /// of the matched symbols.
@@ -175,8 +186,9 @@
   Criteria.push_back(Corpus.unionOf(move(ScopeIterators)));
 
   // Add proximity paths boosting (all symbols, some boosted).
-  Criteria.push_back(
-      createFileProximityIterator(Req.ProximityPaths, InvertedIndex, Corpus));
+  Criteria.push_back(createFileProximityIterator(Req.ProximityPaths));
+  // Add boosting for preferred types.
+  Criteria.push_back(createTypeBoostingIterator(Req.PreferredTypes));
 
   if (Req.RestrictForCodeCompletion)
     Criteria.push_back(iterator(RestrictedForCodeCompletion));
diff --git a/clangd/index/dex/Dex.h b/clangd/index/dex/Dex.h
index c790e41..fb80ca0 100644
--- a/clangd/index/dex/Dex.h
+++ b/clangd/index/dex/Dex.h
@@ -1,9 +1,8 @@
 //===--- Dex.h - Dex Symbol Index Implementation ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -78,6 +77,10 @@
 private:
   void buildIndex();
   std::unique_ptr<Iterator> iterator(const Token &Tok) const;
+  std::unique_ptr<Iterator>
+  createFileProximityIterator(llvm::ArrayRef<std::string> ProximityPaths) const;
+  std::unique_ptr<Iterator>
+  createTypeBoostingIterator(llvm::ArrayRef<std::string> Types) const;
 
   /// Stores symbols sorted in the descending order of symbol quality..
   std::vector<const Symbol *> Symbols;
diff --git a/clangd/index/dex/Iterator.cpp b/clangd/index/dex/Iterator.cpp
index 0b132b9..cb294a3 100644
--- a/clangd/index/dex/Iterator.cpp
+++ b/clangd/index/dex/Iterator.cpp
@@ -1,9 +1,8 @@
 //===--- Iterator.cpp - Query Symbol Retrieval ------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/dex/Iterator.h b/clangd/index/dex/Iterator.h
index 149fd43..34b42c3 100644
--- a/clangd/index/dex/Iterator.h
+++ b/clangd/index/dex/Iterator.h
@@ -1,9 +1,8 @@
 //===--- Iterator.h - Query Symbol Retrieval --------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clangd/index/dex/PostingList.cpp b/clangd/index/dex/PostingList.cpp
index eb2e475..67ed070 100644
--- a/clangd/index/dex/PostingList.cpp
+++ b/clangd/index/dex/PostingList.cpp
@@ -1,15 +1,15 @@
 //===--- PostingList.cpp - Symbol identifiers storage interface -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "PostingList.h"
 #include "Iterator.h"
 #include "Token.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MathExtras.h"
 
@@ -50,7 +50,8 @@
       return;
     advanceToChunk(ID);
     // Try to find ID within current chunk.
-    CurrentID = std::lower_bound(CurrentID, std::end(DecompressedChunk), ID);
+    CurrentID = llvm::bsearch(CurrentID, DecompressedChunk.end(),
+                              [&](const DocID D) { return D >= ID; });
     normalizeCursor();
   }
 
@@ -101,10 +102,9 @@
   void advanceToChunk(DocID ID) {
     if ((CurrentChunk != Chunks.end() - 1) &&
         ((CurrentChunk + 1)->Head <= ID)) {
-      // Find the next chunk with Head >= ID.
-      CurrentChunk = std::lower_bound(
-          CurrentChunk + 1, Chunks.end(), ID,
-          [](const Chunk &C, const DocID ID) { return C.Head <= ID; });
+      CurrentChunk =
+          llvm::bsearch(CurrentChunk + 1, Chunks.end(),
+                        [&](const Chunk &C) { return C.Head >= ID; });
       --CurrentChunk;
       DecompressedChunk = CurrentChunk->decompress();
       CurrentID = DecompressedChunk.begin();
diff --git a/clangd/index/dex/PostingList.h b/clangd/index/dex/PostingList.h
index 81ba64c..418e4c7 100644
--- a/clangd/index/dex/PostingList.h
+++ b/clangd/index/dex/PostingList.h
@@ -1,9 +1,8 @@
 //===--- PostingList.h - Symbol identifiers storage interface  --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clangd/index/dex/Token.h b/clangd/index/dex/Token.h
index f80d925..37859bc 100644
--- a/clangd/index/dex/Token.h
+++ b/clangd/index/dex/Token.h
@@ -1,9 +1,8 @@
 //===--- Token.h - Symbol Search primitive ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -63,11 +62,11 @@
     /// Example: "file:///path/to/clang-tools-extra/clangd/index/SymbolIndex.h"
     /// and some amount of its parents.
     ProximityURI,
+    /// Type of symbol (see `Symbol::Type`).
+    Type,
     /// Internal Token type for invalid/special tokens, e.g. empty tokens for
     /// llvm::DenseMap.
     Sentinel,
-    /// FIXME(kbobyrev): Add other Token Kinds
-    /// * Type with qualified type name or its USR
   };
 
   Token(Kind TokenKind, llvm::StringRef Data)
@@ -92,6 +91,9 @@
     case Kind::ProximityURI:
       OS << "U=";
       break;
+    case Kind::Type:
+      OS << "Ty=";
+      break;
     case Kind::Sentinel:
       OS << "?=";
       break;
diff --git a/clangd/index/dex/Trigram.cpp b/clangd/index/dex/Trigram.cpp
index 2ba0ad1..24ae72b 100644
--- a/clangd/index/dex/Trigram.cpp
+++ b/clangd/index/dex/Trigram.cpp
@@ -1,9 +1,8 @@
 //===--- Trigram.cpp - Trigram generation for Fuzzy Matching ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/dex/Trigram.h b/clangd/index/dex/Trigram.h
index adce9f4..bf1e5e8 100644
--- a/clangd/index/dex/Trigram.h
+++ b/clangd/index/dex/Trigram.h
@@ -1,9 +1,8 @@
 //===--- Trigram.h - Trigram generation for Fuzzy Matching ------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clangd/index/dex/dexp/Dexp.cpp b/clangd/index/dex/dexp/Dexp.cpp
index 5a0b6d9..820dc66 100644
--- a/clangd/index/dex/dexp/Dexp.cpp
+++ b/clangd/index/dex/dexp/Dexp.cpp
@@ -1,9 +1,8 @@
 //===--- Dexp.cpp - Dex EXPloration tool ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/indexer/CMakeLists.txt b/clangd/indexer/CMakeLists.txt
index 5ba5b67..92aae06 100644
--- a/clangd/indexer/CMakeLists.txt
+++ b/clangd/indexer/CMakeLists.txt
@@ -11,10 +11,10 @@
 target_link_libraries(clangd-indexer
   PRIVATE
   clangAST
-  clangIndex
-  clangDaemon
   clangBasic
+  clangDaemon
   clangFrontend
+  clangIndex
   clangLex
   clangTooling
 )
diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp
index 18e6304..d012825 100644
--- a/clangd/indexer/IndexerMain.cpp
+++ b/clangd/indexer/IndexerMain.cpp
@@ -1,9 +1,8 @@
 //===--- IndexerMain.cpp -----------------------------------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -11,11 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "index/Index.h"
 #include "index/IndexAction.h"
 #include "index/Merge.h"
+#include "index/Ref.h"
 #include "index/Serialization.h"
+#include "index/Symbol.h"
 #include "index/SymbolCollector.h"
+#include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Execution.h"
 #include "clang/Tooling/Tooling.h"
@@ -55,7 +56,7 @@
                [&](RefSlab S) {
                  std::lock_guard<std::mutex> Lock(SymbolsMu);
                  for (const auto &Sym : S) {
-                   // No need to merge as currently all Refs are from main file.
+                   // Deduplication happens during insertion.
                    for (const auto &Ref : Sym.second)
                      Refs.insert(Sym.first, Ref);
                  }
@@ -110,7 +111,8 @@
   // Collect symbols found in each translation unit, merging as we go.
   clang::clangd::IndexFileIn Data;
   auto Err = Executor->get()->execute(
-      llvm::make_unique<clang::clangd::IndexActionFactory>(Data));
+      llvm::make_unique<clang::clangd::IndexActionFactory>(Data),
+      clang::tooling::getStripPluginsAdjuster());
   if (Err) {
     llvm::errs() << llvm::toString(std::move(Err)) << "\n";
   }
diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp
new file mode 100644
index 0000000..34634e6
--- /dev/null
+++ b/clangd/refactor/Tweak.cpp
@@ -0,0 +1,82 @@
+//===--- Tweak.cpp -----------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "Tweak.h"
+#include "Logger.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Registry.h"
+#include <functional>
+#include <memory>
+
+LLVM_INSTANTIATE_REGISTRY(llvm::Registry<clang::clangd::Tweak>)
+
+namespace clang {
+namespace clangd {
+
+/// A handy typedef to save some typing.
+typedef llvm::Registry<Tweak> TweakRegistry;
+
+namespace {
+/// Asserts invariants on TweakRegistry. No-op with assertion disabled.
+void validateRegistry() {
+#ifndef NDEBUG
+  llvm::StringSet<> Seen;
+  for (const auto &E : TweakRegistry::entries()) {
+    // REGISTER_TWEAK ensures E.getName() is equal to the tweak class name.
+    // We check that id() matches it.
+    assert(E.instantiate()->id() == E.getName() &&
+           "id should be equal to class name");
+    assert(Seen.try_emplace(E.getName()).second && "duplicate check id");
+  }
+#endif
+}
+} // namespace
+
+Tweak::Selection::Selection(ParsedAST &AST, unsigned RangeBegin,
+                            unsigned RangeEnd)
+    : AST(AST), ASTSelection(AST.getASTContext(), RangeBegin, RangeEnd) {
+  auto &SM = AST.getASTContext().getSourceManager();
+  Code = SM.getBufferData(SM.getMainFileID());
+  Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin);
+}
+
+std::vector<std::unique_ptr<Tweak>> prepareTweaks(const Tweak::Selection &S) {
+  validateRegistry();
+
+  std::vector<std::unique_ptr<Tweak>> Available;
+  for (const auto &E : TweakRegistry::entries()) {
+    std::unique_ptr<Tweak> T = E.instantiate();
+    if (!T->prepare(S))
+      continue;
+    Available.push_back(std::move(T));
+  }
+  // Ensure deterministic order of the results.
+  llvm::sort(Available,
+             [](const std::unique_ptr<Tweak> &L,
+                const std::unique_ptr<Tweak> &R) { return L->id() < R->id(); });
+  return Available;
+}
+
+llvm::Expected<std::unique_ptr<Tweak>> prepareTweak(StringRef ID,
+                                                    const Tweak::Selection &S) {
+  auto It = llvm::find_if(
+      TweakRegistry::entries(),
+      [ID](const TweakRegistry::entry &E) { return E.getName() == ID; });
+  if (It == TweakRegistry::end())
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "id of the tweak is invalid");
+  std::unique_ptr<Tweak> T = It->instantiate();
+  if (!T->prepare(S))
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "failed to prepare() a check");
+  return std::move(T);
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h
new file mode 100644
index 0000000..35c3ce8
--- /dev/null
+++ b/clangd/refactor/Tweak.h
@@ -0,0 +1,94 @@
+//===--- Tweak.h -------------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Tweaks are small refactoring-like actions that run over the AST and produce
+// the set of edits as a result. They are local, i.e. they should take the
+// current editor context, e.g. the cursor position and selection into account.
+// The actions are executed in two stages:
+//   - Stage 1 should check whether the action is available in a current
+//     context. It should be cheap and fast to compute as it is executed for all
+//     available actions on every client request, which happen quite frequently.
+//   - Stage 2 is performed after stage 1 and can be more expensive to compute.
+//     It is performed when the user actually chooses the action.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H
+
+#include "ClangdUnit.h"
+#include "Protocol.h"
+#include "Selection.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+namespace clang {
+namespace clangd {
+
+/// An interface base for small context-sensitive refactoring actions.
+/// To implement a new tweak use the following pattern in a .cpp file:
+///   class MyTweak : public Tweak {
+///   public:
+///     const char* id() const override final; // defined by REGISTER_TWEAK.
+///     // implement other methods here.
+///   };
+///   REGISTER_TWEAK(MyTweak);
+class Tweak {
+public:
+  /// Input to prepare and apply tweaks.
+  struct Selection {
+    Selection(ParsedAST &AST, unsigned RangeBegin, unsigned RangeEnd);
+    /// The text of the active document.
+    llvm::StringRef Code;
+    /// Parsed AST of the active file.
+    ParsedAST &AST;
+    /// A location of the cursor in the editor.
+    SourceLocation Cursor;
+    // The AST nodes that were selected.
+    SelectionTree ASTSelection;
+    // FIXME: provide a way to get sources and ASTs for other files.
+  };
+  virtual ~Tweak() = default;
+  /// A unique id of the action, it is always equal to the name of the class
+  /// defining the Tweak. Definition is provided automatically by
+  /// REGISTER_TWEAK.
+  virtual const char *id() const = 0;
+  /// Run the first stage of the action. Returns true indicating that the
+  /// action is available and should be shown to the user. Returns false if the
+  /// action is not available.
+  /// This function should be fast, if the action requires non-trivial work it
+  /// should be moved into 'apply'.
+  /// Returns true iff the action is available and apply() can be called on it.
+  virtual bool prepare(const Selection &Sel) = 0;
+  /// Run the second stage of the action that would produce the actual changes.
+  /// EXPECTS: prepare() was called and returned true.
+  virtual Expected<tooling::Replacements> apply(const Selection &Sel) = 0;
+  /// A one-line title of the action that should be shown to the users in the
+  /// UI.
+  /// EXPECTS: prepare() was called and returned true.
+  virtual std::string title() const = 0;
+};
+
+// All tweaks must be registered in the .cpp file next to their definition.
+#define REGISTER_TWEAK(Subclass)                                               \
+  ::llvm::Registry<::clang::clangd::Tweak>::Add<Subclass>                      \
+      TweakRegistrationFor##Subclass(#Subclass, /*Description=*/"");           \
+  const char *Subclass::id() const { return #Subclass; }
+
+/// Calls prepare() on all tweaks, returning those that can run on the
+/// selection.
+std::vector<std::unique_ptr<Tweak>> prepareTweaks(const Tweak::Selection &S);
+
+// Calls prepare() on the tweak with a given ID.
+// If prepare() returns false, returns an error.
+// If prepare() returns true, returns the corresponding tweak.
+llvm::Expected<std::unique_ptr<Tweak>> prepareTweak(StringRef TweakID,
+                                                    const Tweak::Selection &S);
+
+} // namespace clangd
+} // namespace clang
+
+#endif
diff --git a/clangd/refactor/tweaks/CMakeLists.txt b/clangd/refactor/tweaks/CMakeLists.txt
new file mode 100644
index 0000000..35528d8
--- /dev/null
+++ b/clangd/refactor/tweaks/CMakeLists.txt
@@ -0,0 +1,21 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+set(LLVM_LINK_COMPONENTS
+  support
+  )
+
+# A target containing all code tweaks (i.e. mini-refactorings) provided by
+# clangd.
+# Built as an object library to make sure the linker does not remove global
+# constructors that register individual tweaks in a global registry.
+# To enable these tweaks in executables or shared libraries, add
+# $<TARGET_OBJECTS:obj.clangDaemonTweaks> to a list of sources, see
+# clangd/tool/CMakeLists.txt for an example.
+add_clang_library(clangDaemonTweaks OBJECT
+  SwapIfBranches.cpp
+
+  LINK_LIBS
+  clangAST
+  clangDaemon
+  clangToolingCore
+  )
diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp
new file mode 100644
index 0000000..9b0b72d
--- /dev/null
+++ b/clangd/refactor/tweaks/SwapIfBranches.cpp
@@ -0,0 +1,99 @@
+//===--- SwapIfBranches.cpp --------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "ClangdUnit.h"
+#include "Logger.h"
+#include "SourceCode.h"
+#include "refactor/Tweak.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+/// Swaps the 'then' and 'else' branch of the if statement.
+/// Before:
+///   if (foo) { return 10; } else { continue; }
+///   ^^^^^^^                 ^^^^
+/// After:
+///   if (foo) { continue; } else { return 10; }
+class SwapIfBranches : public Tweak {
+public:
+  const char *id() const override final;
+
+  bool prepare(const Selection &Inputs) override;
+  Expected<tooling::Replacements> apply(const Selection &Inputs) override;
+  std::string title() const override;
+
+private:
+  const IfStmt *If = nullptr;
+};
+
+REGISTER_TWEAK(SwapIfBranches)
+
+bool SwapIfBranches::prepare(const Selection &Inputs) {
+  for (const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor();
+       N && !If; N = N->Parent) {
+    // Stop once we hit a block, e.g. a lambda in the if condition.
+    if (dyn_cast_or_null<CompoundStmt>(N->ASTNode.get<Stmt>()))
+      return false;
+    If = dyn_cast_or_null<IfStmt>(N->ASTNode.get<Stmt>());
+  }
+  // avoid dealing with single-statement brances, they require careful handling
+  // to avoid changing semantics of the code (i.e. dangling else).
+  return If && dyn_cast_or_null<CompoundStmt>(If->getThen()) &&
+         dyn_cast_or_null<CompoundStmt>(If->getElse());
+}
+
+Expected<tooling::Replacements> SwapIfBranches::apply(const Selection &Inputs) {
+  auto &Ctx = Inputs.AST.getASTContext();
+  auto &SrcMgr = Ctx.getSourceManager();
+
+  auto ThenRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
+                                     If->getThen()->getSourceRange());
+  if (!ThenRng)
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "Could not obtain range of the 'then' branch. Macros?");
+  auto ElseRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
+                                     If->getElse()->getSourceRange());
+  if (!ElseRng)
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "Could not obtain range of the 'else' branch. Macros?");
+
+  auto ThenCode = toSourceCode(SrcMgr, *ThenRng);
+  auto ElseCode = toSourceCode(SrcMgr, *ElseRng);
+
+  tooling::Replacements Result;
+  if (auto Err = Result.add(tooling::Replacement(Ctx.getSourceManager(),
+                                                 ThenRng->getBegin(),
+                                                 ThenCode.size(), ElseCode)))
+    return std::move(Err);
+  if (auto Err = Result.add(tooling::Replacement(Ctx.getSourceManager(),
+                                                 ElseRng->getBegin(),
+                                                 ElseCode.size(), ThenCode)))
+    return std::move(Err);
+  return Result;
+}
+
+std::string SwapIfBranches::title() const { return "Swap if branches"; }
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/test/CMakeLists.txt b/clangd/test/CMakeLists.txt
new file mode 100644
index 0000000..bbb582f
--- /dev/null
+++ b/clangd/test/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Set CLANG_TOOLS_DIR to buildtree/bin, or buildtree/%(build_mode)s/bin if the
+# location is dynamic. The latter must be interpolated by lit configs.
+# FIXME: this is duplicated in many places.
+if (CMAKE_CFG_INTDIR STREQUAL ".")
+  set(LLVM_BUILD_MODE ".")
+else ()
+  set(LLVM_BUILD_MODE "%(build_mode)s")
+endif ()
+string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
+
+set(CLANGD_TEST_DEPS
+  clangd
+  ClangdTests
+  # No tests for these, but we should still make sure they build.
+  clangd-indexer
+  dexp
+  )
+
+if(CLANGD_BUILD_XPC)
+  list(APPEND CLANGD_TEST_DEPS clangd-xpc-test-client)
+  list(APPEND CLANGD_TEST_DEPS ClangdXpcUnitTests)
+endif()
+
+foreach(dep FileCheck count not)
+  if(TARGET ${dep})
+    list(APPEND CLANGD_TEST_DEPS ${dep})
+  endif()
+endforeach()
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
+
+add_lit_testsuite(check-clangd "Running the Clangd regression tests"
+  ${CMAKE_CURRENT_BINARY_DIR}/../unittests;${CMAKE_CURRENT_BINARY_DIR}
+  DEPENDS ${CLANGD_TEST_DEPS})
diff --git a/test/clangd/Inputs/BenchmarkHeader.h b/clangd/test/Inputs/BenchmarkHeader.h
similarity index 100%
rename from test/clangd/Inputs/BenchmarkHeader.h
rename to clangd/test/Inputs/BenchmarkHeader.h
diff --git a/test/clangd/Inputs/BenchmarkSource.cpp b/clangd/test/Inputs/BenchmarkSource.cpp
similarity index 100%
rename from test/clangd/Inputs/BenchmarkSource.cpp
rename to clangd/test/Inputs/BenchmarkSource.cpp
diff --git a/test/clangd/Inputs/background-index/compile_commands.json b/clangd/test/Inputs/background-index/compile_commands.json
similarity index 100%
rename from test/clangd/Inputs/background-index/compile_commands.json
rename to clangd/test/Inputs/background-index/compile_commands.json
diff --git a/test/clangd/Inputs/background-index/definition.jsonrpc b/clangd/test/Inputs/background-index/definition.jsonrpc
similarity index 94%
rename from test/clangd/Inputs/background-index/definition.jsonrpc
rename to clangd/test/Inputs/background-index/definition.jsonrpc
index 89d5048..933e779 100644
--- a/test/clangd/Inputs/background-index/definition.jsonrpc
+++ b/clangd/test/Inputs/background-index/definition.jsonrpc
@@ -44,7 +44,7 @@
     }
   }
 }
-# CHECK: "uri": "file://DIRECTORY/foo.cpp"
+# CHECK: "uri": "file://{{.*}}/foo.cpp"
 ---
 {"jsonrpc":"2.0","id":3,"method":"shutdown"}
 ---
diff --git a/test/clangd/Inputs/background-index/foo.cpp b/clangd/test/Inputs/background-index/foo.cpp
similarity index 100%
rename from test/clangd/Inputs/background-index/foo.cpp
rename to clangd/test/Inputs/background-index/foo.cpp
diff --git a/test/clangd/Inputs/background-index/foo.h b/clangd/test/Inputs/background-index/foo.h
similarity index 100%
rename from test/clangd/Inputs/background-index/foo.h
rename to clangd/test/Inputs/background-index/foo.h
diff --git a/test/clangd/Inputs/requests.json b/clangd/test/Inputs/requests.json
similarity index 100%
rename from test/clangd/Inputs/requests.json
rename to clangd/test/Inputs/requests.json
diff --git a/test/clangd/Inputs/symbols.test.yaml b/clangd/test/Inputs/symbols.test.yaml
similarity index 100%
rename from test/clangd/Inputs/symbols.test.yaml
rename to clangd/test/Inputs/symbols.test.yaml
diff --git a/test/clangd/background-index.test b/clangd/test/background-index.test
similarity index 95%
rename from test/clangd/background-index.test
rename to clangd/test/background-index.test
index 34c419a..1d11736 100644
--- a/test/clangd/background-index.test
+++ b/clangd/test/background-index.test
@@ -13,7 +13,7 @@
 # RUN: clangd -background-index -background-index-rebuild-period=0 -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc
 
 # Test that the index is writing files in the expected location.
-# RUN: ls %t/.clangd-index/foo.cpp.*.idx
+# RUN: ls %t/.clangd/index/foo.cpp.*.idx
 
 # Test the index is read from disk: delete code and restart clangd.
 # RUN: rm %t/foo.cpp
diff --git a/test/clangd/compile-commands-path-in-initialize.test b/clangd/test/compile-commands-path-in-initialize.test
similarity index 96%
rename from test/clangd/compile-commands-path-in-initialize.test
rename to clangd/test/compile-commands-path-in-initialize.test
index 87086e3..2905bad 100644
--- a/test/clangd/compile-commands-path-in-initialize.test
+++ b/clangd/test/compile-commands-path-in-initialize.test
@@ -21,6 +21,7 @@
 # CHECK-NEXT:   "params": {
 # CHECK-NEXT:     "diagnostics": [
 # CHECK-NEXT:       {
+# CHECK-NEXT:         "code": "-W#pragma-messages",
 # CHECK-NEXT:         "message": "MACRO is one",
 ---
 {"jsonrpc":"2.0","id":10000,"method":"shutdown"}
diff --git a/test/clangd/completion-auto-trigger.test b/clangd/test/completion-auto-trigger.test
similarity index 95%
rename from test/clangd/completion-auto-trigger.test
rename to clangd/test/completion-auto-trigger.test
index db3cc53..9683028 100644
--- a/test/clangd/completion-auto-trigger.test
+++ b/clangd/test/completion-auto-trigger.test
@@ -23,7 +23,7 @@
 # CHECK-NEXT:        "insertTextFormat": 1,
 # CHECK-NEXT:        "kind": 5,
 # CHECK-NEXT:        "label": " size",
-# CHECK-NEXT:        "sortText": "3eacccccsize",
+# CHECK-NEXT:        "sortText": "{{.*}}size",
 # CHECK-NEXT:        "textEdit": {
 # CHECK-NEXT:          "newText": "size",
 # CHECK-NEXT:          "range": {
@@ -45,7 +45,7 @@
 # CHECK-NEXT:         "insertTextFormat": 1,
 # CHECK-NEXT:         "kind": 10,
 # CHECK-NEXT:         "label": " default_capacity",
-# CHECK-NEXT:         "sortText": "3fd70a3ddefault_capacity",
+# CHECK-NEXT:         "sortText": "{{.*}}default_capacity",
 # CHECK-NEXT:         "textEdit": {
 # CHECK-NEXT:           "newText": "default_capacity",
 # CHECK-NEXT:           "range": {
@@ -84,7 +84,7 @@
 # CHECK-NEXT:        "insertTextFormat": 1,
 # CHECK-NEXT:        "kind": 6,
 # CHECK-NEXT:        "label": " ns_member",
-# CHECK-NEXT:        "sortText": "3f2cccccns_member",
+# CHECK-NEXT:        "sortText": "{{.*}}ns_member",
 # CHECK-NEXT:        "textEdit": {
 # CHECK-NEXT:          "newText": "ns_member",
 # CHECK-NEXT:          "range": {
diff --git a/test/clangd/completion-snippets.test b/clangd/test/completion-snippets.test
similarity index 100%
rename from test/clangd/completion-snippets.test
rename to clangd/test/completion-snippets.test
diff --git a/test/clangd/completion.test b/clangd/test/completion.test
similarity index 100%
rename from test/clangd/completion.test
rename to clangd/test/completion.test
diff --git a/test/clangd/crash-non-added-files.test b/clangd/test/crash-non-added-files.test
similarity index 100%
rename from test/clangd/crash-non-added-files.test
rename to clangd/test/crash-non-added-files.test
diff --git a/test/clangd/delimited-input-comment-at-the-end.test b/clangd/test/delimited-input-comment-at-the-end.test
similarity index 100%
rename from test/clangd/delimited-input-comment-at-the-end.test
rename to clangd/test/delimited-input-comment-at-the-end.test
diff --git a/test/clangd/diagnostic-category.test b/clangd/test/diagnostic-category.test
similarity index 88%
rename from test/clangd/diagnostic-category.test
rename to clangd/test/diagnostic-category.test
index 440afbb..3946774 100644
--- a/test/clangd/diagnostic-category.test
+++ b/clangd/test/diagnostic-category.test
@@ -7,7 +7,8 @@
 # CHECK-NEXT:     "diagnostics": [
 # CHECK-NEXT:      {
 # CHECK-NEXT:        "category": "Semantic Issue",
-# CHECK-NEXT:        "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here",
+# CHECK-NEXT:        "code": "use_with_wrong_tag",
+# CHECK-NEXT:        "message": "Use of 'Point' with tag type that does not match previous declaration (fix available)\n\nfoo.c:1:8: note: previous use is here",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 22,
@@ -18,7 +19,8 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 1
+# CHECK-NEXT:        "severity": 1,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      },
 # CHECK-NEXT:      {
 # CHECK-NEXT:        "message": "Previous use is here\n\nfoo.c:1:18: error: use of 'Point' with tag type that does not match previous declaration",
diff --git a/clangd/test/diagnostics-notes.test b/clangd/test/diagnostics-notes.test
new file mode 100644
index 0000000..c04c5cf
--- /dev/null
+++ b/clangd/test/diagnostics-notes.test
@@ -0,0 +1,48 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"textDocument":{"publishDiagnostics":{"relatedInformation":true}}},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cc","languageId":"cpp","version":1,"text":"int x;\nint x;"}}}
+#      CHECK:  "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT:  "params": {
+# CHECK-NEXT:    "diagnostics": [
+# CHECK-NEXT:      {
+# CHECK-NEXT:        "code": "redefinition",
+# CHECK-NEXT:        "message": "Redefinition of 'x'",
+# CHECK-NEXT:        "range": {
+# CHECK-NEXT:          "end": {
+# CHECK-NEXT:            "character": 5,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          },
+# CHECK-NEXT:          "start": {
+# CHECK-NEXT:            "character": 4,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          }
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "relatedInformation": [
+# CHECK-NEXT:          {
+# CHECK-NEXT:            "location": {
+# CHECK-NEXT:              "range": {
+# CHECK-NEXT:                "end": {
+# CHECK-NEXT:                  "character": 5,
+# CHECK-NEXT:                  "line": 0
+# CHECK-NEXT:                },
+# CHECK-NEXT:                "start": {
+# CHECK-NEXT:                  "character": 4,
+# CHECK-NEXT:                  "line": 0
+# CHECK-NEXT:                }
+# CHECK-NEXT:              },
+# CHECK-NEXT:              "uri": "{{.*}}foo.cc"
+# CHECK-NEXT:            },
+# CHECK-NEXT:            "message": "Previous definition is here"
+# CHECK-NEXT:          }
+# CHECK-NEXT:        ],
+# CHECK-NEXT:        "severity": 1,
+# CHECK-NEXT:        "source": "clang"
+# CHECK-NEXT:      }
+# CHECK-NEXT:    ],
+# CHECK-NEXT:    "uri": "file://{{.*}}/foo.cc"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/clangd/test/diagnostics.test b/clangd/test/diagnostics.test
new file mode 100644
index 0000000..accfd17
--- /dev/null
+++ b/clangd/test/diagnostics.test
@@ -0,0 +1,55 @@
+# RUN: clangd -lit-test -clang-tidy-checks=bugprone-sizeof-expression < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {\n(void)sizeof(42);\n}"}}}
+#      CHECK:  "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT:  "params": {
+# CHECK-NEXT:    "diagnostics": [
+# CHECK-NEXT:      {
+# CHECK-NEXT:        "code": "-Wmain-return-type",
+# CHECK-NEXT:        "message": "Return type of 'main' is not 'int' (fix available)",
+# CHECK-NEXT:        "range": {
+# CHECK-NEXT:          "end": {
+# CHECK-NEXT:            "character": 4,
+# CHECK-NEXT:            "line": 0
+# CHECK-NEXT:          },
+# CHECK-NEXT:          "start": {
+# CHECK-NEXT:            "character": 0,
+# CHECK-NEXT:            "line": 0
+# CHECK-NEXT:          }
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "severity": 2,
+# CHECK-NEXT:        "source": "clang"
+# CHECK-NEXT:      },
+# CHECK-NEXT:      {
+# CHECK-NEXT:        "code": "bugprone-sizeof-expression",
+# CHECK-NEXT:        "message": "Suspicious usage of 'sizeof(K)'; did you mean 'K'?",
+# CHECK-NEXT:        "range": {
+# CHECK-NEXT:          "end": {
+# CHECK-NEXT:            "character": 12,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          },
+# CHECK-NEXT:          "start": {
+# CHECK-NEXT:            "character": 6,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          }
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "severity": 2,
+# CHECK-NEXT:        "source": "clang-tidy"
+# CHECK-NEXT:      }
+# CHECK-NEXT:    ],
+# CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":2,"method":"sync","params":null}
+---
+{"jsonrpc":"2.0","method":"textDocument/didClose","params":{"textDocument":{"uri":"test:///foo.c"}}}
+#      CHECK:  "method": "textDocument/publishDiagnostics",
+# CHECK-NEXT:  "params": {
+# CHECK-NEXT:    "diagnostics": [],
+# CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/did-change-configuration-params.test b/clangd/test/did-change-configuration-params.test
similarity index 89%
rename from test/clangd/did-change-configuration-params.test
rename to clangd/test/did-change-configuration-params.test
index 51b4a87..bd8ffaf 100644
--- a/test/clangd/did-change-configuration-params.test
+++ b/clangd/test/did-change-configuration-params.test
@@ -24,7 +24,8 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Variable 'i' is uninitialized when used here",
+# CHECK-NEXT:        "code": "-Wuninitialized",
+# CHECK-NEXT:        "message": "Variable 'i' is uninitialized when used here (fix available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 28,
@@ -35,13 +36,16 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 1
+# CHECK-NEXT:        "severity": 1,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      }
 # CHECK-NEXT:    ],
 # CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
 # CHECK-NEXT:  }
 #
-# ERR: Updating file {{.*}}foo.c with command [{{.*}}clangd-test2] clang -c foo.c -Wall -Werror
+# ERR: Updating file {{.*}}foo.c with command
+# ERR: [{{.*}}clangd-test2]
+# ERR: clang -c foo.c -Wall -Werror
 # Don't reparse the second file:
 # ERR: Skipping rebuild of the AST for {{.*}}bar.c
 ---
diff --git a/test/clangd/execute-command.test b/clangd/test/execute-command.test
similarity index 95%
rename from test/clangd/execute-command.test
rename to clangd/test/execute-command.test
index 85d4b9b..7abd79e 100644
--- a/test/clangd/execute-command.test
+++ b/clangd/test/execute-command.test
@@ -6,7 +6,8 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT:        "code": "-Wparentheses",
+# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses (fixes available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 37,
@@ -17,7 +18,8 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 2
+# CHECK-NEXT:        "severity": 2,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      }
 # CHECK-NEXT:    ],
 # CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
diff --git a/test/clangd/exit-with-shutdown.test b/clangd/test/exit-with-shutdown.test
similarity index 100%
rename from test/clangd/exit-with-shutdown.test
rename to clangd/test/exit-with-shutdown.test
diff --git a/test/clangd/exit-without-shutdown.test b/clangd/test/exit-without-shutdown.test
similarity index 100%
rename from test/clangd/exit-without-shutdown.test
rename to clangd/test/exit-without-shutdown.test
diff --git a/test/clangd/filestatus.test b/clangd/test/filestatus.test
similarity index 100%
rename from test/clangd/filestatus.test
rename to clangd/test/filestatus.test
diff --git a/test/clangd/fixits-codeaction.test b/clangd/test/fixits-codeaction.test
similarity index 83%
rename from test/clangd/fixits-codeaction.test
rename to clangd/test/fixits-codeaction.test
index 97dd4ff..e919071 100644
--- a/test/clangd/fixits-codeaction.test
+++ b/clangd/test/fixits-codeaction.test
@@ -6,7 +6,8 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT:        "code": "-Wparentheses",
+# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses (fixes available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 37,
@@ -17,20 +18,22 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 2
+# CHECK-NEXT:        "severity": 2,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      }
 # CHECK-NEXT:    ],
 # CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
 # CHECK-NEXT:  }
 ---
-{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)", "code": "-Wparentheses", "source": "clang"}]}}}
 #      CHECK:  "id": 2,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": [
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "diagnostics": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT:          "code": "-Wparentheses",
+# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses (fixes available)",
 # CHECK-NEXT:          "range": {
 # CHECK-NEXT:            "end": {
 # CHECK-NEXT:              "character": 37,
@@ -41,7 +44,8 @@
 # CHECK-NEXT:              "line": 0
 # CHECK-NEXT:            }
 # CHECK-NEXT:          },
-# CHECK-NEXT:          "severity": 2
+# CHECK-NEXT:          "severity": 2,
+# CHECK-NEXT:          "source": "clang"
 # CHECK-NEXT:        }
 # CHECK-NEXT:      ],
 # CHECK-NEXT:      "edit": {
@@ -82,7 +86,8 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "diagnostics": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT:          "code": "-Wparentheses",
+# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses (fixes available)",
 # CHECK-NEXT:          "range": {
 # CHECK-NEXT:            "end": {
 # CHECK-NEXT:              "character": 37,
@@ -93,7 +98,8 @@
 # CHECK-NEXT:              "line": 0
 # CHECK-NEXT:            }
 # CHECK-NEXT:          },
-# CHECK-NEXT:          "severity": 2
+# CHECK-NEXT:          "severity": 2,
+# CHECK-NEXT:          "source": "clang"
 # CHECK-NEXT:        }
 # CHECK-NEXT:      ],
 # CHECK-NEXT:      "edit": {
diff --git a/test/clangd/fixits-command.test b/clangd/test/fixits-command.test
similarity index 91%
rename from test/clangd/fixits-command.test
rename to clangd/test/fixits-command.test
index 67f70db..9d43e70 100644
--- a/test/clangd/fixits-command.test
+++ b/clangd/test/fixits-command.test
@@ -6,7 +6,8 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# CHECK-NEXT:        "code": "-Wparentheses",
+# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses (fixes available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 37,
@@ -17,13 +18,14 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 2
+# CHECK-NEXT:        "severity": 2,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      }
 # CHECK-NEXT:    ],
 # CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
 # CHECK-NEXT:  }
 ---
-{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)"}]}}}
 #      CHECK:  "id": 2,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": [
@@ -92,7 +94,7 @@
 # CHECK-NEXT:    }
 # CHECK-NEXT:  ]
 ---
-{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}}
+{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)"}]}}}
 # Make sure unused "code" and "source" fields ignored gracefully
 #      CHECK:  "id": 3,
 # CHECK-NEXT:  "jsonrpc": "2.0",
diff --git a/test/clangd/fixits-embed-in-diagnostic.test b/clangd/test/fixits-embed-in-diagnostic.test
similarity index 91%
rename from test/clangd/fixits-embed-in-diagnostic.test
rename to clangd/test/fixits-embed-in-diagnostic.test
index f1aa1cf..7d2cccd 100644
--- a/test/clangd/fixits-embed-in-diagnostic.test
+++ b/clangd/test/fixits-embed-in-diagnostic.test
@@ -6,6 +6,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
+# CHECK-NEXT:        "code": "use_with_wrong_tag",
 # CHECK-NEXT:        "codeActions": [
 # CHECK-NEXT:          {
 # CHECK-NEXT:            "edit": {
@@ -31,7 +32,7 @@
 # CHECK-NEXT:            "title": "change 'union' to 'struct'"
 # CHECK-NEXT:          }
 # CHECK-NEXT:        ],
-# CHECK-NEXT:        "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here",
+# CHECK-NEXT:        "message": "Use of 'Point' with tag type that does not match previous declaration (fix available)\n\nfoo.c:1:8: note: previous use is here",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 22,
@@ -42,7 +43,8 @@
 # CHECK-NEXT:            "line": 0
 # CHECK-NEXT:          }
 # CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 1
+# CHECK-NEXT:        "severity": 1,
+# CHECK-NEXT:        "source": "clang"
 # CHECK-NEXT:      },
 # CHECK-NEXT:      {
 # CHECK-NEXT:        "message": "Previous use is here\n\nfoo.c:1:18: error: use of 'Point' with tag type that does not match previous declaration",
diff --git a/test/clangd/formatting.test b/clangd/test/formatting.test
similarity index 100%
rename from test/clangd/formatting.test
rename to clangd/test/formatting.test
diff --git a/test/clangd/hover.test b/clangd/test/hover.test
similarity index 100%
rename from test/clangd/hover.test
rename to clangd/test/hover.test
diff --git a/test/clangd/index-tools.test b/clangd/test/index-tools.test
similarity index 100%
rename from test/clangd/index-tools.test
rename to clangd/test/index-tools.test
diff --git a/test/clangd/initialize-params-invalid.test b/clangd/test/initialize-params-invalid.test
similarity index 100%
rename from test/clangd/initialize-params-invalid.test
rename to clangd/test/initialize-params-invalid.test
diff --git a/test/clangd/initialize-params.test b/clangd/test/initialize-params.test
similarity index 90%
rename from test/clangd/initialize-params.test
rename to clangd/test/initialize-params.test
index 62f7b41..488539d 100644
--- a/test/clangd/initialize-params.test
+++ b/clangd/test/initialize-params.test
@@ -14,6 +14,7 @@
 # CHECK-NEXT:          ":"
 # CHECK-NEXT:        ]
 # CHECK-NEXT:      },
+# CHECK-NEXT:      "declarationProvider": true,
 # CHECK-NEXT:      "definitionProvider": true,
 # CHECK-NEXT:      "documentFormattingProvider": true,
 # CHECK-NEXT:      "documentHighlightProvider": true,
@@ -25,7 +26,8 @@
 # CHECK-NEXT:      "documentSymbolProvider": true,
 # CHECK-NEXT:      "executeCommandProvider": {
 # CHECK-NEXT:        "commands": [
-# CHECK-NEXT:          "clangd.applyFix"
+# CHECK-NEXT:          "clangd.applyFix",
+# CHECK-NEXT:          "clangd.applyTweak"
 # CHECK-NEXT:        ]
 # CHECK-NEXT:      },
 # CHECK-NEXT:      "hoverProvider": true,
@@ -38,6 +40,7 @@
 # CHECK-NEXT:        ]
 # CHECK-NEXT:      },
 # CHECK-NEXT:      "textDocumentSync": 2,
+# CHECK-NEXT:      "typeHierarchyProvider": true
 # CHECK-NEXT:      "workspaceSymbolProvider": true
 # CHECK-NEXT:    }
 # CHECK-NEXT:  }
diff --git a/test/clangd/initialize-sequence.test b/clangd/test/initialize-sequence.test
similarity index 100%
rename from test/clangd/initialize-sequence.test
rename to clangd/test/initialize-sequence.test
diff --git a/test/clangd/input-mirror.test b/clangd/test/input-mirror.test
similarity index 100%
rename from test/clangd/input-mirror.test
rename to clangd/test/input-mirror.test
diff --git a/clangd/test/lit.cfg.py b/clangd/test/lit.cfg.py
new file mode 100644
index 0000000..5030ca3
--- /dev/null
+++ b/clangd/test/lit.cfg.py
@@ -0,0 +1,19 @@
+import lit.llvm
+
+lit.llvm.initialize(lit_config, config)
+lit.llvm.llvm_config.use_clang()
+
+config.name = 'Clangd'
+config.suffixes = ['.test']
+config.excludes = ['Inputs']
+config.test_format = lit.formats.ShTest(not lit.llvm.llvm_config.use_lit_shell)
+config.test_source_root = config.clangd_source_dir + "/test"
+config.test_exec_root = config.clangd_binary_dir + "/test"
+
+# Clangd-specific lit environment.
+config.substitutions.append(('%clangd-benchmark-dir',
+                             config.clangd_binary_dir + "/benchmarks"))
+
+if config.clangd_build_xpc:
+  config.available_features.add('clangd-xpc-support')
+
diff --git a/test/clangd/lit.local.cfg b/clangd/test/lit.local.cfg
similarity index 100%
rename from test/clangd/lit.local.cfg
rename to clangd/test/lit.local.cfg
diff --git a/test/lit.site.cfg.in b/clangd/test/lit.site.cfg.py.in
similarity index 62%
copy from test/lit.site.cfg.in
copy to clangd/test/lit.site.cfg.py.in
index d71ca18..0a8301f 100644
--- a/test/lit.site.cfg.in
+++ b/clangd/test/lit.site.cfg.py.in
@@ -1,17 +1,13 @@
 @LIT_SITE_CFG_IN_HEADER@
 
-import sys
-
-config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
-config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+# Variables needed for common clang config.
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
-config.clang_tools_binary_dir = "@CLANG_TOOLS_BINARY_DIR@"
 config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
-config.clang_libs_dir = "@SHLIBDIR@"
-config.python_executable = "@PYTHON_EXECUTABLE@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.clang_libs_dir = "@CLANG_LIBS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
 config.target_triple = "@TARGET_TRIPLE@"
-config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
-config.clangd_xpc_support = @CLANGD_BUILD_XPC_SUPPORT@
+config.host_triple = "@LLVM_HOST_TRIPLE@"
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
@@ -24,8 +20,9 @@
     key, = e.args
     lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
 
-import lit.llvm
-lit.llvm.initialize(lit_config, config)
+config.clangd_source_dir = "@CMAKE_CURRENT_SOURCE_DIR@/.."
+config.clangd_binary_dir = "@CMAKE_CURRENT_BINARY_DIR@/.."
+config.clangd_build_xpc = @CLANGD_BUILD_XPC@
 
-# Let the main config do the real work.
-lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/lit.cfg")
+# Delegate logic to lit.cfg.py.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")
diff --git a/test/clangd/protocol.test b/clangd/test/protocol.test
similarity index 100%
rename from test/clangd/protocol.test
rename to clangd/test/protocol.test
diff --git a/test/clangd/references.test b/clangd/test/references.test
similarity index 100%
rename from test/clangd/references.test
rename to clangd/test/references.test
diff --git a/test/clangd/rename.test b/clangd/test/rename.test
similarity index 95%
rename from test/clangd/rename.test
rename to clangd/test/rename.test
index caf8b20..7c504bd 100644
--- a/test/clangd/rename.test
+++ b/clangd/test/rename.test
@@ -29,7 +29,7 @@
 {"jsonrpc":"2.0","id":2,"method":"textDocument/rename","params":{"textDocument":{"uri":"test:///foo.cpp"},"position":{"line":0,"character":2},"newName":"bar"}}
 #      CHECK:  "error": {
 # CHECK-NEXT:    "code": -32001,
-# CHECK-NEXT:    "message": "clang diagnostic"
+# CHECK-NEXT:    "message": "there is no symbol at the given location"
 # CHECK-NEXT:  },
 # CHECK-NEXT:  "id": 2,
 # CHECK-NEXT:  "jsonrpc": "2.0"
diff --git a/test/clangd/signature-help.test b/clangd/test/signature-help.test
similarity index 100%
rename from test/clangd/signature-help.test
rename to clangd/test/signature-help.test
diff --git a/test/clangd/spaces-in-delimited-input.test b/clangd/test/spaces-in-delimited-input.test
similarity index 100%
rename from test/clangd/spaces-in-delimited-input.test
rename to clangd/test/spaces-in-delimited-input.test
diff --git a/test/clangd/symbol-info.test b/clangd/test/symbol-info.test
similarity index 100%
rename from test/clangd/symbol-info.test
rename to clangd/test/symbol-info.test
diff --git a/test/clangd/symbols.test b/clangd/test/symbols.test
similarity index 100%
rename from test/clangd/symbols.test
rename to clangd/test/symbols.test
diff --git a/test/clangd/test-uri-posix.test b/clangd/test/test-uri-posix.test
similarity index 100%
rename from test/clangd/test-uri-posix.test
rename to clangd/test/test-uri-posix.test
diff --git a/test/clangd/test-uri-windows.test b/clangd/test/test-uri-windows.test
similarity index 100%
rename from test/clangd/test-uri-windows.test
rename to clangd/test/test-uri-windows.test
diff --git a/test/clangd/textdocument-didchange-fail.test b/clangd/test/textdocument-didchange-fail.test
similarity index 100%
rename from test/clangd/textdocument-didchange-fail.test
rename to clangd/test/textdocument-didchange-fail.test
diff --git a/test/clangd/too_large.test b/clangd/test/too_large.test
similarity index 100%
rename from test/clangd/too_large.test
rename to clangd/test/too_large.test
diff --git a/clangd/test/trace.test b/clangd/test/trace.test
new file mode 100644
index 0000000..cb6a226
--- /dev/null
+++ b/clangd/test/trace.test
@@ -0,0 +1,28 @@
+# RUN: env CLANGD_TRACE=%t clangd -lit-test < %s && FileCheck %s < %t
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
+# These assertions are a bit loose, to avoid brittleness.
+# CHECK: {
+# CHECK:   "displayTimeUnit": "ns",
+# CHECK:   "traceEvents": [
+# CHECK:     {
+# CHECK:       "ph": "X",
+# CHECK:       "name": "BuildPreamble",
+# CHECK:       "args": {
+# CHECK:         "File": "{{.*(/|\\)}}foo.c"
+# CHECK:       },
+# CHECK:     }
+# CHECK:     {
+# CHECK:       "ph": "X",
+# CHECK:       "name": "BuildAST",
+# CHECK:       "args": {
+# CHECK:         "File": "{{.*(/|\\)}}foo.c"
+# CHECK:       },
+# CHECK:     }
+# CHECK:   ]
+# CHECK: }
+---
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/clangd/test/tweaks-format.test b/clangd/test/tweaks-format.test
new file mode 100644
index 0000000..8fe7a11
--- /dev/null
+++ b/clangd/test/tweaks-format.test
@@ -0,0 +1,50 @@
+# RUN: clangd -lit-test < %s | FileCheck %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cc","languageId":"cpp","version":1,"text":"int f() { if (true) { return 1; } else {} }"}}}
+---
+{"jsonrpc":"2.0","id":5,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///main.cc"},"range":{"start":{"line":0,"character":11},"end":{"line":0,"character":11}},"context":{"diagnostics":[]}}}
+---
+{"jsonrpc":"2.0","id":6,"method":"workspace/executeCommand","params":{"command":"clangd.applyTweak","arguments":[{"file":"test:///main.cc","selection":{"end":{"character":11,"line":0},"start":{"character":11,"line":0}},"tweakID":"SwapIfBranches"}]}}
+#      CHECK:    "newText": "\n  ",
+# CHECK-NEXT:    "range": {
+# CHECK-NEXT:      "end": {
+# CHECK-NEXT:        "character": 10,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "start": {
+# CHECK-NEXT:        "character": 9,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      }
+# CHECK-NEXT:    }
+# CHECK-NEXT:  },
+# CHECK-NEXT:  {
+# CHECK-NEXT:    "newText": "{\n  }",
+# CHECK-NEXT:    "range": {
+# CHECK-NEXT:      "end": {
+# CHECK-NEXT:        "character": 33,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "start": {
+# CHECK-NEXT:        "character": 20,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      }
+# CHECK-NEXT:    }
+# CHECK-NEXT:  },
+# CHECK-NEXT:  {
+# CHECK-NEXT:    "newText": "{\n    return 1;\n  }\n",
+# CHECK-NEXT:    "range": {
+# CHECK-NEXT:      "end": {
+# CHECK-NEXT:        "character": 42,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "start": {
+# CHECK-NEXT:        "character": 39,
+# CHECK-NEXT:        "line": 0
+# CHECK-NEXT:      }
+# CHECK-NEXT:    }
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/clangd/test/type-hierarchy.test b/clangd/test/type-hierarchy.test
new file mode 100644
index 0000000..420f7fb
--- /dev/null
+++ b/clangd/test/type-hierarchy.test
@@ -0,0 +1,92 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct Parent {};\nstruct Child1 : Parent {};\nstruct Child2 : Child1 {};"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/typeHierarchy","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":11},"direction":1,"resolve":1}}
+#      CHECK:  "id": 1
+# CHECK-NEXT:  "jsonrpc": "2.0",
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "kind": 23,
+# CHECK-NEXT:    "name": "Child2",
+# CHECK-NEXT:    "parents": [
+# CHECK-NEXT:      {
+# CHECK-NEXT:        "kind": 23,
+# CHECK-NEXT:        "name": "Child1",
+# CHECK-NEXT:        "parents": [
+# CHECK-NEXT:          {
+# CHECK-NEXT:            "kind": 23,
+# CHECK-NEXT:            "name": "Parent",
+# CHECK-NEXT:            "parents": [],
+# CHECK-NEXT:            "range": {
+# CHECK-NEXT:              "end": {
+# CHECK-NEXT:                "character": 15,
+# CHECK-NEXT:                "line": 0
+# CHECK-NEXT:              },
+# CHECK-NEXT:              "start": {
+# CHECK-NEXT:                "character": 0,
+# CHECK-NEXT:                "line": 0
+# CHECK-NEXT:              }
+# CHECK-NEXT:            },
+# CHECK-NEXT:            "selectionRange": {
+# CHECK-NEXT:              "end": {
+# CHECK-NEXT:                "character": 13,
+# CHECK-NEXT:                "line": 0
+# CHECK-NEXT:              },
+# CHECK-NEXT:              "start": {
+# CHECK-NEXT:                "character": 7,
+# CHECK-NEXT:                "line": 0
+# CHECK-NEXT:              }
+# CHECK-NEXT:            },
+# CHECK-NEXT:            "uri": "file:///clangd-test/main.cpp"
+# CHECK-NEXT:          }
+# CHECK-NEXT:        ],
+# CHECK-NEXT:        "range": {
+# CHECK-NEXT:          "end": {
+# CHECK-NEXT:            "character": 24,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          },
+# CHECK-NEXT:          "start": {
+# CHECK-NEXT:            "character": 0,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          }
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "selectionRange": {
+# CHECK-NEXT:          "end": {
+# CHECK-NEXT:            "character": 13,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          },
+# CHECK-NEXT:          "start": {
+# CHECK-NEXT:            "character": 7,
+# CHECK-NEXT:            "line": 1
+# CHECK-NEXT:          }
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "uri": "file:///clangd-test/main.cpp"
+# CHECK-NEXT:      }
+# CHECK-NEXT:    ],
+# CHECK-NEXT:    "range": {
+# CHECK-NEXT:      "end": {
+# CHECK-NEXT:        "character": 24,
+# CHECK-NEXT:        "line": 2
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "start": {
+# CHECK-NEXT:        "character": 0,
+# CHECK-NEXT:        "line": 2
+# CHECK-NEXT:      }
+# CHECK-NEXT:    },
+# CHECK-NEXT:    "selectionRange": {
+# CHECK-NEXT:      "end": {
+# CHECK-NEXT:        "character": 13,
+# CHECK-NEXT:        "line": 2
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "start": {
+# CHECK-NEXT:        "character": 7,
+# CHECK-NEXT:        "line": 2
+# CHECK-NEXT:      }
+# CHECK-NEXT:    },
+# CHECK-NEXT:    "uri": "file:///clangd-test/main.cpp"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":2,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/unsupported-method.test b/clangd/test/unsupported-method.test
similarity index 100%
rename from test/clangd/unsupported-method.test
rename to clangd/test/unsupported-method.test
diff --git a/clangd/test/utf8.test b/clangd/test/utf8.test
new file mode 100644
index 0000000..5a00c89
--- /dev/null
+++ b/clangd/test/utf8.test
@@ -0,0 +1,32 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+# This test verifies that we can negotiate UTF-8 offsets via protocol extension.
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"offsetEncoding":["utf-8","utf-16"]},"trace":"off"}}
+# CHECK: "offsetEncoding": "utf-8"
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"/*ö*/int x;\nint y=x;"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":6}}}
+# /*ö*/int x;
+# 01234567890
+# x is character (and utf-16) range [9,10) but byte range [10,11).
+#      CHECK:  "id": 1,
+# CHECK-NEXT:  "jsonrpc": "2.0",
+# CHECK-NEXT:  "result": [
+# CHECK-NEXT:    {
+# CHECK-NEXT:      "range": {
+# CHECK-NEXT:        "end": {
+# CHECK-NEXT:          "character": 11,
+# CHECK-NEXT:          "line": 0
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "start": {
+# CHECK-NEXT:          "character": 10,
+# CHECK-NEXT:          "line": 0
+# CHECK-NEXT:        }
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "uri": "file://{{.*}}/main.cpp"
+# CHECK-NEXT:    }
+# CHECK-NEXT:  ]
+---
+{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/xpc/initialize.test b/clangd/test/xpc/initialize.test
similarity index 100%
rename from test/clangd/xpc/initialize.test
rename to clangd/test/xpc/initialize.test
diff --git a/test/clangd/xrefs.test b/clangd/test/xrefs.test
similarity index 62%
rename from test/clangd/xrefs.test
rename to clangd/test/xrefs.test
index 58ca44c..128c97f 100644
--- a/test/clangd/xrefs.test
+++ b/clangd/test/xrefs.test
@@ -1,9 +1,9 @@
 # RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
 ---
-{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x = 0;\nint y = x;"}}}
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"extern int x;\nint x = 0;\nint y = x;"}}}
 ---
-{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}}
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":8}}}
 #      CHECK:  "id": 1,
 # CHECK-NEXT:  "jsonrpc": "2.0",
 # CHECK-NEXT:  "result": [
@@ -11,10 +11,30 @@
 # CHECK-NEXT:      "range": {
 # CHECK-NEXT:        "end": {
 # CHECK-NEXT:          "character": 5,
-# CHECK-NEXT:          "line": 0
+# CHECK-NEXT:          "line": 1
 # CHECK-NEXT:        },
 # CHECK-NEXT:        "start": {
 # CHECK-NEXT:          "character": 4,
+# CHECK-NEXT:          "line": 1
+# CHECK-NEXT:        }
+# CHECK-NEXT:      },
+# CHECK-NEXT:      "uri": "file://{{.*}}/{{([A-Z]:/)?}}main.cpp"
+# CHECK-NEXT:    }
+# CHECK-NEXT:  ]
+---
+# Toggle: we're on the definition, so jump to the declaration.
+{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":4}}}
+#      CHECK:  "id": 1,
+# CHECK-NEXT:  "jsonrpc": "2.0",
+# CHECK-NEXT:  "result": [
+# CHECK-NEXT:    {
+# CHECK-NEXT:      "range": {
+# CHECK-NEXT:        "end": {
+# CHECK-NEXT:          "character": 12,
+# CHECK-NEXT:          "line": 0
+# CHECK-NEXT:        },
+# CHECK-NEXT:        "start": {
+# CHECK-NEXT:          "character": 11,
 # CHECK-NEXT:          "line": 0
 # CHECK-NEXT:        }
 # CHECK-NEXT:      },
@@ -22,7 +42,7 @@
 # CHECK-NEXT:    }
 # CHECK-NEXT:  ]
 ---
-{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}}
+{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":8}}}
 #      CHECK: "id": 1
 # CHECK-NEXT: "jsonrpc": "2.0",
 # CHECK-NEXT: "result": [
@@ -30,25 +50,38 @@
 # CHECK-NEXT:     "kind": 1,
 # CHECK-NEXT:     "range": {
 # CHECK-NEXT:       "end": {
-# CHECK-NEXT:         "character": 5,
+# CHECK-NEXT:         "character": 12,
 # CHECK-NEXT:         "line": 0
 # CHECK-NEXT:       },
 # CHECK-NEXT:       "start": {
-# CHECK-NEXT:         "character": 4,
+# CHECK-NEXT:         "character": 11,
 # CHECK-NEXT:         "line": 0
 # CHECK-NEXT:       }
 # CHECK-NEXT:     }
 # CHECK-NEXT:   },
 # CHECK-NEXT:   {
+# CHECK-NEXT:     "kind": 1,
+# CHECK-NEXT:     "range": {
+# CHECK-NEXT:       "end": {
+# CHECK-NEXT:         "character": 5,
+# CHECK-NEXT:         "line": 1
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "start": {
+# CHECK-NEXT:         "character": 4,
+# CHECK-NEXT:         "line": 1
+# CHECK-NEXT:       }
+# CHECK-NEXT:     }
+# CHECK-NEXT:   },
+# CHECK-NEXT:   {
 # CHECK-NEXT:     "kind": 2,
 # CHECK-NEXT:     "range": {
 # CHECK-NEXT:       "end": {
 # CHECK-NEXT:         "character": 9,
-# CHECK-NEXT:         "line": 1
+# CHECK-NEXT:         "line": 2
 # CHECK-NEXT:       },
 # CHECK-NEXT:       "start": {
 # CHECK-NEXT:         "character": 8,
-# CHECK-NEXT:         "line": 1
+# CHECK-NEXT:         "line": 2
 # CHECK-NEXT:       }
 # CHECK-NEXT:     }
 # CHECK-NEXT:   }
diff --git a/clangd/tool/CMakeLists.txt b/clangd/tool/CMakeLists.txt
index 1ad2ca1..93d7f14 100644
--- a/clangd/tool/CMakeLists.txt
+++ b/clangd/tool/CMakeLists.txt
@@ -3,6 +3,7 @@
 
 add_clang_tool(clangd
   ClangdMain.cpp
+  $<TARGET_OBJECTS:obj.clangDaemonTweaks>
   )
 
 set(LLVM_LINK_COMPONENTS
@@ -16,7 +17,9 @@
 
 target_link_libraries(clangd
   PRIVATE
+  clangAST
   clangBasic
+  clangTidy
   clangDaemon
   clangFormat
   clangFrontend
diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp
index 34e81d3..b066283 100644
--- a/clangd/tool/ClangdMain.cpp
+++ b/clangd/tool/ClangdMain.cpp
@@ -1,19 +1,23 @@
 //===--- ClangdMain.cpp - clangd server loop ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "Features.inc"
 #include "ClangdLSPServer.h"
+#include "CodeComplete.h"
+#include "Features.inc"
 #include "Path.h"
+#include "Protocol.h"
 #include "Trace.h"
 #include "Transport.h"
+#include "index/Background.h"
 #include "index/Serialization.h"
 #include "clang/Basic/Version.h"
+#include "clang/Format/Format.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -32,7 +36,7 @@
 static llvm::cl::opt<bool>
     UseDex("use-dex-index",
            llvm::cl::desc("Use experimental Dex dynamic index."),
-           llvm::cl::init(false), llvm::cl::Hidden);
+           llvm::cl::init(true), llvm::cl::Hidden);
 
 static llvm::cl::opt<Path> CompileCommandsDir(
     "compile-commands-dir",
@@ -91,7 +95,7 @@
 static llvm::cl::opt<bool>
     Test("lit-test",
          llvm::cl::desc("Abbreviation for -input-style=delimited -pretty "
-                        "-run-synchronously -enable-test-scheme. "
+                        "-run-synchronously -enable-test-scheme -log=verbose. "
                         "Intended to simplify lit tests."),
          llvm::cl::init(false), llvm::cl::Hidden);
 
@@ -153,6 +157,20 @@
     "debug-origin", llvm::cl::desc("Show origins of completion items"),
     llvm::cl::init(CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden);
 
+static llvm::cl::opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion(
+    "header-insertion",
+    llvm::cl::desc("Add #include directives when accepting code completions"),
+    llvm::cl::init(CodeCompleteOptions().InsertIncludes),
+    llvm::cl::values(
+        clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
+                   "Include what you use. "
+                   "Insert the owning header for top-level symbols, unless the "
+                   "header is already directly included or the symbol is "
+                   "forward-declared."),
+        clEnumValN(
+            CodeCompleteOptions::NeverInsert, "never",
+            "Never insert #include directives as part of code completion")));
+
 static llvm::cl::opt<bool> HeaderInsertionDecorators(
     "header-insertion-decorators",
     llvm::cl::desc("Prepend a circular dot or space before the completion "
@@ -164,7 +182,7 @@
     "index-file",
     llvm::cl::desc(
         "Index file to build the static index. The file must have been created "
-        "by a compatible clangd-index.\n"
+        "by a compatible clangd-indexer.\n"
         "WARNING: This option is experimental only, and will be removed "
         "eventually. Don't rely on it."),
     llvm::cl::init(""), llvm::cl::Hidden);
@@ -202,6 +220,48 @@
                    "placeholders for method parameters."),
     llvm::cl::init(CodeCompleteOptions().EnableFunctionArgSnippets));
 
+static llvm::cl::opt<std::string> ClangTidyChecks(
+    "clang-tidy-checks",
+    llvm::cl::desc(
+        "List of clang-tidy checks to run (this will override "
+        ".clang-tidy files). Only meaningful when -clang-tidy flag is on."),
+    llvm::cl::init(""));
+
+static llvm::cl::opt<bool> EnableClangTidy(
+    "clang-tidy",
+    llvm::cl::desc("Enable clang-tidy diagnostics."),
+    llvm::cl::init(true));
+
+static llvm::cl::opt<std::string>
+    FallbackStyle("fallback-style",
+                  llvm::cl::desc("clang-format style to apply by default when "
+                                 "no .clang-format file is found"),
+                  llvm::cl::init(clang::format::DefaultFallbackStyle));
+
+static llvm::cl::opt<bool> SuggestMissingIncludes(
+    "suggest-missing-includes",
+    llvm::cl::desc("Attempts to fix diagnostic errors caused by missing "
+                   "includes using index."),
+    llvm::cl::init(true));
+
+static llvm::cl::opt<OffsetEncoding> ForceOffsetEncoding(
+    "offset-encoding",
+    llvm::cl::desc("Force the offsetEncoding used for character positions. "
+                   "This bypasses negotiation via client capabilities."),
+    llvm::cl::values(clEnumValN(OffsetEncoding::UTF8, "utf-8",
+                                "Offsets are in UTF-8 bytes"),
+                     clEnumValN(OffsetEncoding::UTF16, "utf-16",
+                                "Offsets are in UTF-16 code units")),
+    llvm::cl::init(OffsetEncoding::UnsupportedEncoding));
+
+static llvm::cl::opt<bool> AllowFallbackCompletion(
+    "allow-fallback-completion",
+    llvm::cl::desc(
+        "Allow falling back to code completion without compiling files (using "
+        "identifiers and symbol indexes), when file cannot be built or the "
+        "build is not ready."),
+    llvm::cl::init(false));
+
 namespace {
 
 /// \brief Supports a test URI scheme with relaxed constraints for lit tests.
@@ -278,8 +338,10 @@
   if (Test) {
     RunSynchronously = true;
     InputStyle = JSONStreamStyle::Delimited;
+    LogLevel = Logger::Verbose;
     PrettyPrint = true;
-    preventThreadStarvationInTests(); // Ensure background index makes progress.
+    // Ensure background index makes progress.
+    BackgroundIndex::preventThreadStarvationInTests();
   }
   if (Test || EnableTestScheme) {
     static URISchemeRegistry::Add<TestScheme> X(
@@ -297,6 +359,8 @@
       llvm::errs() << "Ignoring -j because -run-synchronously is set.\n";
     WorkerThreadsCount = 0;
   }
+  if (FallbackStyle.getNumOccurrences())
+    clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
 
   // Validate command line arguments.
   llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
@@ -401,6 +465,7 @@
   CCOpts.Limit = LimitResults;
   CCOpts.BundleOverloads = CompletionStyle != Detailed;
   CCOpts.ShowOrigins = ShowOrigins;
+  CCOpts.InsertIncludes = HeaderInsertion;
   if (!HeaderInsertionDecorators) {
     CCOpts.IncludeIndicator.Insert.clear();
     CCOpts.IncludeIndicator.NoInsert.clear();
@@ -408,7 +473,9 @@
   CCOpts.SpeculativeIndexRequest = Opts.StaticIndex;
   CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
   CCOpts.AllScopes = AllScopesCompletion;
+  CCOpts.AllowFallback = AllowFallbackCompletion;
 
+  RealFileSystemProvider FSProvider;
   // Initialize and run ClangdLSPServer.
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();
@@ -428,9 +495,25 @@
         PrettyPrint, InputStyle);
   }
 
+  // Create an empty clang-tidy option.
+  std::unique_ptr<tidy::ClangTidyOptionsProvider> ClangTidyOptProvider;
+  if (EnableClangTidy) {
+    auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults();
+    OverrideClangTidyOptions.Checks = ClangTidyChecks;
+    ClangTidyOptProvider = llvm::make_unique<tidy::FileOptionsProvider>(
+        tidy::ClangTidyGlobalOptions(),
+        /* Default */ tidy::ClangTidyOptions::getDefaults(),
+        /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem());
+  }
+  Opts.ClangTidyOptProvider = ClangTidyOptProvider.get();
+  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
+  llvm::Optional<OffsetEncoding> OffsetEncodingFromFlag;
+  if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
+    OffsetEncodingFromFlag = ForceOffsetEncoding;
   ClangdLSPServer LSPServer(
-      *TransportLayer, CCOpts, CompileCommandsDirPath,
-      /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts);
+      *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
+      /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
+      OffsetEncodingFromFlag, Opts);
   llvm::set_thread_name("clangd.main");
   return LSPServer.run() ? 0
                          : static_cast<int>(ErrorResultCode::NoShutdownRequest);
diff --git a/clangd/unittests/Annotations.cpp b/clangd/unittests/Annotations.cpp
new file mode 100644
index 0000000..edb0ea9
--- /dev/null
+++ b/clangd/unittests/Annotations.cpp
@@ -0,0 +1,53 @@
+//===--- Annotations.cpp - Annotated source code for unit tests --*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "SourceCode.h"
+
+namespace clang {
+namespace clangd {
+
+Position Annotations::point(llvm::StringRef Name) const {
+  return offsetToPosition(code(), Base::point(Name));
+}
+
+std::vector<Position> Annotations::points(llvm::StringRef Name) const {
+  auto Offsets = Base::points(Name);
+
+  std::vector<Position> Ps;
+  Ps.reserve(Offsets.size());
+  for (size_t O : Offsets)
+    Ps.push_back(offsetToPosition(code(), O));
+
+  return Ps;
+}
+
+static clangd::Range toLSPRange(llvm::StringRef Code, Annotations::Range R) {
+  clangd::Range LSPRange;
+  LSPRange.start = offsetToPosition(Code, R.Begin);
+  LSPRange.end = offsetToPosition(Code, R.End);
+  return LSPRange;
+}
+
+clangd::Range Annotations::range(llvm::StringRef Name) const {
+  return toLSPRange(code(), Base::range(Name));
+}
+
+std::vector<clangd::Range> Annotations::ranges(llvm::StringRef Name) const {
+  auto OffsetRanges = Base::ranges(Name);
+
+  std::vector<clangd::Range> Rs;
+  Rs.reserve(OffsetRanges.size());
+  for (Annotations::Range R : OffsetRanges)
+    Rs.push_back(toLSPRange(code(), R));
+
+  return Rs;
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/unittests/Annotations.h b/clangd/unittests/Annotations.h
new file mode 100644
index 0000000..846c36a
--- /dev/null
+++ b/clangd/unittests/Annotations.h
@@ -0,0 +1,39 @@
+//===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// A clangd-specific version of llvm/Testing/Support/Annotations.h, replaces
+// offsets and offset-based ranges with types from the LSP protocol.
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
+#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
+
+#include "Protocol.h"
+#include "llvm/Testing/Support/Annotations.h"
+
+namespace clang {
+namespace clangd {
+
+/// Same as llvm::Annotations, but adjusts functions to LSP-specific types for
+/// positions and ranges.
+class Annotations : public llvm::Annotations {
+  using Base = llvm::Annotations;
+
+public:
+  using llvm::Annotations::Annotations;
+
+  Position point(llvm::StringRef Name = "") const;
+  std::vector<Position> points(llvm::StringRef Name = "") const;
+
+  clangd::Range range(llvm::StringRef Name = "") const;
+  std::vector<clangd::Range> ranges(llvm::StringRef Name = "") const;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
diff --git a/unittests/clangd/BackgroundIndexTests.cpp b/clangd/unittests/BackgroundIndexTests.cpp
similarity index 86%
rename from unittests/clangd/BackgroundIndexTests.cpp
rename to clangd/unittests/BackgroundIndexTests.cpp
index 639d35c..86f8700 100644
--- a/unittests/clangd/BackgroundIndexTests.cpp
+++ b/clangd/unittests/BackgroundIndexTests.cpp
@@ -7,12 +7,12 @@
 #include "gtest/gtest.h"
 #include <thread>
 
-using testing::_;
-using testing::AllOf;
-using testing::Contains;
-using testing::ElementsAre;
-using testing::Not;
-using testing::UnorderedElementsAre;
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::Not;
+using ::testing::UnorderedElementsAre;
 
 namespace clang {
 namespace clangd {
@@ -23,9 +23,9 @@
 }
 MATCHER(Defined, "") { return !StringRef(arg.Definition.FileURI).empty(); }
 MATCHER_P(FileURI, F, "") { return StringRef(arg.Location.FileURI) == F; }
-testing::Matcher<const RefSlab &>
-RefsAre(std::vector<testing::Matcher<Ref>> Matchers) {
-  return ElementsAre(testing::Pair(_, UnorderedElementsAreArray(Matchers)));
+::testing::Matcher<const RefSlab &>
+RefsAre(std::vector<::testing::Matcher<Ref>> Matchers) {
+  return ElementsAre(::testing::Pair(_, UnorderedElementsAreArray(Matchers)));
 }
 // URI cannot be empty since it references keys in the IncludeGraph.
 MATCHER(EmptyIncludeNode, "") {
@@ -44,12 +44,14 @@
   llvm::Error storeShard(llvm::StringRef ShardIdentifier,
                          IndexFileOut Shard) const override {
     std::lock_guard<std::mutex> Lock(StorageMu);
+    AccessedPaths.insert(ShardIdentifier);
     Storage[ShardIdentifier] = llvm::to_string(Shard);
     return llvm::Error::success();
   }
   std::unique_ptr<IndexFileIn>
   loadShard(llvm::StringRef ShardIdentifier) const override {
     std::lock_guard<std::mutex> Lock(StorageMu);
+    AccessedPaths.insert(ShardIdentifier);
     if (Storage.find(ShardIdentifier) == Storage.end()) {
       return nullptr;
     }
@@ -62,11 +64,13 @@
     CacheHits++;
     return llvm::make_unique<IndexFileIn>(std::move(*IndexFile));
   }
+
+  mutable llvm::StringSet<> AccessedPaths;
 };
 
 class BackgroundIndexTest : public ::testing::Test {
 protected:
-  BackgroundIndexTest() { preventThreadStarvationInTests(); }
+  BackgroundIndexTest() { BackgroundIndex::preventThreadStarvationInTests(); }
 };
 
 TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) {
@@ -76,7 +80,7 @@
   size_t CacheHits = 0;
   MemoryShardStorage MSS(Storage, CacheHits);
   OverlayCDB CDB(/*Base=*/nullptr);
-  BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+  BackgroundIndex Idx(Context::empty(), FS, CDB,
                       [&](llvm::StringRef) { return &MSS; });
 
   tooling::CompileCommand Cmd;
@@ -113,7 +117,7 @@
   size_t CacheHits = 0;
   MemoryShardStorage MSS(Storage, CacheHits);
   OverlayCDB CDB(/*Base=*/nullptr);
-  BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+  BackgroundIndex Idx(Context::empty(), FS, CDB,
                       [&](llvm::StringRef) { return &MSS; });
 
   tooling::CompileCommand Cmd;
@@ -168,7 +172,7 @@
   // Check nothing is loaded from Storage, but A.cc and A.h has been stored.
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -178,7 +182,7 @@
 
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -224,7 +228,7 @@
   Cmd.CommandLine = {"clang++", testPath("root/A.cc")};
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -262,7 +266,7 @@
   MemoryShardStorage MSS(Storage, CacheHits);
   OverlayCDB CDB(/*Base=*/nullptr);
   BackgroundIndex Idx(
-      Context::empty(), "", FS, CDB, [&](llvm::StringRef) { return &MSS; },
+      Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; },
       /*BuildIndexPeriodMs=*/500);
 
   FS.Files[testPath("root/A.cc")] = "#include \"A.h\"";
@@ -310,7 +314,7 @@
   // Check nothing is loaded from Storage, but A.cc and A.h has been stored.
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -325,7 +329,7 @@
       )cpp";
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -343,7 +347,7 @@
   {
     CacheHits = 0;
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -384,7 +388,7 @@
   // Check that A.cc, A.h and B.h has been stored.
   {
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -400,7 +404,7 @@
   {
     CacheHits = 0;
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -416,7 +420,7 @@
   {
     CacheHits = 0;
     OverlayCDB CDB(/*Base=*/nullptr);
-    BackgroundIndex Idx(Context::empty(), "", FS, CDB,
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
                         [&](llvm::StringRef) { return &MSS; });
     CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
     ASSERT_TRUE(Idx.blockUntilIdleForTest());
@@ -428,5 +432,34 @@
               Contains(AllOf(Named("new_func"), Declared(), Not(Defined()))));
 }
 
+TEST_F(BackgroundIndexTest, NoDotsInAbsPath) {
+  MockFSProvider FS;
+  llvm::StringMap<std::string> Storage;
+  size_t CacheHits = 0;
+  MemoryShardStorage MSS(Storage, CacheHits);
+  OverlayCDB CDB(/*Base=*/nullptr);
+  BackgroundIndex Idx(Context::empty(), FS, CDB,
+                      [&](llvm::StringRef) { return &MSS; });
+
+  tooling::CompileCommand Cmd;
+  FS.Files[testPath("root/A.cc")] = "";
+  Cmd.Filename = "../A.cc";
+  Cmd.Directory = testPath("root/build");
+  Cmd.CommandLine = {"clang++", "../A.cc"};
+  CDB.setCompileCommand(testPath("root/build/../A.cc"), Cmd);
+
+  FS.Files[testPath("root/B.cc")] = "";
+  Cmd.Filename = "./B.cc";
+  Cmd.Directory = testPath("root");
+  Cmd.CommandLine = {"clang++", "./B.cc"};
+  CDB.setCompileCommand(testPath("root/./B.cc"), Cmd);
+
+  ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  for (llvm::StringRef AbsPath : MSS.AccessedPaths.keys()) {
+    EXPECT_FALSE(AbsPath.contains("./")) << AbsPath;
+    EXPECT_FALSE(AbsPath.contains("../")) << AbsPath;
+  }
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/CMakeLists.txt b/clangd/unittests/CMakeLists.txt
similarity index 61%
rename from unittests/clangd/CMakeLists.txt
rename to clangd/unittests/CMakeLists.txt
index ccc1927..96b1d36 100644
--- a/unittests/clangd/CMakeLists.txt
+++ b/clangd/unittests/CMakeLists.txt
@@ -4,20 +4,35 @@
 
 get_filename_component(CLANGD_SOURCE_DIR
   ${CMAKE_CURRENT_SOURCE_DIR}/../../clangd REALPATH)
+get_filename_component(CLANGD_BINARY_DIR
+  ${CMAKE_CURRENT_BINARY_DIR}/../../clangd REALPATH)
 include_directories(
   ${CLANGD_SOURCE_DIR}
+  ${CLANGD_BINARY_DIR}
   )
 
-add_extra_unittest(ClangdTests
+if(CLANG_BUILT_STANDALONE)
+  # LLVMTestingSupport library is needed for clangd tests.
+  if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
+      AND NOT TARGET LLVMTestingSupport)
+    add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
+      lib/Testing/Support)
+  endif()
+endif()
+
+add_custom_target(ClangdUnitTests)
+add_unittest(ClangdUnitTests ClangdTests
   Annotations.cpp
   BackgroundIndexTests.cpp
   CancellationTests.cpp
+  CanonicalIncludesTests.cpp
   ClangdTests.cpp
   ClangdUnitTests.cpp
   CodeCompleteTests.cpp
   CodeCompletionStringsTests.cpp
   ContextTests.cpp
   DexTests.cpp
+  DiagnosticsTests.cpp
   DraftStoreTests.cpp
   ExpectedTypeTest.cpp
   FileDistanceTests.cpp
@@ -31,8 +46,10 @@
   IndexActionTests.cpp
   IndexTests.cpp
   JSONTransportTests.cpp
+  PrintASTTests.cpp
   QualityTests.cpp
   RIFFTests.cpp
+  SelectionTests.cpp
   SerializationTests.cpp
   SourceCodeTests.cpp
   SymbolCollectorTests.cpp
@@ -44,8 +61,12 @@
   TestTU.cpp
   ThreadingTests.cpp
   TraceTests.cpp
+  TypeHierarchyTests.cpp
+  TweakTests.cpp
   URITests.cpp
   XRefsTests.cpp
+
+  $<TARGET_OBJECTS:obj.clangDaemonTweaks>
   )
 
 target_link_libraries(ClangdTests
@@ -59,6 +80,7 @@
   clangLex
   clangSema
   clangSerialization
+  clangTidy
   clangTooling
   clangToolingCore
   clangToolingInclusions
@@ -69,3 +91,7 @@
 if (CLANGD_BUILD_XPC)
   add_subdirectory(xpc)
 endif ()
+
+configure_lit_site_cfg(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
diff --git a/unittests/clangd/CancellationTests.cpp b/clangd/unittests/CancellationTests.cpp
similarity index 100%
rename from unittests/clangd/CancellationTests.cpp
rename to clangd/unittests/CancellationTests.cpp
diff --git a/clangd/unittests/CanonicalIncludesTests.cpp b/clangd/unittests/CanonicalIncludesTests.cpp
new file mode 100644
index 0000000..9fd7884
--- /dev/null
+++ b/clangd/unittests/CanonicalIncludesTests.cpp
@@ -0,0 +1,62 @@
+//===-- CanonicalIncludesTests.cpp - --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "index/CanonicalIncludes.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TEST(CanonicalIncludesTest, CXXStandardLibrary) {
+  CanonicalIncludes CI;
+  addSystemHeadersMapping(&CI);
+
+  // Usual standard library symbols are mapped correctly.
+  EXPECT_EQ("<vector>", CI.mapHeader("path/vector.h", "std::vector"));
+  // std::move is ambiguous, currently mapped only based on path
+  EXPECT_EQ("<utility>", CI.mapHeader("libstdc++/bits/move.h", "std::move"));
+  EXPECT_EQ("path/utility.h", CI.mapHeader("path/utility.h", "std::move"));
+  // Unknown std symbols aren't mapped.
+  EXPECT_EQ("foo/bar.h", CI.mapHeader("foo/bar.h", "std::notathing"));
+  // iosfwd declares some symbols it doesn't own.
+  EXPECT_EQ("<ostream>", CI.mapHeader("iosfwd", "std::ostream"));
+  // And (for now) we assume it owns the others.
+  EXPECT_EQ("<iosfwd>", CI.mapHeader("iosfwd", "std::notwathing"));
+}
+
+TEST(CanonicalIncludesTest, PathMapping) {
+  // As used for IWYU pragmas.
+  CanonicalIncludes CI;
+  CI.addMapping("foo/bar", "<baz>");
+
+  EXPECT_EQ("<baz>", CI.mapHeader("foo/bar", "some::symbol"));
+  EXPECT_EQ("bar/bar", CI.mapHeader("bar/bar", "some::symbol"));
+}
+
+TEST(CanonicalIncludesTest, SymbolMapping) {
+  // As used for standard library.
+  CanonicalIncludes CI;
+  CI.addSymbolMapping("some::symbol", "<baz>");
+
+  EXPECT_EQ("<baz>", CI.mapHeader("foo/bar", "some::symbol"));
+  EXPECT_EQ("foo/bar", CI.mapHeader("foo/bar", "other::symbol"));
+}
+
+TEST(CanonicalIncludesTest, Precedence) {
+  CanonicalIncludes CI;
+  CI.addMapping("some/path", "<path>");
+  CI.addSymbolMapping("some::symbol", "<symbol>");
+
+  // Symbol mapping beats path mapping.
+  EXPECT_EQ("<symbol>", CI.mapHeader("some/path", "some::symbol"));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/ClangdTests.cpp b/clangd/unittests/ClangdTests.cpp
similarity index 85%
rename from unittests/clangd/ClangdTests.cpp
rename to clangd/unittests/ClangdTests.cpp
index c1cc623..5d98bdc 100644
--- a/unittests/clangd/ClangdTests.cpp
+++ b/clangd/unittests/ClangdTests.cpp
@@ -1,20 +1,22 @@
 //===-- ClangdTests.cpp - Clangd unit tests ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "Annotations.h"
 #include "ClangdLSPServer.h"
 #include "ClangdServer.h"
+#include "GlobalCompilationDatabase.h"
 #include "Matchers.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
+#include "Threading.h"
 #include "URI.h"
 #include "clang/Config/config.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Errc.h"
@@ -36,15 +38,15 @@
 namespace {
 
 using ::testing::ElementsAre;
-using ::testing::Eq;
 using ::testing::Field;
 using ::testing::Gt;
 using ::testing::IsEmpty;
 using ::testing::Pair;
 using ::testing::UnorderedElementsAre;
 
-MATCHER_P2(FileRange, File, Range, "") {
-  return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg;
+MATCHER_P2(DeclAt, File, Range, "") {
+  return arg.PreferredDeclaration ==
+         Location{URIForFile::canonicalize(File, testRoot()), Range};
 }
 
 bool diagsContainErrors(const std::vector<Diag> &Diagnostics) {
@@ -458,10 +460,9 @@
               UnorderedElementsAre(Pair(FooCpp, false), Pair(BarCpp, true),
                                    Pair(BazCpp, false)));
 
-  auto Locations = runFindDefinitions(Server, FooCpp, FooSource.point());
+  auto Locations = runLocateSymbolAt(Server, FooCpp, FooSource.point());
   EXPECT_TRUE(bool(Locations));
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooCpp, FooSource.range("one"))));
+  EXPECT_THAT(*Locations, ElementsAre(DeclAt(FooCpp, FooSource.range("one"))));
 
   // Undefine MACRO, close baz.cpp.
   CDB.ExtraClangFlags.clear();
@@ -474,10 +475,9 @@
   EXPECT_THAT(DiagConsumer.filesWithDiags(),
               UnorderedElementsAre(Pair(FooCpp, false), Pair(BarCpp, false)));
 
-  Locations = runFindDefinitions(Server, FooCpp, FooSource.point());
+  Locations = runLocateSymbolAt(Server, FooCpp, FooSource.point());
   EXPECT_TRUE(bool(Locations));
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooCpp, FooSource.range("two"))));
+  EXPECT_THAT(*Locations, ElementsAre(DeclAt(FooCpp, FooSource.range("two"))));
 }
 
 TEST_F(ClangdVFSTest, MemoryUsage) {
@@ -532,15 +532,15 @@
   runAddDocument(Server, FooCpp, "int main() {}");
 
   EXPECT_EQ(runDumpAST(Server, FooCpp), "<no-ast>");
-  EXPECT_ERROR(runFindDefinitions(Server, FooCpp, Position()));
+  EXPECT_ERROR(runLocateSymbolAt(Server, FooCpp, Position()));
   EXPECT_ERROR(runFindDocumentHighlights(Server, FooCpp, Position()));
   EXPECT_ERROR(runRename(Server, FooCpp, Position(), "new_name"));
-  // FIXME: codeComplete and signatureHelp should also return errors when they
-  // can't parse the file.
+  // Identifier-based fallback completion.
   EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, Position(),
                                        clangd::CodeCompleteOptions()))
                   .Completions,
-              IsEmpty());
+              ElementsAre(Field(&CodeCompletion::Name, "int"),
+                          Field(&CodeCompletion::Name, "main")));
   auto SigHelp = runSignatureHelp(Server, FooCpp, Position());
   ASSERT_TRUE(bool(SigHelp)) << "signatureHelp returned an error";
   EXPECT_THAT(SigHelp->signatures, IsEmpty());
@@ -717,7 +717,7 @@
                                clangd::CodeCompleteOptions()));
     };
 
-    auto FindDefinitionsRequest = [&]() {
+    auto LocateSymbolRequest = [&]() {
       unsigned FileIndex = FileIndexDist(RandGen);
       // Make sure we don't violate the ClangdServer's contract.
       if (ReqStats[FileIndex].FileIsRemoved)
@@ -727,13 +727,13 @@
       Pos.line = LineDist(RandGen);
       Pos.character = ColumnDist(RandGen);
 
-      ASSERT_TRUE(!!runFindDefinitions(Server, FilePaths[FileIndex], Pos));
+      ASSERT_TRUE(!!runLocateSymbolAt(Server, FilePaths[FileIndex], Pos));
     };
 
     std::vector<std::function<void()>> AsyncRequests = {
         AddDocumentRequest, ForceReparseRequest, RemoveDocumentRequest};
     std::vector<std::function<void()>> BlockingRequests = {
-        CodeCompletionRequest, FindDefinitionsRequest};
+        CodeCompletionRequest, LocateSymbolRequest};
 
     // Bash requests to ClangdServer in a loop.
     std::uniform_int_distribution<int> AsyncRequestIndexDist(
@@ -1037,6 +1037,126 @@
 }
 #endif
 
+TEST_F(ClangdVFSTest, FlagsWithPlugins) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+  CDB.ExtraClangFlags = {
+      "-Xclang",
+      "-add-plugin",
+      "-Xclang",
+      "random-plugin",
+  };
+  OverlayCDB OCDB(&CDB);
+  ClangdServer Server(OCDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+  auto FooCpp = testPath("foo.cpp");
+  const auto SourceContents = "int main() { return 0; }";
+  FS.Files[FooCpp] = FooCpp;
+  Server.addDocument(FooCpp, SourceContents);
+  auto Result = dumpASTWithoutMemoryLocs(Server, FooCpp);
+  EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics";
+  EXPECT_NE(Result, "<no-ast>");
+}
+
+TEST_F(ClangdVFSTest, FallbackWhenPreambleIsNotReady) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+  auto FooCpp = testPath("foo.cpp");
+   Annotations Code(R"cpp(
+    namespace ns { int xyz; }
+    using namespace ns;
+    int main() {
+       xy^
+    })cpp");
+  FS.Files[FooCpp] = FooCpp;
+
+  auto Opts = clangd::CodeCompleteOptions();
+  Opts.AllowFallback = true;
+
+  // This will make compile command broken and preamble absent.
+  CDB.ExtraClangFlags = {"yolo.cc"};
+  Server.addDocument(FooCpp, Code.code());
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  auto Res = cantFail(runCodeComplete(Server, FooCpp, Code.point(), Opts));
+  EXPECT_EQ(Res.Context, CodeCompletionContext::CCC_Recovery);
+  // Identifier-based fallback completion doesn't know about "symbol" scope.
+  EXPECT_THAT(Res.Completions,
+              ElementsAre(AllOf(Field(&CodeCompletion::Name, "xyz"),
+                                Field(&CodeCompletion::Scope, ""))));
+
+  // Make the compile command work again.
+  CDB.ExtraClangFlags = {"-std=c++11"};
+  Server.addDocument(FooCpp, Code.code());
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, Code.point(),
+                                       clangd::CodeCompleteOptions()))
+                  .Completions,
+              ElementsAre(AllOf(Field(&CodeCompletion::Name, "xyz"),
+                                Field(&CodeCompletion::Scope, "ns::"))));
+}
+
+TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  // Returns compile command only when notified.
+  class DelayedCompilationDatabase : public GlobalCompilationDatabase {
+  public:
+    DelayedCompilationDatabase(Notification &CanReturnCommand)
+        : CanReturnCommand(CanReturnCommand) {}
+
+    llvm::Optional<tooling::CompileCommand>
+    getCompileCommand(PathRef File, ProjectInfo * = nullptr) const override {
+      // FIXME: make this timeout and fail instead of waiting forever in case
+      // something goes wrong.
+      CanReturnCommand.wait();
+      auto FileName = llvm::sys::path::filename(File);
+      std::vector<std::string> CommandLine = {"clangd", "-ffreestanding", File};
+      return {tooling::CompileCommand(llvm::sys::path::parent_path(File),
+                                      FileName, std::move(CommandLine), "")};
+    }
+
+    std::vector<std::string> ExtraClangFlags;
+
+  private:
+    Notification &CanReturnCommand;
+  };
+
+  Notification CanReturnCommand;
+  DelayedCompilationDatabase CDB(CanReturnCommand);
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+  auto FooCpp = testPath("foo.cpp");
+  Annotations Code(R"cpp(
+    namespace ns { int xyz; }
+    using namespace ns;
+    int main() {
+       xy^
+    })cpp");
+  FS.Files[FooCpp] = FooCpp;
+  Server.addDocument(FooCpp, Code.code());
+
+  // Sleep for some time to make sure code completion is not run because update
+  // hasn't been scheduled.
+  std::this_thread::sleep_for(std::chrono::milliseconds(10));
+  auto Opts = clangd::CodeCompleteOptions();
+  Opts.AllowFallback = true;
+
+  auto Res = cantFail(runCodeComplete(Server, FooCpp, Code.point(), Opts));
+  EXPECT_EQ(Res.Context, CodeCompletionContext::CCC_Recovery);
+
+  CanReturnCommand.notify();
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, Code.point(),
+                                       clangd::CodeCompleteOptions()))
+                  .Completions,
+              ElementsAre(AllOf(Field(&CodeCompletion::Name, "xyz"),
+                                Field(&CodeCompletion::Scope, "ns::"))));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/unittests/ClangdUnitTests.cpp b/clangd/unittests/ClangdUnitTests.cpp
new file mode 100644
index 0000000..2c239ce
--- /dev/null
+++ b/clangd/unittests/ClangdUnitTests.cpp
@@ -0,0 +1,86 @@
+//===-- ClangdUnitTests.cpp - ClangdUnit tests ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "ClangdUnit.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::ElementsAre;
+
+TEST(ClangdUnitTest, GetBeginningOfIdentifier) {
+  std::string Preamble = R"cpp(
+struct Bar { int func(); };
+#define MACRO(X) void f() { X; }
+Bar* bar;
+  )cpp";
+  // First ^ is the expected beginning, last is the search position.
+  for (std::string Text : std::vector<std::string>{
+           "int ^f^oo();", // inside identifier
+           "int ^foo();",  // beginning of identifier
+           "int ^foo^();", // end of identifier
+           "int foo(^);",  // non-identifier
+           "^int foo();",  // beginning of file (can't back up)
+           "int ^f0^0();", // after a digit (lexing at N-1 is wrong)
+           "int ^λλ^λ();", // UTF-8 handled properly when backing up
+
+           // identifier in macro arg
+           "MACRO(bar->^func())",  // beginning of identifier
+           "MACRO(bar->^fun^c())", // inside identifier
+           "MACRO(bar->^func^())", // end of identifier
+           "MACRO(^bar->func())",  // begin identifier
+           "MACRO(^bar^->func())", // end identifier
+           "^MACRO(bar->func())",  // beginning of macro name
+           "^MAC^RO(bar->func())", // inside macro name
+           "^MACRO^(bar->func())", // end of macro name
+       }) {
+    std::string WithPreamble = Preamble + Text;
+    Annotations TestCase(WithPreamble);
+    auto AST = TestTU::withCode(TestCase.code()).build();
+    const auto &SourceMgr = AST.getASTContext().getSourceManager();
+    SourceLocation Actual = getBeginningOfIdentifier(
+        AST, TestCase.points().back(), SourceMgr.getMainFileID());
+    Position ActualPos = offsetToPosition(
+        TestCase.code(),
+        SourceMgr.getFileOffset(SourceMgr.getSpellingLoc(Actual)));
+    EXPECT_EQ(TestCase.points().front(), ActualPos) << Text;
+  }
+}
+
+MATCHER_P(DeclNamed, Name, "") {
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
+    if (ND->getName() == Name)
+      return true;
+  if (auto *Stream = result_listener->stream()) {
+    llvm::raw_os_ostream OS(*Stream);
+    arg->dump(OS);
+  }
+  return false;
+}
+
+TEST(ClangdUnitTest, TopLevelDecls) {
+  TestTU TU;
+  TU.HeaderCode = R"(
+    int header1();
+    int header2;
+  )";
+  TU.Code = "int main();";
+  auto AST = TU.build();
+  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/CodeCompleteTests.cpp b/clangd/unittests/CodeCompleteTests.cpp
similarity index 86%
rename from unittests/clangd/CodeCompleteTests.cpp
rename to clangd/unittests/CodeCompleteTests.cpp
index 02f12ea..e584597 100644
--- a/unittests/clangd/CodeCompleteTests.cpp
+++ b/clangd/unittests/CodeCompleteTests.cpp
@@ -1,9 +1,8 @@
 //===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,9 +16,14 @@
 #include "SourceCode.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
+#include "TestIndex.h"
+#include "TestTU.h"
+#include "index/Index.h"
 #include "index/MemIndex.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -31,7 +35,6 @@
 using ::llvm::Failed;
 using ::testing::AllOf;
 using ::testing::Contains;
-using ::testing::Each;
 using ::testing::ElementsAre;
 using ::testing::Field;
 using ::testing::HasSubstr;
@@ -138,53 +141,25 @@
                      FilePath);
 }
 
-std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle,
-                    llvm::StringRef Repl) {
-  std::string Result;
-  llvm::raw_string_ostream OS(Result);
-  std::pair<llvm::StringRef, llvm::StringRef> Split;
-  for (Split = Haystack.split(Needle); !Split.second.empty();
-       Split = Split.first.split(Needle))
-    OS << Split.first << Repl;
-  Result += Split.first;
-  OS.flush();
-  return Result;
+// Builds a server and runs code completion.
+// If IndexSymbols is non-empty, an index will be built and passed to opts.
+CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
+                                        std::vector<Symbol> IndexSymbols = {},
+                                        clangd::CodeCompleteOptions Opts = {},
+                                        PathRef FilePath = "foo.cpp") {
+  std::unique_ptr<SymbolIndex> OverrideIndex;
+  if (!IndexSymbols.empty()) {
+    assert(!Opts.Index && "both Index and IndexSymbols given!");
+    OverrideIndex = memIndex(std::move(IndexSymbols));
+    Opts.Index = OverrideIndex.get();
+  }
+
+  MockFSProvider FS;
+  Annotations Test(Text);
+  return codeComplete(FilePath, tooling::CompileCommand(), /*Preamble=*/nullptr,
+                      Test.code(), Test.point(), FS.getFileSystem(), Opts);
 }
 
-// Helpers to produce fake index symbols for memIndex() or completions().
-// USRFormat is a regex replacement string for the unqualified part of the USR.
-Symbol sym(llvm::StringRef QName, index::SymbolKind Kind,
-           llvm::StringRef USRFormat) {
-  Symbol Sym;
-  std::string USR = "c:"; // We synthesize a few simple cases of USRs by hand!
-  size_t Pos = QName.rfind("::");
-  if (Pos == llvm::StringRef::npos) {
-    Sym.Name = QName;
-    Sym.Scope = "";
-  } else {
-    Sym.Name = QName.substr(Pos + 2);
-    Sym.Scope = QName.substr(0, Pos + 2);
-    USR += "@N@" + replace(QName.substr(0, Pos), "::", "@N@"); // ns:: -> @N@ns
-  }
-  USR += llvm::Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F@func#
-  Sym.ID = SymbolID(USR);
-  Sym.SymInfo.Kind = Kind;
-  Sym.Flags |= Symbol::IndexedForCodeCompletion;
-  Sym.Origin = SymbolOrigin::Static;
-  return Sym;
-}
-Symbol func(llvm::StringRef Name) { // Assumes the function has no args.
-  return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args
-}
-Symbol cls(llvm::StringRef Name) {
-  return sym(Name, index::SymbolKind::Class, "@S@\\0");
-}
-Symbol var(llvm::StringRef Name) {
-  return sym(Name, index::SymbolKind::Variable, "@\\0");
-}
-Symbol ns(llvm::StringRef Name) {
-  return sym(Name, index::SymbolKind::Namespace, "@N@\\0");
-}
 Symbol withReferences(int N, Symbol S) {
   S.References = N;
   return S;
@@ -199,6 +174,7 @@
   int BBB();
   int CCC();
 };
+
 int main() { ClassWithMembers().^ }
       )cpp",
                              /*IndexSymbols=*/{}, Opts);
@@ -259,6 +235,7 @@
       )cpp",
       {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
 
+  EXPECT_TRUE(Results.RanParser);
   // Class members. The only items that must be present in after-dot
   // completion.
   EXPECT_THAT(Results.Completions,
@@ -308,6 +285,7 @@
       )cpp",
       {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
 
+  EXPECT_TRUE(Results.RanParser);
   // Class members. Should never be present in global completions.
   EXPECT_THAT(Results.Completions,
               Not(AnyOf(Has("method"), Has("method()"), Has("field"))));
@@ -349,7 +327,7 @@
   }
 }
 
-TEST(CompletionTest, Priorities) {
+TEST(CompletionTest, Accessible) {
   auto Internal = completions(R"cpp(
       class Foo {
         public: void pub();
@@ -359,7 +337,7 @@
       void Foo::pub() { this->^ }
   )cpp");
   EXPECT_THAT(Internal.Completions,
-              HasSubsequence(Named("priv"), Named("prot"), Named("pub")));
+              AllOf(Has("priv"), Has("prot"), Has("pub")));
 
   auto External = completions(R"cpp(
       class Foo {
@@ -527,6 +505,21 @@
               HasSubsequence(Named("absl"), Named("absb")));
 }
 
+TEST(CompletionTest, ContextWords) {
+  auto Results = completions(R"cpp(
+  enum class Color { RED, YELLOW, BLUE };
+
+  // (blank lines so the definition above isn't "context")
+
+  // "It was a yellow car," he said. "Big yellow car, new."
+  auto Finish = Color::^
+  )cpp");
+  // Yellow would normally sort last (alphabetic).
+  // But the recent mention shuold bump it up.
+  ASSERT_THAT(Results.Completions,
+              HasSubsequence(Named("YELLOW"), Named("BLUE")));
+}
+
 TEST(CompletionTest, GlobalQualified) {
   auto Results = completions(
       R"cpp(
@@ -602,6 +595,16 @@
                              {Sym});
   EXPECT_THAT(Results.Completions,
               ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\""))));
+  // Can be disabled via option.
+  CodeCompleteOptions NoInsertion;
+  NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
+  Results = completions(Server,
+                             R"cpp(
+          int main() { ns::^ }
+      )cpp",
+                             {Sym}, NoInsertion);
+  EXPECT_THAT(Results.Completions,
+              ElementsAre(AllOf(Named("X"), Not(InsertInclude()))));
   // Duplicate based on inclusions in preamble.
   Results = completions(Server,
                         R"cpp(
@@ -692,6 +695,39 @@
   EXPECT_THAT(Results, ElementsAre(Named("ifndef")));
 }
 
+TEST(CompletionTest, DynamicIndexIncludeInsertion) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer::Options Opts = ClangdServer::optsForTest();
+  Opts.BuildDynamicSymbolIndex = true;
+  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
+
+  FS.Files[testPath("foo_header.h")] = R"cpp(
+    #pragma once
+    struct Foo {
+       // Member doc
+       int foo();
+    };
+  )cpp";
+  const std::string FileContent(R"cpp(
+    #include "foo_header.h"
+    int Foo::foo() {
+      return 42;
+    }
+  )cpp");
+  Server.addDocument(testPath("foo_impl.cpp"), FileContent);
+  // Wait for the dynamic index being built.
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  EXPECT_THAT(completions(Server, "Foo^ foo;").Completions,
+              ElementsAre(AllOf(Named("Foo"),
+                                HasInclude('"' +
+                                           llvm::sys::path::convert_to_slash(
+                                               testPath("foo_header.h")) +
+                                           '"'),
+                                InsertInclude())));
+}
+
 TEST(CompletionTest, DynamicIndexMultiFile) {
   MockFSProvider FS;
   MockCompilationDatabase CDB;
@@ -1111,8 +1147,10 @@
       } // namespace ns
   )cpp");
 
-  EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
-                                          UnorderedElementsAre("bar::"))));
+  EXPECT_THAT(Requests,
+              ElementsAre(Field(
+                  &FuzzyFindRequest::Scopes,
+                  UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
 }
 
 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
@@ -1371,7 +1409,7 @@
   // FIXME: Auto-completion in a template requires disabling delayed template
   // parsing.
   CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing");
-  Server.addDocument(FooCpp, Source.code(), WantDiagnostics::Yes);
+  runAddDocument(Server, FooCpp, Source.code(), WantDiagnostics::Yes);
   CodeCompleteResult Completions = cantFail(runCodeComplete(
       Server, FooCpp, Source.point(), clangd::CodeCompleteOptions()));
 
@@ -1929,28 +1967,37 @@
   )cpp");
 }
 
-TEST(SpeculateCompletionFilter, Filters) {
-  Annotations F(R"cpp($bof^
-      $bol^
-      ab$ab^
-      x.ab$dot^
-      x.$dotempty^
-      x::ab$scoped^
-      x::$scopedempty^
+TEST(GuessCompletionPrefix, Filters) {
+  for (llvm::StringRef Case : {
+    "[[scope::]][[ident]]^",
+    "[[]][[]]^",
+    "\n[[]][[]]^",
+    "[[]][[ab]]^",
+    "x.[[]][[ab]]^",
+    "x.[[]][[]]^",
+    "[[x::]][[ab]]^",
+    "[[x::]][[]]^",
+    "[[::x::]][[ab]]^",
+    "some text [[scope::more::]][[identif]]^ier",
+    "some text [[scope::]][[mor]]^e::identifier",
+    "weird case foo::[[::bar::]][[baz]]^",
+  }) {
+    Annotations F(Case);
+    auto Offset = cantFail(positionToOffset(F.code(), F.point()));
+    auto ToStringRef = [&](Range R) {
+      return F.code().slice(cantFail(positionToOffset(F.code(), R.start)),
+                            cantFail(positionToOffset(F.code(), R.end)));
+    };
+    auto WantQualifier = ToStringRef(F.ranges()[0]),
+         WantName = ToStringRef(F.ranges()[1]);
 
-  )cpp");
-  auto speculate = [&](StringRef PointName) {
-    auto Filter = speculateCompletionFilter(F.code(), F.point(PointName));
-    assert(Filter);
-    return *Filter;
-  };
-  EXPECT_EQ(speculate("bof"), "");
-  EXPECT_EQ(speculate("bol"), "");
-  EXPECT_EQ(speculate("ab"), "ab");
-  EXPECT_EQ(speculate("dot"), "ab");
-  EXPECT_EQ(speculate("dotempty"), "");
-  EXPECT_EQ(speculate("scoped"), "ab");
-  EXPECT_EQ(speculate("scopedempty"), "");
+    auto Prefix = guessCompletionPrefix(F.code(), Offset);
+    // Even when components are empty, check their offsets are correct.
+    EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
+    EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
+    EXPECT_EQ(WantName, Prefix.Name) << Case;
+    EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
+  }
 }
 
 TEST(CompletionTest, EnableSpeculativeIndexRequest) {
@@ -2044,19 +2091,28 @@
               UnorderedElementsAre(Named("Clangd_Macro_Test")));
 }
 
-TEST(CompletionTest, NoMacroFromPreambleIfIndexIsSet) {
+TEST(CompletionTest, MacroFromPreamble) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  std::string FooHeader = testPath("foo.h");
+  FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n";
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
   auto Results = completions(
-      R"cpp(#define CLANGD_PREAMBLE x
+      R"cpp(#include "foo.h"
+          #define CLANGD_PREAMBLE_MAIN x
 
           int x = 0;
           #define CLANGD_MAIN x
           void f() { CLANGD_^ }
       )cpp",
       {func("CLANGD_INDEX")});
-  // Index is overriden in code completion options, so the preamble symbol is
-  // not seen.
-  EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("CLANGD_MAIN"),
-                                                        Named("CLANGD_INDEX")));
+  // We should get results from the main file, including the preamble section.
+  // However no results from included files (the index should cover them).
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(Named("CLANGD_PREAMBLE_MAIN"),
+                                   Named("CLANGD_MAIN"),
+                                   Named("CLANGD_INDEX")));
 }
 
 TEST(CompletionTest, DeprecatedResults) {
@@ -2320,6 +2376,176 @@
   EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}")));
 }
 
+TEST(CompletionTest, WorksWithNullType) {
+  auto R = completions(R"cpp(
+    int main() {
+      for (auto [loopVar] : y ) { // y has to be unresolved.
+        int z = loopV^;
+      }
+    }
+  )cpp");
+  EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar")));
+}
+
+TEST(CompletionTest, UsingDecl) {
+  const char *Header(R"cpp(
+    void foo(int);
+    namespace std {
+      using ::foo;
+    })cpp");
+  const char *Source(R"cpp(
+    void bar() {
+      std::^;
+    })cpp");
+  auto Index = TestTU::withHeaderCode(Header).index();
+  clangd::CodeCompleteOptions Opts;
+  Opts.Index = Index.get();
+  Opts.AllScopes = true;
+  auto R = completions(Source, {}, Opts);
+  EXPECT_THAT(R.Completions,
+              ElementsAre(AllOf(Scope("std::"), Named("foo"),
+                                Kind(CompletionItemKind::Reference))));
+}
+
+TEST(CompletionTest, ScopeIsUnresolved) {
+  clangd::CodeCompleteOptions Opts = {};
+  Opts.AllScopes = true;
+
+  auto Results = completions(R"cpp(
+    namespace a {
+    void f() { b::X^ }
+    }
+  )cpp",
+                             {cls("a::b::XYZ")}, Opts);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ"))));
+}
+
+TEST(CompletionTest, NestedScopeIsUnresolved) {
+  clangd::CodeCompleteOptions Opts = {};
+  Opts.AllScopes = true;
+
+  auto Results = completions(R"cpp(
+    namespace a {
+    namespace b {}
+    void f() { b::c::X^ }
+    }
+  )cpp",
+                             {cls("a::b::c::XYZ")}, Opts);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ"))));
+}
+
+// Clang parser gets confused here and doesn't report the ns:: prefix.
+// Naive behavior is to insert it again. We examine the source and recover.
+TEST(CompletionTest, NamespaceDoubleInsertion) {
+  clangd::CodeCompleteOptions Opts = {};
+
+  auto Results = completions(R"cpp(
+    namespace foo {
+    namespace ns {}
+    #define M(X) < X
+    M(ns::ABC^
+    }
+  )cpp",
+                             {cls("foo::ns::ABCDE")}, Opts);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(AllOf(Qualifier(""), Named("ABCDE"))));
+}
+
+TEST(NoCompileCompletionTest, Basic) {
+  auto Results = completionsNoCompile(R"cpp(
+    void func() {
+      int xyz;
+      int abc;
+      ^
+    }
+  )cpp");
+  EXPECT_FALSE(Results.RanParser);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(Named("void"), Named("func"), Named("int"),
+                                   Named("xyz"), Named("abc")));
+}
+
+TEST(NoCompileCompletionTest, WithFilter) {
+  auto Results = completionsNoCompile(R"cpp(
+    void func() {
+      int sym1;
+      int sym2;
+      int xyz1;
+      int xyz2;
+      sy^
+    }
+  )cpp");
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(Named("sym1"), Named("sym2")));
+}
+
+TEST(NoCompileCompletionTest, WithIndex) {
+  std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"),
+                              func("c::xxx"), func("ns::d::xxx")};
+  auto Results = completionsNoCompile(
+      R"cpp(
+        // Current-scopes, unqualified completion.
+        using namespace a;
+        namespace ns {
+        using namespace b;
+        void foo() {
+        xx^
+        }
+      )cpp",
+      Syms);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(AllOf(Qualifier(""), Scope("")),
+                                   AllOf(Qualifier(""), Scope("a::")),
+                                   AllOf(Qualifier(""), Scope("ns::b::"))));
+  CodeCompleteOptions Opts;
+  Opts.AllScopes = true;
+  Results = completionsNoCompile(
+      R"cpp(
+        // All-scopes unqualified completion.
+        using namespace a;
+        namespace ns {
+        using namespace b;
+        void foo() {
+        xx^
+        }
+      )cpp",
+      Syms, Opts);
+  EXPECT_THAT(Results.Completions,
+              UnorderedElementsAre(AllOf(Qualifier(""), Scope("")),
+                                   AllOf(Qualifier(""), Scope("a::")),
+                                   AllOf(Qualifier(""), Scope("ns::b::")),
+                                   AllOf(Qualifier("c::"), Scope("c::")),
+                                   AllOf(Qualifier("d::"), Scope("ns::d::"))));
+  Results = completionsNoCompile(
+      R"cpp(
+        // Qualified completion.
+        using namespace a;
+        namespace ns {
+        using namespace b;
+        void foo() {
+        b::xx^
+        }
+      )cpp",
+      Syms, Opts);
+  EXPECT_THAT(Results.Completions,
+              ElementsAre(AllOf(Qualifier(""), Scope("ns::b::"))));
+  Results = completionsNoCompile(
+      R"cpp(
+        // Absolutely qualified completion.
+        using namespace a;
+        namespace ns {
+        using namespace b;
+        void foo() {
+        ::a::xx^
+        }
+      )cpp",
+      Syms, Opts);
+  EXPECT_THAT(Results.Completions,
+              ElementsAre(AllOf(Qualifier(""), Scope("a::"))));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/CodeCompletionStringsTests.cpp b/clangd/unittests/CodeCompletionStringsTests.cpp
similarity index 95%
rename from unittests/clangd/CodeCompletionStringsTests.cpp
rename to clangd/unittests/CodeCompletionStringsTests.cpp
index eab35e1..43429c8 100644
--- a/unittests/clangd/CodeCompletionStringsTests.cpp
+++ b/clangd/unittests/CodeCompletionStringsTests.cpp
@@ -1,9 +1,8 @@
 //===-- CodeCompletionStringsTests.cpp --------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/ContextTests.cpp b/clangd/unittests/ContextTests.cpp
similarity index 87%
rename from unittests/clangd/ContextTests.cpp
rename to clangd/unittests/ContextTests.cpp
index d5cb3ce..d760f4e 100644
--- a/unittests/clangd/ContextTests.cpp
+++ b/clangd/unittests/ContextTests.cpp
@@ -1,9 +1,8 @@
 //===-- ContextTests.cpp - Context tests ------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/DexTests.cpp b/clangd/unittests/DexTests.cpp
similarity index 91%
rename from unittests/clangd/DexTests.cpp
rename to clangd/unittests/DexTests.cpp
index 078bae2..11aedec 100644
--- a/unittests/clangd/DexTests.cpp
+++ b/clangd/unittests/DexTests.cpp
@@ -1,9 +1,8 @@
 //===-- DexTests.cpp  ---------------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,6 +11,7 @@
 #include "TestIndex.h"
 #include "index/Index.h"
 #include "index/Merge.h"
+#include "index/SymbolID.h"
 #include "index/dex/Dex.h"
 #include "index/dex/Iterator.h"
 #include "index/dex/Token.h"
@@ -25,6 +25,7 @@
 
 using ::testing::AnyOf;
 using ::testing::ElementsAre;
+using ::testing::IsEmpty;
 using ::testing::UnorderedElementsAre;
 
 namespace clang {
@@ -351,16 +352,16 @@
 // Search token tests.
 //===----------------------------------------------------------------------===//
 
-testing::Matcher<std::vector<Token>>
+::testing::Matcher<std::vector<Token>>
 tokensAre(std::initializer_list<std::string> Strings, Token::Kind Kind) {
   std::vector<Token> Tokens;
   for (const auto &TokenData : Strings) {
     Tokens.push_back(Token(Kind, TokenData));
   }
-  return testing::UnorderedElementsAreArray(Tokens);
+  return ::testing::UnorderedElementsAreArray(Tokens);
 }
 
-testing::Matcher<std::vector<Token>>
+::testing::Matcher<std::vector<Token>>
 trigramsAre(std::initializer_list<std::string> Trigrams) {
   return tokensAre(Trigrams, Token::Kind::Trigram);
 }
@@ -689,6 +690,63 @@
   EXPECT_THAT(Files, ElementsAre(AnyOf("foo.h", "foo.cc")));
 }
 
+TEST(DexTest, PreferredTypesBoosting) {
+  auto Sym1 = symbol("t1");
+  Sym1.Type = "T1";
+  auto Sym2 = symbol("t2");
+  Sym2.Type = "T2";
+
+  std::vector<Symbol> Symbols{Sym1, Sym2};
+  Dex I(Symbols, RefSlab());
+
+  FuzzyFindRequest Req;
+  Req.AnyScope = true;
+  Req.Query = "t";
+  // The best candidate can change depending on the preferred type.
+  Req.Limit = 1;
+
+  Req.PreferredTypes = {Sym1.Type};
+  EXPECT_THAT(match(I, Req), ElementsAre("t1"));
+
+  Req.PreferredTypes = {Sym2.Type};
+  EXPECT_THAT(match(I, Req), ElementsAre("t2"));
+}
+
+TEST(DexTest, TemplateSpecialization) {
+  SymbolSlab::Builder B;
+
+  Symbol S = symbol("TempSpec");
+  S.ID = SymbolID("0");
+  B.insert(S);
+
+  S = symbol("TempSpec");
+  S.ID = SymbolID("1");
+  S.TemplateSpecializationArgs = "<int, bool>";
+  S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+      index::SymbolProperty::TemplateSpecialization);
+  B.insert(S);
+
+  S = symbol("TempSpec");
+  S.ID = SymbolID("2");
+  S.TemplateSpecializationArgs = "<int, U>";
+  S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+      index::SymbolProperty::TemplatePartialSpecialization);
+  B.insert(S);
+
+  auto I = dex::Dex::build(std::move(B).build(), RefSlab());
+  FuzzyFindRequest Req;
+  Req.AnyScope = true;
+
+  Req.Query = "TempSpec";
+  EXPECT_THAT(match(*I, Req),
+              UnorderedElementsAre("TempSpec", "TempSpec<int, bool>",
+                                   "TempSpec<int, U>"));
+
+  // FIXME: Add filtering for template argument list.
+  Req.Query = "TempSpec<int";
+  EXPECT_THAT(match(*I, Req), IsEmpty());
+}
+
 } // namespace
 } // namespace dex
 } // namespace clangd
diff --git a/clangd/unittests/DiagnosticsTests.cpp b/clangd/unittests/DiagnosticsTests.cpp
new file mode 100644
index 0000000..826428c
--- /dev/null
+++ b/clangd/unittests/DiagnosticsTests.cpp
@@ -0,0 +1,773 @@
+//===--- DiagnosticsTests.cpp ------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "ClangdUnit.h"
+#include "Diagnostics.h"
+#include "Path.h"
+#include "Protocol.h"
+#include "SourceCode.h"
+#include "TestFS.h"
+#include "TestIndex.h"
+#include "TestTU.h"
+#include "index/MemIndex.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <algorithm>
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::Pair;
+using ::testing::UnorderedElementsAre;
+
+::testing::Matcher<const Diag &> WithFix(::testing::Matcher<Fix> FixMatcher) {
+  return Field(&Diag::Fixes, ElementsAre(FixMatcher));
+}
+
+::testing::Matcher<const Diag &> WithFix(::testing::Matcher<Fix> FixMatcher1,
+                                         ::testing::Matcher<Fix> FixMatcher2) {
+  return Field(&Diag::Fixes, UnorderedElementsAre(FixMatcher1, FixMatcher2));
+}
+
+::testing::Matcher<const Diag &>
+WithNote(::testing::Matcher<Note> NoteMatcher) {
+  return Field(&Diag::Notes, ElementsAre(NoteMatcher));
+}
+
+MATCHER_P2(Diag, Range, Message,
+           "Diag at " + llvm::to_string(Range) + " = [" + Message + "]") {
+  return arg.Range == Range && arg.Message == Message;
+}
+
+MATCHER_P3(Fix, Range, Replacement, Message,
+           "Fix " + llvm::to_string(Range) + " => " +
+               ::testing::PrintToString(Replacement) + " = [" + Message + "]") {
+  return arg.Message == Message && arg.Edits.size() == 1 &&
+         arg.Edits[0].range == Range && arg.Edits[0].newText == Replacement;
+}
+
+MATCHER_P(EqualToLSPDiag, LSPDiag,
+          "LSP diagnostic " + llvm::to_string(LSPDiag)) {
+  if (toJSON(arg) != toJSON(LSPDiag)) {
+    *result_listener << llvm::formatv("expected:\n{0:2}\ngot\n{1:2}",
+                                      toJSON(LSPDiag), toJSON(arg))
+                            .str();
+    return false;
+  }
+  return true;
+}
+
+MATCHER_P(DiagSource, S, "") { return arg.Source == S; }
+MATCHER_P(DiagName, N, "") { return arg.Name == N; }
+
+MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) {
+  if (arg.Message != Fix.Message)
+    return false;
+  if (arg.Edits.size() != Fix.Edits.size())
+    return false;
+  for (std::size_t I = 0; I < arg.Edits.size(); ++I) {
+    if (arg.Edits[I].range != Fix.Edits[I].range ||
+        arg.Edits[I].newText != Fix.Edits[I].newText)
+      return false;
+  }
+  return true;
+}
+
+// Helper function to make tests shorter.
+Position pos(int line, int character) {
+  Position Res;
+  Res.line = line;
+  Res.character = character;
+  return Res;
+}
+
+TEST(DiagnosticsTest, DiagnosticRanges) {
+  // Check we report correct ranges, including various edge-cases.
+  Annotations Test(R"cpp(
+    namespace test{};
+    void $decl[[foo]]();
+    int main() {
+      $typo[[go\
+o]]();
+      foo()$semicolon[[]]//with comments
+      $unk[[unknown]]();
+      double $type[[bar]] = "foo";
+      struct Foo { int x; }; Foo a;
+      a.$nomember[[y]];
+      test::$nomembernamespace[[test]];
+    }
+  )cpp");
+  EXPECT_THAT(
+      TestTU::withCode(Test.code()).build().getDiagnostics(),
+      ElementsAre(
+          // This range spans lines.
+          AllOf(Diag(Test.range("typo"),
+                     "use of undeclared identifier 'goo'; did you mean 'foo'?"),
+                DiagSource(Diag::Clang), DiagName("undeclared_var_use_suggest"),
+                WithFix(
+                    Fix(Test.range("typo"), "foo", "change 'go\\ o' to 'foo'")),
+                // This is a pretty normal range.
+                WithNote(Diag(Test.range("decl"), "'foo' declared here"))),
+          // This range is zero-width and insertion. Therefore make sure we are
+          // not expanding it into other tokens. Since we are not going to
+          // replace those.
+          AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"),
+                WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))),
+          // This range isn't provided by clang, we expand to the token.
+          Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"),
+          Diag(Test.range("type"),
+               "cannot initialize a variable of type 'double' with an lvalue "
+               "of type 'const char [4]'"),
+          Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"),
+          Diag(Test.range("nomembernamespace"),
+               "no member named 'test' in namespace 'test'")));
+}
+
+TEST(DiagnosticsTest, FlagsMatter) {
+  Annotations Test("[[void]] main() {}");
+  auto TU = TestTU::withCode(Test.code());
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"),
+                                WithFix(Fix(Test.range(), "int",
+                                            "change 'void' to 'int'")))));
+  // Same code built as C gets different diagnostics.
+  TU.Filename = "Plain.c";
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      ElementsAre(AllOf(
+          Diag(Test.range(), "return type of 'main' is not 'int'"),
+          WithFix(Fix(Test.range(), "int", "change return type to 'int'")))));
+}
+
+TEST(DiagnosticsTest, DiagnosticPreamble) {
+  Annotations Test(R"cpp(
+    #include $[["not-found.h"]]
+  )cpp");
+
+  auto TU = TestTU::withCode(Test.code());
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              ElementsAre(::testing::AllOf(
+                  Diag(Test.range(), "'not-found.h' file not found"),
+                  DiagSource(Diag::Clang), DiagName("pp_file_not_found"))));
+}
+
+TEST(DiagnosticsTest, ClangTidy) {
+  Annotations Test(R"cpp(
+    #include $deprecated[["assert.h"]]
+
+    #define $macrodef[[SQUARE]](X) (X)*(X)
+    int main() {
+      return $doubled[[sizeof]](sizeof(int));
+    }
+    int square() {
+      int y = 4;
+      return SQUARE($macroarg[[++]]y);
+    }
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  TU.HeaderFilename = "assert.h"; // Suppress "not found" error.
+  TU.ClangTidyChecks =
+      "-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, "
+      "modernize-deprecated-headers";
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(
+          AllOf(Diag(Test.range("deprecated"),
+                     "inclusion of deprecated C++ header 'assert.h'; consider "
+                     "using 'cassert' instead"),
+                DiagSource(Diag::ClangTidy),
+                DiagName("modernize-deprecated-headers"),
+                WithFix(Fix(Test.range("deprecated"), "<cassert>",
+                            "change '\"assert.h\"' to '<cassert>'"))),
+          Diag(Test.range("doubled"),
+               "suspicious usage of 'sizeof(sizeof(...))'"),
+          AllOf(
+              Diag(Test.range("macroarg"),
+                   "side effects in the 1st macro argument 'X' are repeated in "
+                   "macro expansion"),
+              DiagSource(Diag::ClangTidy),
+              DiagName("bugprone-macro-repeated-side-effects"),
+              WithNote(
+                  Diag(Test.range("macrodef"), "macro 'SQUARE' defined here"))),
+          Diag(Test.range("macroarg"),
+               "multiple unsequenced modifications to 'y'")));
+}
+
+TEST(DiagnosticsTest, Preprocessor) {
+  // This looks like a preamble, but there's an #else in the middle!
+  // Check that:
+  //  - the #else doesn't generate diagnostics (we had this bug)
+  //  - we get diagnostics from the taken branch
+  //  - we get no diagnostics from the not taken branch
+  Annotations Test(R"cpp(
+    #ifndef FOO
+    #define FOO
+      int a = [[b]];
+    #else
+      int x = y;
+    #endif
+    )cpp");
+  EXPECT_THAT(
+      TestTU::withCode(Test.code()).build().getDiagnostics(),
+      ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'")));
+}
+
+TEST(DiagnosticsTest, InsideMacros) {
+  Annotations Test(R"cpp(
+    #define TEN 10
+    #define RET(x) return x + 10
+
+    int* foo() {
+      RET($foo[[0]]);
+    }
+    int* bar() {
+      return $bar[[TEN]];
+    }
+    )cpp");
+  EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(),
+              ElementsAre(Diag(Test.range("foo"),
+                               "cannot initialize return object of type "
+                               "'int *' with an rvalue of type 'int'"),
+                          Diag(Test.range("bar"),
+                               "cannot initialize return object of type "
+                               "'int *' with an rvalue of type 'int'")));
+}
+
+TEST(DiagnosticsTest, NoFixItInMacro) {
+  Annotations Test(R"cpp(
+    #define Define(name) void name() {}
+
+    [[Define]](main)
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"),
+                                Not(WithFix(_)))));
+}
+
+TEST(DiagnosticsTest, ToLSP) {
+  URIForFile MainFile =
+      URIForFile::canonicalize(testPath("foo/bar/main.cpp"), "");
+  URIForFile HeaderFile =
+      URIForFile::canonicalize(testPath("foo/bar/header.h"), "");
+
+  clangd::Diag D;
+  D.ID = clang::diag::err_enum_class_reference;
+  D.Name = "enum_class_reference";
+  D.Source = clangd::Diag::Clang;
+  D.Message = "something terrible happened";
+  D.Range = {pos(1, 2), pos(3, 4)};
+  D.InsideMainFile = true;
+  D.Severity = DiagnosticsEngine::Error;
+  D.File = "foo/bar/main.cpp";
+  D.AbsFile = MainFile.file();
+
+  clangd::Note NoteInMain;
+  NoteInMain.Message = "declared somewhere in the main file";
+  NoteInMain.Range = {pos(5, 6), pos(7, 8)};
+  NoteInMain.Severity = DiagnosticsEngine::Remark;
+  NoteInMain.File = "../foo/bar/main.cpp";
+  NoteInMain.InsideMainFile = true;
+  NoteInMain.AbsFile = MainFile.file();
+
+  D.Notes.push_back(NoteInMain);
+
+  clangd::Note NoteInHeader;
+  NoteInHeader.Message = "declared somewhere in the header file";
+  NoteInHeader.Range = {pos(9, 10), pos(11, 12)};
+  NoteInHeader.Severity = DiagnosticsEngine::Note;
+  NoteInHeader.File = "../foo/baz/header.h";
+  NoteInHeader.InsideMainFile = false;
+  NoteInHeader.AbsFile = HeaderFile.file();
+  D.Notes.push_back(NoteInHeader);
+
+  clangd::Fix F;
+  F.Message = "do something";
+  D.Fixes.push_back(F);
+
+  // Diagnostics should turn into these:
+  clangd::Diagnostic MainLSP;
+  MainLSP.range = D.Range;
+  MainLSP.severity = getSeverity(DiagnosticsEngine::Error);
+  MainLSP.code = "enum_class_reference";
+  MainLSP.source = "clang";
+  MainLSP.message =
+      R"(Something terrible happened (fix available)
+
+main.cpp:6:7: remark: declared somewhere in the main file
+
+../foo/baz/header.h:10:11:
+note: declared somewhere in the header file)";
+
+  clangd::Diagnostic NoteInMainLSP;
+  NoteInMainLSP.range = NoteInMain.Range;
+  NoteInMainLSP.severity = getSeverity(DiagnosticsEngine::Remark);
+  NoteInMainLSP.message = R"(Declared somewhere in the main file
+
+main.cpp:2:3: error: something terrible happened)";
+
+  ClangdDiagnosticOptions Opts;
+  // Transform diagnostics and check the results.
+  std::vector<std::pair<clangd::Diagnostic, std::vector<clangd::Fix>>> LSPDiags;
+  toLSPDiags(D, MainFile, Opts,
+             [&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix> Fixes) {
+               LSPDiags.push_back(
+                   {std::move(LSPDiag),
+                    std::vector<clangd::Fix>(Fixes.begin(), Fixes.end())});
+             });
+
+  EXPECT_THAT(
+      LSPDiags,
+      ElementsAre(Pair(EqualToLSPDiag(MainLSP), ElementsAre(EqualToFix(F))),
+                  Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty())));
+  EXPECT_EQ(LSPDiags[0].first.code, "enum_class_reference");
+  EXPECT_EQ(LSPDiags[0].first.source, "clang");
+  EXPECT_EQ(LSPDiags[1].first.code, "");
+  EXPECT_EQ(LSPDiags[1].first.source, "");
+
+  // Same thing, but don't flatten notes into the main list.
+  LSPDiags.clear();
+  Opts.EmitRelatedLocations = true;
+  toLSPDiags(D, MainFile, Opts,
+             [&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix> Fixes) {
+               LSPDiags.push_back(
+                   {std::move(LSPDiag),
+                    std::vector<clangd::Fix>(Fixes.begin(), Fixes.end())});
+             });
+  MainLSP.message = "Something terrible happened (fix available)";
+  DiagnosticRelatedInformation NoteInMainDRI;
+  NoteInMainDRI.message = "Declared somewhere in the main file";
+  NoteInMainDRI.location.range = NoteInMain.Range;
+  NoteInMainDRI.location.uri = MainFile;
+  MainLSP.relatedInformation = {NoteInMainDRI};
+  DiagnosticRelatedInformation NoteInHeaderDRI;
+  NoteInHeaderDRI.message = "Declared somewhere in the header file";
+  NoteInHeaderDRI.location.range = NoteInHeader.Range;
+  NoteInHeaderDRI.location.uri = HeaderFile;
+  MainLSP.relatedInformation = {NoteInMainDRI, NoteInHeaderDRI};
+  EXPECT_THAT(LSPDiags, ElementsAre(Pair(EqualToLSPDiag(MainLSP),
+                                         ElementsAre(EqualToFix(F)))));
+}
+
+struct SymbolWithHeader {
+  std::string QName;
+  std::string DeclaringFile;
+  std::string IncludeHeader;
+};
+
+std::unique_ptr<SymbolIndex>
+buildIndexWithSymbol(llvm::ArrayRef<SymbolWithHeader> Syms) {
+  SymbolSlab::Builder Slab;
+  for (const auto &S : Syms) {
+    Symbol Sym = cls(S.QName);
+    Sym.Flags |= Symbol::IndexedForCodeCompletion;
+    Sym.CanonicalDeclaration.FileURI = S.DeclaringFile.c_str();
+    Sym.Definition.FileURI = S.DeclaringFile.c_str();
+    Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1);
+    Slab.insert(Sym);
+  }
+  return MemIndex::build(std::move(Slab).build(), RefSlab());
+}
+
+TEST(IncludeFixerTest, IncompleteType) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace ns {
+  class X;
+  $nested[[X::]]Nested n;
+}
+class Y : $base[[public ns::X]] {};
+int main() {
+  ns::X *x;
+  x$access[[->]]f();
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      {SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""}});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(
+          AllOf(Diag(Test.range("nested"),
+                     "incomplete type 'ns::X' named in nested name specifier"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X"))),
+          AllOf(Diag(Test.range("base"), "base class has incomplete type"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X"))),
+          AllOf(Diag(Test.range("access"),
+                     "member access into incomplete type 'ns::X'"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X")))));
+}
+
+TEST(IncludeFixerTest, NoSuggestIncludeWhenNoDefinitionInHeader) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace ns {
+  class X;
+}
+class Y : $base[[public ns::X]] {};
+int main() {
+  ns::X *x;
+  x$access[[->]]f();
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  Symbol Sym = cls("ns::X");
+  Sym.Flags |= Symbol::IndexedForCodeCompletion;
+  Sym.CanonicalDeclaration.FileURI = "unittest:///x.h";
+  Sym.Definition.FileURI = "unittest:///x.cc";
+  Sym.IncludeHeaders.emplace_back("\"x.h\"", 1);
+
+  SymbolSlab::Builder Slab;
+  Slab.insert(Sym);
+  auto Index = MemIndex::build(std::move(Slab).build(), RefSlab());
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(
+                  Diag(Test.range("base"), "base class has incomplete type"),
+                  Diag(Test.range("access"),
+                       "member access into incomplete type 'ns::X'")));
+}
+
+TEST(IncludeFixerTest, Typo) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace ns {
+void foo() {
+  $unqualified1[[X]] x;
+  // No fix if the unresolved type is used as specifier. (ns::)X::Nested will be
+  // considered the unresolved type.
+  $unqualified2[[X]]::Nested n;
+}
+}
+void bar() {
+  ns::$qualified1[[X]] x; // ns:: is valid.
+  ns::$qualified2[[X]](); // Error: no member in namespace
+
+  ::$global[[Global]] glob;
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      {SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""},
+       SymbolWithHeader{"Global", "unittest:///global.h", "\"global.h\""}});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(
+          AllOf(Diag(Test.range("unqualified1"), "unknown type name 'X'"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X"))),
+          Diag(Test.range("unqualified2"), "use of undeclared identifier 'X'"),
+          AllOf(Diag(Test.range("qualified1"),
+                     "no type named 'X' in namespace 'ns'"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X"))),
+          AllOf(Diag(Test.range("qualified2"),
+                     "no member named 'X' in namespace 'ns'"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::X"))),
+          AllOf(Diag(Test.range("global"),
+                     "no type named 'Global' in the global namespace"),
+                WithFix(Fix(Test.range("insert"), "#include \"global.h\"\n",
+                            "Add include \"global.h\" for symbol Global")))));
+}
+
+TEST(IncludeFixerTest, MultipleMatchedSymbols) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace na {
+namespace nb {
+void foo() {
+  $unqualified[[X]] x;
+}
+}
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      {SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""},
+       SymbolWithHeader{"na::nb::X", "unittest:///b.h", "\"b.h\""}});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(AllOf(
+                  Diag(Test.range("unqualified"), "unknown type name 'X'"),
+                  WithFix(Fix(Test.range("insert"), "#include \"a.h\"\n",
+                              "Add include \"a.h\" for symbol na::X"),
+                          Fix(Test.range("insert"), "#include \"b.h\"\n",
+                              "Add include \"b.h\" for symbol na::nb::X")))));
+}
+
+TEST(IncludeFixerTest, NoCrashMemebrAccess) {
+  Annotations Test(R"cpp(
+    struct X { int  xyz; };
+    void g() { X x; x.$[[xy]] }
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'")));
+}
+
+TEST(IncludeFixerTest, UseCachedIndexResults) {
+  // As index results for the identical request are cached, more than 5 fixes
+  // are generated.
+  Annotations Test(R"cpp(
+$insert[[]]void foo() {
+  $x1[[X]] x;
+  $x2[[X]] x;
+  $x3[[X]] x;
+  $x4[[X]] x;
+  $x5[[X]] x;
+  $x6[[X]] x;
+  $x7[[X]] x;
+}
+
+class X;
+void bar(X *x) {
+  x$a1[[->]]f();
+  x$a2[[->]]f();
+  x$a3[[->]]f();
+  x$a4[[->]]f();
+  x$a5[[->]]f();
+  x$a6[[->]]f();
+  x$a7[[->]]f();
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index =
+      buildIndexWithSymbol(SymbolWithHeader{"X", "unittest:///a.h", "\"a.h\""});
+  TU.ExternalIndex = Index.get();
+
+  auto Parsed = TU.build();
+  for (const auto &D : Parsed.getDiagnostics()) {
+    EXPECT_EQ(D.Fixes.size(), 1u);
+    EXPECT_EQ(D.Fixes[0].Message,
+              std::string("Add include \"a.h\" for symbol X"));
+  }
+}
+
+TEST(IncludeFixerTest, UnresolvedNameAsSpecifier) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace ns {
+}
+void g() {  ns::$[[scope]]::X_Y();  }
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      SymbolWithHeader{"ns::scope::X_Y", "unittest:///x.h", "\"x.h\""});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(AllOf(
+          Diag(Test.range(), "no member named 'scope' in namespace 'ns'"),
+          WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                      "Add include \"x.h\" for symbol ns::scope::X_Y")))));
+}
+
+TEST(IncludeFixerTest, UnresolvedSpecifierWithSemaCorrection) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace clang {
+void f() {
+  // "clangd::" will be corrected to "clang::" by Sema.
+  $q1[[clangd]]::$x[[X]] x;
+  $q2[[clangd]]::$ns[[ns]]::Y y;
+}
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      {SymbolWithHeader{"clang::clangd::X", "unittest:///x.h", "\"x.h\""},
+       SymbolWithHeader{"clang::clangd::ns::Y", "unittest:///y.h", "\"y.h\""}});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(
+          AllOf(
+              Diag(Test.range("q1"), "use of undeclared identifier 'clangd'; "
+                                     "did you mean 'clang'?"),
+              WithFix(_, // change clangd to clang
+                      Fix(Test.range("insert"), "#include \"x.h\"\n",
+                          "Add include \"x.h\" for symbol clang::clangd::X"))),
+          AllOf(
+              Diag(Test.range("x"), "no type named 'X' in namespace 'clang'"),
+              WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                          "Add include \"x.h\" for symbol clang::clangd::X"))),
+          AllOf(
+              Diag(Test.range("q2"), "use of undeclared identifier 'clangd'; "
+                                     "did you mean 'clang'?"),
+              WithFix(
+                  _, // change clangd to clangd
+                  Fix(Test.range("insert"), "#include \"y.h\"\n",
+                      "Add include \"y.h\" for symbol clang::clangd::ns::Y"))),
+          AllOf(Diag(Test.range("ns"),
+                     "no member named 'ns' in namespace 'clang'"),
+                WithFix(Fix(
+                    Test.range("insert"), "#include \"y.h\"\n",
+                    "Add include \"y.h\" for symbol clang::clangd::ns::Y")))));
+}
+
+TEST(IncludeFixerTest, SpecifiedScopeIsNamespaceAlias) {
+  Annotations Test(R"cpp(
+$insert[[]]namespace a {}
+namespace b = a;
+namespace c {
+  b::$[[X]] x;
+}
+  )cpp");
+  auto TU = TestTU::withCode(Test.code());
+  auto Index = buildIndexWithSymbol(
+      SymbolWithHeader{"a::X", "unittest:///x.h", "\"x.h\""});
+  TU.ExternalIndex = Index.get();
+
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(AllOf(
+                  Diag(Test.range(), "no type named 'X' in namespace 'a'"),
+                  WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                              "Add include \"x.h\" for symbol a::X")))));
+}
+
+TEST(DiagsInHeaders, DiagInsideHeader) {
+  Annotations Main(R"cpp(
+    #include [["a.h"]]
+    void foo() {})cpp");
+  Annotations Header("[[no_type_spec]];");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", Header.code()}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(AllOf(
+                  Diag(Main.range(), "in included file: C++ requires a "
+                                     "type specifier for all declarations"),
+                  WithNote(Diag(Header.range(), "error occurred here")))));
+}
+
+TEST(DiagsInHeaders, DiagInTransitiveInclude) {
+  Annotations Main(R"cpp(
+    #include [["a.h"]]
+    void foo() {})cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", "#include \"b.h\""}, {"b.h", "no_type_spec;"}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(
+                  Diag(Main.range(), "in included file: C++ requires a "
+                                     "type specifier for all declarations")));
+}
+
+TEST(DiagsInHeaders, DiagInMultipleHeaders) {
+  Annotations Main(R"cpp(
+    #include $a[["a.h"]]
+    #include $b[["b.h"]]
+    void foo() {})cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", "no_type_spec;"}, {"b.h", "no_type_spec;"}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(
+                  Diag(Main.range("a"), "in included file: C++ requires a type "
+                                        "specifier for all declarations"),
+                  Diag(Main.range("b"), "in included file: C++ requires a type "
+                                        "specifier for all declarations")));
+}
+
+TEST(DiagsInHeaders, PreferExpansionLocation) {
+  Annotations Main(R"cpp(
+    #include [["a.h"]]
+    #include "b.h"
+    void foo() {})cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", "#include \"b.h\"\n"},
+                        {"b.h", "#ifndef X\n#define X\nno_type_spec;\n#endif"}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(Diag(Main.range(),
+                                        "in included file: C++ requires a type "
+                                        "specifier for all declarations")));
+}
+
+TEST(DiagsInHeaders, PreferExpansionLocationMacros) {
+  Annotations Main(R"cpp(
+    #define X
+    #include "a.h"
+    #undef X
+    #include [["b.h"]]
+    void foo() {})cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", "#include \"c.h\"\n"},
+                        {"b.h", "#include \"c.h\"\n"},
+                        {"c.h", "#ifndef X\n#define X\nno_type_spec;\n#endif"}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(
+                  Diag(Main.range(), "in included file: C++ requires a "
+                                     "type specifier for all declarations")));
+}
+
+TEST(DiagsInHeaders, LimitDiagsOutsideMainFile) {
+  Annotations Main(R"cpp(
+    #include [["a.h"]]
+    #include "b.h"
+    void foo() {})cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", "#include \"c.h\"\n"},
+                        {"b.h", "#include \"c.h\"\n"},
+                        {"c.h", R"cpp(
+      #ifndef X
+      #define X
+      no_type_spec_0;
+      no_type_spec_1;
+      no_type_spec_2;
+      no_type_spec_3;
+      no_type_spec_4;
+      no_type_spec_5;
+      no_type_spec_6;
+      no_type_spec_7;
+      no_type_spec_8;
+      no_type_spec_9;
+      no_type_spec_10;
+      #endif)cpp"}};
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(
+                  Diag(Main.range(), "in included file: C++ requires a "
+                                     "type specifier for all declarations")));
+}
+
+TEST(DiagsInHeaders, OnlyErrorOrFatal) {
+  Annotations Main(R"cpp(
+    #include [["a.h"]]
+    void foo() {})cpp");
+  Annotations Header(R"cpp(
+    [[no_type_spec]];
+    int x = 5/0;)cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.AdditionalFiles = {{"a.h", Header.code()}};
+  auto diags = TU.build().getDiagnostics();
+  EXPECT_THAT(TU.build().getDiagnostics(),
+              UnorderedElementsAre(AllOf(
+                  Diag(Main.range(), "in included file: C++ requires "
+                                     "a type specifier for all declarations"),
+                  WithNote(Diag(Header.range(), "error occurred here")))));
+}
+} // namespace
+
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/DraftStoreTests.cpp b/clangd/unittests/DraftStoreTests.cpp
similarity index 95%
rename from unittests/clangd/DraftStoreTests.cpp
rename to clangd/unittests/DraftStoreTests.cpp
index 78057f3..1840892 100644
--- a/unittests/clangd/DraftStoreTests.cpp
+++ b/clangd/unittests/DraftStoreTests.cpp
@@ -1,9 +1,8 @@
 //===-- DraftStoreTests.cpp -------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -241,7 +240,7 @@
 
   EXPECT_TRUE(!Result);
   EXPECT_EQ(toString(Result.takeError()),
-            "UTF-16 offset 100 is invalid for line 0");
+            "utf-16 offset 100 is invalid for line 0");
 }
 
 TEST(DraftStoreIncrementalUpdateTest, EndCharOutOfRange) {
@@ -262,7 +261,7 @@
 
   EXPECT_TRUE(!Result);
   EXPECT_EQ(toString(Result.takeError()),
-            "UTF-16 offset 100 is invalid for line 0");
+            "utf-16 offset 100 is invalid for line 0");
 }
 
 TEST(DraftStoreIncrementalUpdateTest, StartLineOutOfRange) {
@@ -336,7 +335,7 @@
 
   EXPECT_TRUE(!Result);
   EXPECT_EQ(toString(Result.takeError()),
-            "UTF-16 offset 100 is invalid for line 0");
+            "utf-16 offset 100 is invalid for line 0");
 
   Optional<std::string> Contents = DS.getDraft(File);
   EXPECT_TRUE(Contents);
diff --git a/unittests/clangd/ExpectedTypeTest.cpp b/clangd/unittests/ExpectedTypeTest.cpp
similarity index 94%
rename from unittests/clangd/ExpectedTypeTest.cpp
rename to clangd/unittests/ExpectedTypeTest.cpp
index de3b486..8d2d60e 100644
--- a/unittests/clangd/ExpectedTypeTest.cpp
+++ b/clangd/unittests/ExpectedTypeTest.cpp
@@ -1,9 +1,8 @@
 //===-- ExpectedTypeTest.cpp  -----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "llvm/ADT/StringRef.h"
-#include "gmock/gmock-matchers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/unittests/clangd/FSTests.cpp b/clangd/unittests/FSTests.cpp
similarity index 87%
rename from unittests/clangd/FSTests.cpp
rename to clangd/unittests/FSTests.cpp
index 6c0bfec..044452c 100644
--- a/unittests/clangd/FSTests.cpp
+++ b/clangd/unittests/FSTests.cpp
@@ -1,9 +1,8 @@
 //===-- FSTests.cpp - File system related tests -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/FileDistanceTests.cpp b/clangd/unittests/FileDistanceTests.cpp
similarity index 94%
rename from unittests/clangd/FileDistanceTests.cpp
rename to clangd/unittests/FileDistanceTests.cpp
index 6d7d477..3003582 100644
--- a/unittests/clangd/FileDistanceTests.cpp
+++ b/clangd/unittests/FileDistanceTests.cpp
@@ -1,9 +1,8 @@
 //===-- FileDistanceTests.cpp  ------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/FileIndexTests.cpp b/clangd/unittests/FileIndexTests.cpp
similarity index 79%
rename from unittests/clangd/FileIndexTests.cpp
rename to clangd/unittests/FileIndexTests.cpp
index c3b11ae..142e255 100644
--- a/unittests/clangd/FileIndexTests.cpp
+++ b/clangd/unittests/FileIndexTests.cpp
@@ -1,9 +1,8 @@
 //===-- FileIndexTests.cpp  ---------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,10 +12,10 @@
 #include "SyncAPI.h"
 #include "TestFS.h"
 #include "TestTU.h"
+#include "index/CanonicalIncludes.h"
 #include "index/FileIndex.h"
 #include "index/Index.h"
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Lex/Preprocessor.h"
@@ -24,13 +23,13 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using testing::_;
-using testing::AllOf;
-using testing::Contains;
-using testing::ElementsAre;
-using testing::IsEmpty;
-using testing::Pair;
-using testing::UnorderedElementsAre;
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::Pair;
+using ::testing::UnorderedElementsAre;
 
 MATCHER_P(RefRange, Range, "") {
   return std::make_tuple(arg.Location.Start.line(), arg.Location.Start.column(),
@@ -50,9 +49,9 @@
 namespace clang {
 namespace clangd {
 namespace {
-testing::Matcher<const RefSlab &>
-RefsAre(std::vector<testing::Matcher<Ref>> Matchers) {
-  return ElementsAre(testing::Pair(_, UnorderedElementsAreArray(Matchers)));
+::testing::Matcher<const RefSlab &>
+RefsAre(std::vector<::testing::Matcher<Ref>> Matchers) {
+  return ElementsAre(::testing::Pair(_, UnorderedElementsAreArray(Matchers)));
 }
 
 Symbol symbol(llvm::StringRef ID) {
@@ -148,8 +147,8 @@
   File.HeaderFilename = (Basename + ".h").str();
   File.HeaderCode = Code;
   auto AST = File.build();
-  M.updatePreamble(File.Filename, AST.getASTContext(),
-                   AST.getPreprocessorPtr());
+  M.updatePreamble(File.Filename, AST.getASTContext(), AST.getPreprocessorPtr(),
+                   AST.getCanonicalIncludes());
 }
 
 TEST(FileIndexTest, CustomizedURIScheme) {
@@ -200,13 +199,27 @@
                                    QName("X::f")));
 }
 
-TEST(FileIndexTest, NoIncludeCollected) {
+TEST(FileIndexTest, IncludeCollected) {
   FileIndex M;
-  update(M, "f", "class string {};");
+  update(
+      M, "f",
+      "// IWYU pragma: private, include <the/good/header.h>\nclass string {};");
 
   auto Symbols = runFuzzyFind(M, "");
   EXPECT_THAT(Symbols, ElementsAre(_));
-  EXPECT_THAT(Symbols.begin()->IncludeHeaders, IsEmpty());
+  EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader,
+              "<the/good/header.h>");
+}
+
+TEST(FileIndexTest, HasSystemHeaderMappingsInPreamble) {
+  TestTU TU;
+  TU.HeaderCode = "class Foo{};";
+  TU.HeaderFilename = "algorithm";
+
+  auto Symbols = runFuzzyFind(*TU.index(), "");
+  EXPECT_THAT(Symbols, ElementsAre(_));
+  EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader,
+              "<algorithm>");
 }
 
 TEST(FileIndexTest, TemplateParamsInLabel) {
@@ -270,11 +283,12 @@
   bool IndexUpdated = false;
   buildPreamble(
       FooCpp, *CI, /*OldPreamble=*/nullptr, tooling::CompileCommand(), PI,
-      std::make_shared<PCHContainerOperations>(), /*StoreInMemory=*/true,
-      [&](ASTContext &Ctx, std::shared_ptr<Preprocessor> PP) {
+      /*StoreInMemory=*/true,
+      [&](ASTContext &Ctx, std::shared_ptr<Preprocessor> PP,
+          const CanonicalIncludes &CanonIncludes) {
         EXPECT_FALSE(IndexUpdated) << "Expected only a single index update";
         IndexUpdated = true;
-        Index.updatePreamble(FooCpp, Ctx, std::move(PP));
+        Index.updatePreamble(FooCpp, Ctx, std::move(PP), CanonIncludes);
       });
   ASSERT_TRUE(IndexUpdated);
 
@@ -333,49 +347,23 @@
 }
 
 TEST(FileIndexTest, ReferencesInMainFileWithPreamble) {
-  const std::string Header = R"cpp(
-    class Foo {};
-  )cpp";
+  TestTU TU;
+  TU.HeaderCode = "class Foo{};";
   Annotations Main(R"cpp(
     #include "foo.h"
     void f() {
       [[Foo]] foo;
     }
   )cpp");
-  auto MainFile = testPath("foo.cpp");
-  auto HeaderFile = testPath("foo.h");
-  std::vector<const char *> Cmd = {"clang", "-xc++", MainFile.c_str()};
-  // Preparse ParseInputs.
-  ParseInputs PI;
-  PI.CompileCommand.Directory = testRoot();
-  PI.CompileCommand.Filename = MainFile;
-  PI.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
-  PI.Contents = Main.code();
-  PI.FS = buildTestFS({{MainFile, Main.code()}, {HeaderFile, Header}});
-
-  // Prepare preamble.
-  auto CI = buildCompilerInvocation(PI);
-  auto PreambleData = buildPreamble(
-      MainFile, *buildCompilerInvocation(PI), /*OldPreamble=*/nullptr,
-      tooling::CompileCommand(), PI, std::make_shared<PCHContainerOperations>(),
-      /*StoreInMemory=*/true,
-      [&](ASTContext &Ctx, std::shared_ptr<Preprocessor> PP) {});
-  // Build AST for main file with preamble.
-  auto AST =
-      ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData,
-                       llvm::MemoryBuffer::getMemBufferCopy(Main.code()),
-                       std::make_shared<PCHContainerOperations>(), PI.FS);
-  ASSERT_TRUE(AST);
+  TU.Code = Main.code();
+  auto AST = TU.build();
   FileIndex Index;
-  Index.updateMain(MainFile, *AST);
-
-  auto Foo = findSymbol(TestTU::withHeaderCode(Header).headerSymbols(), "Foo");
-  RefsRequest Request;
-  Request.IDs.insert(Foo.ID);
+  Index.updateMain(testPath(TU.Filename), AST);
 
   // Expect to see references in main file, references in headers are excluded
   // because we only index main AST.
-  EXPECT_THAT(getRefs(Index, Foo.ID), RefsAre({RefRange(Main.range())}));
+  EXPECT_THAT(getRefs(Index, findSymbol(TU.headerSymbols(), "Foo").ID),
+              RefsAre({RefRange(Main.range())}));
 }
 
 } // namespace
diff --git a/unittests/clangd/FindSymbolsTests.cpp b/clangd/unittests/FindSymbolsTests.cpp
similarity index 89%
rename from unittests/clangd/FindSymbolsTests.cpp
rename to clangd/unittests/FindSymbolsTests.cpp
index 9b63159..f311237 100644
--- a/unittests/clangd/FindSymbolsTests.cpp
+++ b/clangd/unittests/FindSymbolsTests.cpp
@@ -1,9 +1,8 @@
 //===-- FindSymbolsTests.cpp -------------------------*- C++ -*------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
@@ -45,7 +44,7 @@
 // GMock helpers for matching DocumentSymbol.
 MATCHER_P(SymNameRange, Range, "") { return arg.selectionRange == Range; }
 template <class... ChildMatchers>
-testing::Matcher<DocumentSymbol> Children(ChildMatchers... ChildrenM) {
+::testing::Matcher<DocumentSymbol> Children(ChildMatchers... ChildrenM) {
   return Field(&DocumentSymbol::children, ElementsAre(ChildrenM...));
 }
 
@@ -88,13 +87,16 @@
 
 } // namespace
 
-TEST_F(WorkspaceSymbolsTest, NoMacro) {
+TEST_F(WorkspaceSymbolsTest, Macros) {
   addFile("foo.cpp", R"cpp(
-      #define MACRO X
-      )cpp");
+       #define MACRO X
+       )cpp");
 
-  // Macros are not in the index.
-  EXPECT_THAT(getSymbols("macro"), IsEmpty());
+  // LSP's SymbolKind doesn't have a "Macro" kind, and
+  // indexSymbolKindToSymbolKind() currently maps macros
+  // to SymbolKind::String.
+  EXPECT_THAT(getSymbols("macro"),
+              ElementsAre(AllOf(QName("MACRO"), WithKind(SymbolKind::String))));
 }
 
 TEST_F(WorkspaceSymbolsTest, NoLocals) {
@@ -145,8 +147,7 @@
       int test() {}
       static test2() {}
       )cpp");
-  EXPECT_THAT(getSymbols("test"), 
-              ElementsAre(QName("test"), QName("test2")));
+  EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"), QName("test2")));
 }
 
 TEST_F(WorkspaceSymbolsTest, Namespaces) {
@@ -299,6 +300,23 @@
   EXPECT_THAT(getSymbols("foo"), ElementsAre(QName("foo")));
 }
 
+TEST_F(WorkspaceSymbolsTest, TempSpecs) {
+  addFile("foo.h", R"cpp(
+      template <typename T, typename U, int X = 5> class Foo {};
+      template <typename T> class Foo<int, T> {};
+      template <> class Foo<bool, int> {};
+      template <> class Foo<bool, int, 3> {};
+      )cpp");
+  // Foo is higher ranked because of exact name match.
+  EXPECT_THAT(
+      getSymbols("Foo"),
+      UnorderedElementsAre(
+          AllOf(QName("Foo"), WithKind(SymbolKind::Class)),
+          AllOf(QName("Foo<int, T>"), WithKind(SymbolKind::Class)),
+          AllOf(QName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
+          AllOf(QName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
+}
+
 namespace {
 class DocumentSymbolsTest : public ::testing::Test {
 public:
@@ -366,9 +384,6 @@
       // Namespace alias
       namespace baz = bar;
 
-      // FIXME: using declaration is not supported as the IndexAction will ignore
-      // implicit declarations (the implicit using shadow declaration) by default,
-      // and there is no way to customize this behavior at the moment.
       using bar::v2;
       } // namespace foo
     )");
@@ -413,7 +428,7 @@
                                           Children()))),
                      AllOf(WithName("baz"), WithKind(SymbolKind::Namespace),
                            Children()),
-                     AllOf(WithName("v2"), WithKind(SymbolKind::Variable))))}));
+                     AllOf(WithName("v2"), WithKind(SymbolKind::Namespace))))}));
 }
 
 TEST_F(DocumentSymbolsTest, DeclarationDefinition) {
@@ -526,11 +541,9 @@
           AllOf(WithName("Tmpl<double>"), WithKind(SymbolKind::Struct),
                 Children()),
           AllOf(WithName("funcTmpl"), Children()),
-          // FIXME(ibiryukov): template args should be <int> to match the code.
-          AllOf(WithName("funcTmpl<int, double, float>"), Children()),
+          AllOf(WithName("funcTmpl<int>"), Children()),
           AllOf(WithName("varTmpl"), Children()),
-          // FIXME(ibiryukov): template args should be <int> to match the code.
-          AllOf(WithName("varTmpl<int, double>"), Children())));
+          AllOf(WithName("varTmpl<int>"), Children())));
 }
 
 TEST_F(DocumentSymbolsTest, Namespaces) {
@@ -560,7 +573,7 @@
       )cpp");
   EXPECT_THAT(
       getSymbols(FilePath),
-      ElementsAreArray<testing::Matcher<DocumentSymbol>>(
+      ElementsAreArray<::testing::Matcher<DocumentSymbol>>(
           {AllOf(WithName("ans1"),
                  Children(AllOf(WithName("ai1"), Children()),
                           AllOf(WithName("ans2"), Children(WithName("ai2"))))),
@@ -654,5 +667,22 @@
                           WithName("using namespace ns_alias")));
 }
 
+TEST_F(DocumentSymbolsTest, TempSpecs) {
+  addFile("foo.cpp", R"cpp(
+      template <typename T, typename U, int X = 5> class Foo {};
+      template <typename T> class Foo<int, T> {};
+      template <> class Foo<bool, int> {};
+      template <> class Foo<bool, int, 3> {};
+      )cpp");
+  // Foo is higher ranked because of exact name match.
+  EXPECT_THAT(
+      getSymbols("foo.cpp"),
+      UnorderedElementsAre(
+          AllOf(WithName("Foo"), WithKind(SymbolKind::Class)),
+          AllOf(WithName("Foo<int, T>"), WithKind(SymbolKind::Class)),
+          AllOf(WithName("Foo<bool, int>"), WithKind(SymbolKind::Class)),
+          AllOf(WithName("Foo<bool, int, 3>"), WithKind(SymbolKind::Class))));
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/FunctionTests.cpp b/clangd/unittests/FunctionTests.cpp
similarity index 77%
rename from unittests/clangd/FunctionTests.cpp
rename to clangd/unittests/FunctionTests.cpp
index 613190d..0cd8b79 100644
--- a/unittests/clangd/FunctionTests.cpp
+++ b/clangd/unittests/FunctionTests.cpp
@@ -1,9 +1,8 @@
-//===-- FunctionsTests.cpp ------------------------------------------------===//
+//===-- FunctionTests.cpp -------------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/FuzzyMatchTests.cpp b/clangd/unittests/FuzzyMatchTests.cpp
similarity index 89%
rename from unittests/clangd/FuzzyMatchTests.cpp
rename to clangd/unittests/FuzzyMatchTests.cpp
index 1c4062c..33d202b 100644
--- a/unittests/clangd/FuzzyMatchTests.cpp
+++ b/clangd/unittests/FuzzyMatchTests.cpp
@@ -1,9 +1,8 @@
 //===-- FuzzyMatchTests.cpp - String fuzzy matcher tests --------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,7 +15,7 @@
 namespace clang {
 namespace clangd {
 namespace {
-using testing::Not;
+using ::testing::Not;
 
 struct ExpectedMatch {
   // Annotations are optional, and will not be asserted if absent.
@@ -44,7 +43,7 @@
   llvm::Optional<llvm::StringRef> Annotated;
 };
 
-struct MatchesMatcher : public testing::MatcherInterface<llvm::StringRef> {
+struct MatchesMatcher : public ::testing::MatcherInterface<llvm::StringRef> {
   ExpectedMatch Candidate;
   llvm::Optional<float> Score;
   MatchesMatcher(ExpectedMatch Candidate, llvm::Optional<float> Score)
@@ -57,7 +56,7 @@
   }
 
   bool MatchAndExplain(llvm::StringRef Pattern,
-                       testing::MatchResultListener *L) const override {
+                       ::testing::MatchResultListener *L) const override {
     std::unique_ptr<llvm::raw_ostream> OS(
         L->stream()
             ? (llvm::raw_ostream *)(new llvm::raw_os_ostream(*L->stream()))
@@ -66,15 +65,15 @@
     auto Result = Matcher.match(Candidate.Word);
     auto AnnotatedMatch = Matcher.dumpLast(*OS << "\n");
     return Result && Candidate.accepts(AnnotatedMatch) &&
-           (!Score || testing::Value(*Result, testing::FloatEq(*Score)));
+           (!Score || ::testing::Value(*Result, ::testing::FloatEq(*Score)));
   }
 };
 
 // Accepts patterns that match a given word, optionally requiring a score.
 // Dumps the debug tables on match failure.
-testing::Matcher<llvm::StringRef> matches(llvm::StringRef M,
-                                          llvm::Optional<float> Score = {}) {
-  return testing::MakeMatcher<llvm::StringRef>(new MatchesMatcher(M, Score));
+::testing::Matcher<llvm::StringRef> matches(llvm::StringRef M,
+                                            llvm::Optional<float> Score = {}) {
+  return ::testing::MakeMatcher<llvm::StringRef>(new MatchesMatcher(M, Score));
 }
 
 TEST(FuzzyMatch, Matches) {
@@ -180,7 +179,7 @@
   EXPECT_THAT("std", Not(matches("pthread_condattr_setpshared")));
 }
 
-struct RankMatcher : public testing::MatcherInterface<llvm::StringRef> {
+struct RankMatcher : public ::testing::MatcherInterface<llvm::StringRef> {
   std::vector<ExpectedMatch> RankedStrings;
   RankMatcher(std::initializer_list<ExpectedMatch> RankedStrings)
       : RankedStrings(RankedStrings) {}
@@ -194,7 +193,7 @@
   }
 
   bool MatchAndExplain(llvm::StringRef Pattern,
-                       testing::MatchResultListener *L) const override {
+                       ::testing::MatchResultListener *L) const override {
     std::unique_ptr<llvm::raw_ostream> OS(
         L->stream()
             ? (llvm::raw_ostream *)(new llvm::raw_os_ostream(*L->stream()))
@@ -237,8 +236,8 @@
 // Accepts patterns that match all the strings and rank them in the given order.
 // Dumps the debug tables on match failure.
 template <typename... T>
-testing::Matcher<llvm::StringRef> ranks(T... RankedStrings) {
-  return testing::MakeMatcher<llvm::StringRef>(
+::testing::Matcher<llvm::StringRef> ranks(T... RankedStrings) {
+  return ::testing::MakeMatcher<llvm::StringRef>(
       new RankMatcher{ExpectedMatch(RankedStrings)...});
 }
 
@@ -248,6 +247,8 @@
   EXPECT_THAT("foo", ranks("[foo]", "[Foo]"));
   EXPECT_THAT("onMes",
               ranks("[onMes]sage", "[onmes]sage", "[on]This[M]ega[Es]capes"));
+  EXPECT_THAT("onmes",
+              ranks("[onmes]sage", "[onMes]sage", "[on]This[M]ega[Es]capes"));
   EXPECT_THAT("CC", ranks("[C]amel[C]ase", "[c]amel[C]ase"));
   EXPECT_THAT("cC", ranks("[c]amel[C]ase", "[C]amel[C]ase"));
   EXPECT_THAT("p", ranks("[p]", "[p]arse", "[p]osix", "[p]afdsa", "[p]ath"));
@@ -271,12 +272,18 @@
 // Verify some bounds so we know scores fall in the right range.
 // Testing exact scores is fragile, so we prefer Ranking tests.
 TEST(FuzzyMatch, Scoring) {
-  EXPECT_THAT("abs", matches("[a]w[B]xYz[S]", 0.f));
+  EXPECT_THAT("abs", matches("[a]w[B]xYz[S]", 7.f / 12.f));
   EXPECT_THAT("abs", matches("[abs]l", 1.f));
   EXPECT_THAT("abs", matches("[abs]", 2.f));
   EXPECT_THAT("Abs", matches("[abs]", 2.f));
 }
 
+TEST(FuzzyMatch, InitialismAndPrefix) {
+  // We want these scores to be roughly the same.
+  EXPECT_THAT("up", matches("[u]nique_[p]tr", 3.f / 4.f));
+  EXPECT_THAT("up", matches("[up]per_bound", 1.f));
+}
+
 // Returns pretty-printed segmentation of Text.
 // e.g. std::basic_string --> +--  +---- +-----
 std::string segment(llvm::StringRef Text) {
diff --git a/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/clangd/unittests/GlobalCompilationDatabaseTests.cpp
similarity index 62%
rename from unittests/clangd/GlobalCompilationDatabaseTests.cpp
rename to clangd/unittests/GlobalCompilationDatabaseTests.cpp
index b0052c7..7c7993c 100644
--- a/unittests/clangd/GlobalCompilationDatabaseTests.cpp
+++ b/clangd/unittests/GlobalCompilationDatabaseTests.cpp
@@ -1,9 +1,8 @@
 //===-- GlobalCompilationDatabaseTests.cpp ----------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,15 +16,18 @@
 namespace clang {
 namespace clangd {
 namespace {
+using ::testing::AllOf;
+using ::testing::Contains;
 using ::testing::ElementsAre;
 using ::testing::EndsWith;
+using ::testing::Not;
 
 TEST(GlobalCompilationDatabaseTest, FallbackCommand) {
   DirectoryBasedGlobalCompilationDatabase DB(None);
   auto Cmd = DB.getFallbackCommand(testPath("foo/bar.cc"));
   EXPECT_EQ(Cmd.Directory, testPath("foo"));
-  EXPECT_THAT(Cmd.CommandLine, ElementsAre(
-    EndsWith("clang"), testPath("foo/bar.cc")));
+  EXPECT_THAT(Cmd.CommandLine,
+              ElementsAre(EndsWith("clang"), testPath("foo/bar.cc")));
   EXPECT_EQ(Cmd.Output, "");
 
   // .h files have unknown language, so they are parsed liberally as obj-c++.
@@ -65,17 +67,19 @@
 };
 
 TEST_F(OverlayCDBTest, GetCompileCommand) {
-  OverlayCDB CDB(Base.get());
-  EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")),
-            Base->getCompileCommand(testPath("foo.cc")));
+  OverlayCDB CDB(Base.get(), {}, std::string(""));
+  EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
+              AllOf(Contains(testPath("foo.cc")), Contains("-DA=1")));
   EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None);
 
   auto Override = cmd(testPath("foo.cc"), "-DA=3");
   CDB.setCompileCommand(testPath("foo.cc"), Override);
-  EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")), Override);
+  EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
+              Contains("-DA=3"));
   EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None);
   CDB.setCompileCommand(testPath("missing.cc"), Override);
-  EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), Override);
+  EXPECT_THAT(CDB.getCompileCommand(testPath("missing.cc"))->CommandLine,
+              Contains("-DA=3"));
 }
 
 TEST_F(OverlayCDBTest, GetFallbackCommand) {
@@ -85,11 +89,12 @@
 }
 
 TEST_F(OverlayCDBTest, NoBase) {
-  OverlayCDB CDB(nullptr, {"-DA=6"});
+  OverlayCDB CDB(nullptr, {"-DA=6"}, std::string(""));
   EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), None);
   auto Override = cmd(testPath("bar.cc"), "-DA=5");
   CDB.setCompileCommand(testPath("bar.cc"), Override);
-  EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), Override);
+  EXPECT_THAT(CDB.getCompileCommand(testPath("bar.cc"))->CommandLine,
+              Contains("-DA=5"));
 
   EXPECT_THAT(CDB.getFallbackCommand(testPath("foo.cc")).CommandLine,
               ElementsAre(EndsWith("clang"), testPath("foo.cc"), "-DA=6"));
@@ -112,6 +117,35 @@
                                    ElementsAre("A.cpp"), ElementsAre("C.cpp")));
 }
 
+TEST_F(OverlayCDBTest, Adjustments) {
+  OverlayCDB CDB(Base.get(), {}, std::string(""));
+  auto Cmd = CDB.getCompileCommand(testPath("foo.cc")).getValue();
+  // Delete the file name.
+  Cmd.CommandLine.pop_back();
+
+  // Check dependency file commands are dropped.
+  Cmd.CommandLine.push_back("-MF");
+  Cmd.CommandLine.push_back("random-dependency");
+
+  // Check plugin-related commands are dropped.
+  Cmd.CommandLine.push_back("-Xclang");
+  Cmd.CommandLine.push_back("-load");
+  Cmd.CommandLine.push_back("-Xclang");
+  Cmd.CommandLine.push_back("random-plugin");
+
+  Cmd.CommandLine.push_back("-DA=5");
+  Cmd.CommandLine.push_back(Cmd.Filename);
+
+  CDB.setCompileCommand(testPath("foo.cc"), Cmd);
+
+  EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
+              AllOf(Contains("-fsyntax-only"), Contains("-DA=5"),
+                    Contains(testPath("foo.cc")), Not(Contains("-MF")),
+                    Not(Contains("random-dependency")),
+                    Not(Contains("-Xclang")), Not(Contains("-load")),
+                    Not(Contains("random-plugin"))));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/HeadersTests.cpp b/clangd/unittests/HeadersTests.cpp
similarity index 83%
rename from unittests/clangd/HeadersTests.cpp
rename to clangd/unittests/HeadersTests.cpp
index 79f0b9c..e1591ab 100644
--- a/unittests/clangd/HeadersTests.cpp
+++ b/clangd/unittests/HeadersTests.cpp
@@ -1,9 +1,8 @@
 //===-- HeadersTests.cpp - Include headers unit tests -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,6 +15,7 @@
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Lex/PreprocessorOptions.h"
+#include "llvm/Support/Path.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -52,8 +52,8 @@
     CI->getDiagnosticOpts().IgnoreWarnings = true;
     auto Clang = prepareCompilerInstance(
         std::move(CI), /*Preamble=*/nullptr,
-        llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile),
-        std::make_shared<PCHContainerOperations>(), VFS, IgnoreDiags);
+        llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile), VFS,
+        IgnoreDiags);
 
     EXPECT_FALSE(Clang->getFrontendOpts().Inputs.empty());
     return Clang;
@@ -91,14 +91,13 @@
 
     IncludeInserter Inserter(MainFile, /*Code=*/"", format::getLLVMStyle(),
                              CDB.getCompileCommand(MainFile)->Directory,
-                             Clang->getPreprocessor().getHeaderSearchInfo());
+                             &Clang->getPreprocessor().getHeaderSearchInfo());
     for (const auto &Inc : Inclusions)
       Inserter.addExisting(Inc);
-    auto Declaring = ToHeaderFile(Original);
     auto Inserted = ToHeaderFile(Preferred);
-    if (!Inserter.shouldInsertInclude(Declaring, Inserted))
+    if (!Inserter.shouldInsertInclude(Original, Inserted))
       return "";
-    std::string Path = Inserter.calculateIncludePath(Declaring, Inserted);
+    std::string Path = Inserter.calculateIncludePath(Inserted);
     Action.EndSourceFile();
     return Path;
   }
@@ -111,7 +110,7 @@
 
     IncludeInserter Inserter(MainFile, /*Code=*/"", format::getLLVMStyle(),
                              CDB.getCompileCommand(MainFile)->Directory,
-                             Clang->getPreprocessor().getHeaderSearchInfo());
+                             &Clang->getPreprocessor().getHeaderSearchInfo());
     auto Edit = Inserter.insert(VerbatimHeader);
     Action.EndSourceFile();
     return Edit;
@@ -215,10 +214,16 @@
 TEST_F(HeadersTest, ShortenedInclude) {
   std::string BarHeader = testPath("sub/bar.h");
   EXPECT_EQ(calculate(BarHeader), "\"bar.h\"");
+
+  SearchDirArg = (llvm::Twine("-I") + Subdir + "/..").str();
+  CDB.ExtraClangFlags = {SearchDirArg.c_str()};
+  BarHeader = testPath("sub/bar.h");
+  EXPECT_EQ(calculate(BarHeader), "\"sub/bar.h\"");
 }
 
 TEST_F(HeadersTest, NotShortenedInclude) {
-  std::string BarHeader = testPath("sub-2/bar.h");
+  std::string BarHeader =
+      llvm::sys::path::convert_to_slash(testPath("sub-2/bar.h"));
   EXPECT_EQ(calculate(BarHeader, ""), "\"" + BarHeader + "\"");
 }
 
@@ -253,6 +258,22 @@
   EXPECT_TRUE(StringRef(Edit->newText).contains("<y>"));
 }
 
+TEST(Headers, NoHeaderSearchInfo) {
+  std::string MainFile = testPath("main.cpp");
+  IncludeInserter Inserter(MainFile, /*Code=*/"", format::getLLVMStyle(),
+                           /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
+
+  auto HeaderPath = testPath("sub/bar.h");
+  auto Inserting = HeaderFile{HeaderPath, /*Verbatim=*/false};
+  auto Verbatim = HeaderFile{"<x>", /*Verbatim=*/true};
+
+  EXPECT_EQ(Inserter.calculateIncludePath(Inserting), "\"" + HeaderPath + "\"");
+  EXPECT_EQ(Inserter.shouldInsertInclude(HeaderPath, Inserting), false);
+
+  EXPECT_EQ(Inserter.calculateIncludePath(Verbatim), "<x>");
+  EXPECT_EQ(Inserter.shouldInsertInclude(HeaderPath, Verbatim), true);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/IndexActionTests.cpp b/clangd/unittests/IndexActionTests.cpp
similarity index 86%
rename from unittests/clangd/IndexActionTests.cpp
rename to clangd/unittests/IndexActionTests.cpp
index 6a3da53..6adc8cc 100644
--- a/unittests/clangd/IndexActionTests.cpp
+++ b/clangd/unittests/IndexActionTests.cpp
@@ -1,9 +1,8 @@
 //===------ IndexActionTests.cpp  -------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -30,13 +29,15 @@
 
 MATCHER_P(HasDigest, Digest, "") { return arg.Digest == Digest; }
 
+MATCHER_P(HasName, Name, "") { return arg.Name == Name; }
+
 MATCHER(HasSameURI, "") {
-  llvm::StringRef URI = testing::get<0>(arg);
-  const std::string &Path = testing::get<1>(arg);
+  llvm::StringRef URI = ::testing::get<0>(arg);
+  const std::string &Path = ::testing::get<1>(arg);
   return toUri(Path) == URI;
 }
 
-testing::Matcher<const IncludeGraphNode &>
+::testing::Matcher<const IncludeGraphNode &>
 IncludesAre(const std::vector<std::string> &Includes) {
   return ::testing::Field(&IncludeGraphNode::DirectIncludes,
                           UnorderedPointwise(HasSameURI(), Includes));
@@ -44,6 +45,7 @@
 
 void checkNodesAreInitialized(const IndexFileIn &IndexFile,
                               const std::vector<std::string> &Paths) {
+  ASSERT_TRUE(IndexFile.Sources);
   EXPECT_THAT(Paths.size(), IndexFile.Sources->size());
   for (llvm::StringRef Path : Paths) {
     auto URI = toUri(Path);
@@ -225,6 +227,27 @@
                                         HasDigest(digest(HeaderCode))))));
 }
 
+TEST_F(IndexActionTest, NoWarnings) {
+  std::string MainFilePath = testPath("main.cpp");
+  std::string MainCode = R"cpp(
+      void foo(int x) {
+        if (x = 1) // -Wparentheses
+          return;
+        if (x = 1) // -Wparentheses
+          return;
+      }
+      void bar() {}
+  )cpp";
+  addFile(MainFilePath, MainCode);
+  // We set -ferror-limit so the warning-promoted-to-error would be fatal.
+  // This would cause indexing to stop (if warnings weren't disabled).
+  IndexFileIn IndexFile = runIndexingAction(
+      MainFilePath, {"-ferror-limit=1", "-Wparentheses", "-Werror"});
+  ASSERT_TRUE(IndexFile.Sources);
+  ASSERT_NE(0u, IndexFile.Sources->size());
+  EXPECT_THAT(*IndexFile.Symbols, ElementsAre(HasName("foo"), HasName("bar")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/IndexTests.cpp b/clangd/unittests/IndexTests.cpp
similarity index 85%
rename from unittests/clangd/IndexTests.cpp
rename to clangd/unittests/IndexTests.cpp
index 3b7d6ff..8d8c8da 100644
--- a/unittests/clangd/IndexTests.cpp
+++ b/clangd/unittests/IndexTests.cpp
@@ -1,9 +1,8 @@
 //===-- IndexTests.cpp  -------------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,16 +13,19 @@
 #include "index/Index.h"
 #include "index/MemIndex.h"
 #include "index/Merge.h"
+#include "index/Symbol.h"
+#include "clang/Index/IndexSymbol.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using testing::_;
-using testing::AllOf;
-using testing::AnyOf;
-using testing::ElementsAre;
-using testing::Pair;
-using testing::Pointee;
-using testing::UnorderedElementsAre;
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::AnyOf;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::Pair;
+using ::testing::Pointee;
+using ::testing::UnorderedElementsAre;
 
 namespace clang {
 namespace clangd {
@@ -182,6 +184,41 @@
   EXPECT_THAT(lookup(*I, SymbolID("ns::nonono")), UnorderedElementsAre());
 }
 
+TEST(MemIndexTest, TemplateSpecialization) {
+  SymbolSlab::Builder B;
+
+  Symbol S = symbol("TempSpec");
+  S.ID = SymbolID("1");
+  B.insert(S);
+
+  S = symbol("TempSpec");
+  S.ID = SymbolID("2");
+  S.TemplateSpecializationArgs = "<int, bool>";
+  S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+      index::SymbolProperty::TemplateSpecialization);
+  B.insert(S);
+
+  S = symbol("TempSpec");
+  S.ID = SymbolID("3");
+  S.TemplateSpecializationArgs = "<int, U>";
+  S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+      index::SymbolProperty::TemplatePartialSpecialization);
+  B.insert(S);
+
+  auto I = MemIndex::build(std::move(B).build(), RefSlab());
+  FuzzyFindRequest Req;
+  Req.AnyScope = true;
+
+  Req.Query = "TempSpec";
+  EXPECT_THAT(match(*I, Req),
+              UnorderedElementsAre("TempSpec", "TempSpec<int, bool>",
+                                   "TempSpec<int, U>"));
+
+  // FIXME: Add filtering for template argument list.
+  Req.Query = "TempSpec<int";
+  EXPECT_THAT(match(*I, Req), IsEmpty());
+}
+
 TEST(MergeIndexTest, Lookup) {
   auto I = MemIndex::build(generateSymbols({"ns::A", "ns::B"}), RefSlab()),
        J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}), RefSlab());
@@ -254,6 +291,22 @@
   EXPECT_EQ(M.Name, "right");
 }
 
+TEST(MergeTest, PreferSymbolLocationInCodegenFile) {
+  Symbol L, R;
+
+  L.ID = R.ID = SymbolID("hello");
+  L.CanonicalDeclaration.FileURI = "file:/x.proto.h";
+  R.CanonicalDeclaration.FileURI = "file:/x.proto";
+
+  Symbol M = mergeSymbol(L, R);
+  EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/x.proto");
+
+  // Prefer L if both have codegen suffix.
+  L.CanonicalDeclaration.FileURI = "file:/y.proto";
+  M = mergeSymbol(L, R);
+  EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/y.proto");
+}
+
 TEST(MergeIndexTest, Refs) {
   FileIndex Dyn;
   FileIndex StaticIndex;
diff --git a/unittests/clangd/JSONTransportTests.cpp b/clangd/unittests/JSONTransportTests.cpp
similarity index 94%
rename from unittests/clangd/JSONTransportTests.cpp
rename to clangd/unittests/JSONTransportTests.cpp
index 23c3934..3f71a10 100644
--- a/unittests/clangd/JSONTransportTests.cpp
+++ b/clangd/unittests/JSONTransportTests.cpp
@@ -1,9 +1,8 @@
 //===-- JSONTransportTests.cpp  -------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Protocol.h"
@@ -18,8 +17,8 @@
 
 // No fmemopen on windows or on versions of MacOS X earlier than 10.13, so we
 // can't easily run this test.
-#if !(defined(WIN32) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&           \
-                         __MAC_OS_X_VERSION_MIN_REQUIRED < 101300))
+#if !(defined(_WIN32) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) &&          \
+                          __MAC_OS_X_VERSION_MIN_REQUIRED < 101300))
 
 // Fixture takes care of managing the input/output buffers for the transport.
 class JSONTransportTest : public ::testing::Test {
diff --git a/unittests/clangd/Matchers.h b/clangd/unittests/Matchers.h
similarity index 67%
rename from unittests/clangd/Matchers.h
rename to clangd/unittests/Matchers.h
index d666de3..0946398 100644
--- a/unittests/clangd/Matchers.h
+++ b/clangd/unittests/Matchers.h
@@ -1,9 +1,8 @@
 //===-- Matchers.h ----------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -128,6 +127,73 @@
     llvm::consumeError(ComputedValue.takeError());                             \
   } while (false)
 
+// Implements the HasValue(m) matcher for matching an Optional whose
+// value matches matcher m.
+template <typename InnerMatcher> class OptionalMatcher {
+public:
+  explicit OptionalMatcher(const InnerMatcher &matcher) : matcher_(matcher) {}
+
+  // This type conversion operator template allows Optional(m) to be
+  // used as a matcher for any Optional type whose value type is
+  // compatible with the inner matcher.
+  //
+  // The reason we do this instead of relying on
+  // MakePolymorphicMatcher() is that the latter is not flexible
+  // enough for implementing the DescribeTo() method of Optional().
+  template <typename Optional> operator Matcher<Optional>() const {
+    return MakeMatcher(new Impl<Optional>(matcher_));
+  }
+
+private:
+  // The monomorphic implementation that works for a particular optional type.
+  template <typename Optional>
+  class Impl : public ::testing::MatcherInterface<Optional> {
+  public:
+    using Value = typename std::remove_const<
+        typename std::remove_reference<Optional>::type>::type::value_type;
+
+    explicit Impl(const InnerMatcher &matcher)
+        : matcher_(::testing::MatcherCast<const Value &>(matcher)) {}
+
+    virtual void DescribeTo(::std::ostream *os) const {
+      *os << "has a value that ";
+      matcher_.DescribeTo(os);
+    }
+
+    virtual void DescribeNegationTo(::std::ostream *os) const {
+      *os << "does not have a value that ";
+      matcher_.DescribeTo(os);
+    }
+
+    virtual bool
+    MatchAndExplain(Optional optional,
+                    ::testing::MatchResultListener *listener) const {
+      if (!optional.hasValue())
+        return false;
+
+      *listener << "which has a value ";
+      return MatchPrintAndExplain(*optional, matcher_, listener);
+    }
+
+  private:
+    const Matcher<const Value &> matcher_;
+
+    GTEST_DISALLOW_ASSIGN_(Impl);
+  };
+
+  const InnerMatcher matcher_;
+
+  GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
+};
+
+// Creates a matcher that matches an Optional that has a value
+// that matches inner_matcher.
+template <typename InnerMatcher>
+inline OptionalMatcher<InnerMatcher>
+HasValue(const InnerMatcher &inner_matcher) {
+  return OptionalMatcher<InnerMatcher>(inner_matcher);
+}
+
 } // namespace clangd
 } // namespace clang
 #endif
diff --git a/clangd/unittests/PrintASTTests.cpp b/clangd/unittests/PrintASTTests.cpp
new file mode 100644
index 0000000..9cf2e7d
--- /dev/null
+++ b/clangd/unittests/PrintASTTests.cpp
@@ -0,0 +1,102 @@
+//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AST.h"
+#include "Annotations.h"
+#include "Protocol.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest-param-test.h"
+#include "gtest/gtest.h"
+#include "gtest/internal/gtest-param-util-generated.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::ElementsAreArray;
+
+struct Case {
+  const char *AnnotatedCode;
+  std::vector<const char *> Expected;
+};
+class ASTUtils : public ::testing::Test,
+                 public ::testing::WithParamInterface<Case> {};
+
+TEST_P(ASTUtils, PrintTemplateArgs) {
+  auto Pair = GetParam();
+  Annotations Test(Pair.AnnotatedCode);
+  auto AST = TestTU::withCode(Test.code()).build();
+  struct Visitor : RecursiveASTVisitor<Visitor> {
+    Visitor(std::vector<Position> Points) : Points(std::move(Points)) {}
+    bool VisitNamedDecl(const NamedDecl *ND) {
+      if (TemplateArgsAtPoints.size() == Points.size())
+        return true;
+      auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(),
+                                     ND->getLocation());
+      if (Pos != Points[TemplateArgsAtPoints.size()])
+        return true;
+      TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND));
+      return true;
+    }
+    std::vector<std::string> TemplateArgsAtPoints;
+    const std::vector<Position> Points;
+  };
+  Visitor V(Test.points());
+  V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
+  EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected));
+}
+
+INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils,
+                        ::testing::ValuesIn(std::vector<Case>({
+                            {
+                                R"cpp(
+                                  template <class X> class Bar {};
+                                  template <> class ^Bar<double> {};)cpp",
+                                {"<double>"}},
+                            {
+                                R"cpp(
+                                  template <class X> class Bar {};
+                                  template <class T, class U,
+                                  template<typename> class Z, int Q>
+                                  struct Foo {};
+                                  template struct ^Foo<int, bool, Bar, 8>;
+                                  template <typename T>
+                                  struct ^Foo<T *, T, Bar, 3> {};)cpp",
+                                {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
+                            {
+                                R"cpp(
+                                  template <int ...> void Foz() {};
+                                  template <> void ^Foz<3, 5, 8>() {};)cpp",
+                                {"<3, 5, 8>"}},
+                            {
+                                R"cpp(
+                                  template <class X> class Bar {};
+                                  template <template <class> class ...>
+                                  class Aux {};
+                                  template <> class ^Aux<Bar, Bar> {};
+                                  template <template <class> T>
+                                  class ^Aux<T, T> {};)cpp",
+                                {"<Bar, Bar>", "<T, T>"}},
+                            {
+                                R"cpp(
+                                  template <typename T> T var = 1234;
+                                  template <> int ^var<int> = 1;)cpp",
+                                {"<int>"}},
+                            {
+                                R"cpp(
+                                  template <typename T> struct Foo;
+                                  struct Bar { friend class Foo<int>; };
+                                  template <> struct ^Foo<int> {};)cpp",
+                                {"<int>"}},
+                        })));
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/QualityTests.cpp b/clangd/unittests/QualityTests.cpp
similarity index 93%
rename from unittests/clangd/QualityTests.cpp
rename to clangd/unittests/QualityTests.cpp
index 9175d6b..0c739d7 100644
--- a/unittests/clangd/QualityTests.cpp
+++ b/clangd/unittests/QualityTests.cpp
@@ -1,9 +1,8 @@
-//===-- SourceCodeTests.cpp  ------------------------------------*- C++ -*-===//
+//===-- QualityTests.cpp ----------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -179,6 +178,19 @@
   BaseMember.InBaseClass = true;
   Relevance.merge(BaseMember);
   EXPECT_TRUE(Relevance.InBaseClass);
+
+  auto Index = Test.index();
+  FuzzyFindRequest Req;
+  Req.Query = "X";
+  Req.AnyScope = true;
+  bool Matched = false;
+  Index->fuzzyFind(Req, [&](const Symbol &S) {
+    Matched = true;
+    Relevance = {};
+    Relevance.merge(S);
+    EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope);
+  });
+  EXPECT_TRUE(Matched);
 }
 
 // Do the signals move the scores in the direction we expect?
@@ -265,7 +277,7 @@
 
   SymbolRelevanceSignals Scoped;
   Scoped.Scope = SymbolRelevanceSignals::FileScope;
-  EXPECT_EQ(Scoped.evaluate(), Default.evaluate());
+  EXPECT_LT(Scoped.evaluate(), Default.evaluate());
   Scoped.Query = SymbolRelevanceSignals::CodeComplete;
   EXPECT_GT(Scoped.evaluate(), Default.evaluate());
 
@@ -280,6 +292,16 @@
   SymbolRelevanceSignals InBaseClass;
   InBaseClass.InBaseClass = true;
   EXPECT_LT(InBaseClass.evaluate(), Default.evaluate());
+
+  llvm::StringSet<> Words = {"one", "two", "three"};
+  SymbolRelevanceSignals WithoutMatchingWord;
+  WithoutMatchingWord.ContextWords = &Words;
+  WithoutMatchingWord.Name = "four";
+  EXPECT_EQ(WithoutMatchingWord.evaluate(), Default.evaluate());
+  SymbolRelevanceSignals WithMatchingWord;
+  WithMatchingWord.ContextWords = &Words;
+  WithMatchingWord.Name = "TheTwoTowers";
+  EXPECT_GT(WithMatchingWord.evaluate(), Default.evaluate());
 }
 
 TEST(QualityTests, ScopeProximity) {
diff --git a/unittests/clangd/RIFFTests.cpp b/clangd/unittests/RIFFTests.cpp
similarity index 83%
rename from unittests/clangd/RIFFTests.cpp
rename to clangd/unittests/RIFFTests.cpp
index 7ea1466..4cd54f4 100644
--- a/unittests/clangd/RIFFTests.cpp
+++ b/clangd/unittests/RIFFTests.cpp
@@ -1,9 +1,8 @@
 //===-- RIFFTests.cpp - Binary container unit tests -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/unittests/SelectionTests.cpp b/clangd/unittests/SelectionTests.cpp
new file mode 100644
index 0000000..ac9facc
--- /dev/null
+++ b/clangd/unittests/SelectionTests.cpp
@@ -0,0 +1,259 @@
+//===-- SelectionTests.cpp - ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "Annotations.h"
+#include "Selection.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+using ::testing::UnorderedElementsAreArray;
+
+SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) {
+  Annotations Test(MarkedCode);
+  switch (Test.points().size()) {
+  case 1: // Point selection.
+    return SelectionTree(AST.getASTContext(),
+                         cantFail(positionToOffset(Test.code(), Test.point())));
+  case 2: // Range selection.
+    return SelectionTree(
+        AST.getASTContext(),
+        cantFail(positionToOffset(Test.code(), Test.points()[0])),
+        cantFail(positionToOffset(Test.code(), Test.points()[1])));
+  default:
+    ADD_FAILURE() << "Expected 1-2 points for selection.\n" << MarkedCode;
+    return SelectionTree(AST.getASTContext(), 0u, 0u);
+  }
+}
+
+Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
+  if (!N)
+    return Range{};
+  SourceManager &SM = AST.getASTContext().getSourceManager();
+  StringRef Buffer = SM.getBufferData(SM.getMainFileID());
+  SourceRange SR = N->ASTNode.getSourceRange();
+  SR.setBegin(SM.getFileLoc(SR.getBegin()));
+  SR.setEnd(SM.getFileLoc(SR.getEnd()));
+  CharSourceRange R =
+      Lexer::getAsCharRange(SR, SM, AST.getASTContext().getLangOpts());
+  return Range{offsetToPosition(Buffer, SM.getFileOffset(R.getBegin())),
+               offsetToPosition(Buffer, SM.getFileOffset(R.getEnd()))};
+}
+
+std::string nodeKind(const SelectionTree::Node *N) {
+  if (!N)
+    return "<null>";
+  return N->ASTNode.getNodeKind().asStringRef().str();
+}
+
+std::vector<const SelectionTree::Node *> allNodes(const SelectionTree &T) {
+  std::vector<const SelectionTree::Node *> Result = {T.root()};
+  for (unsigned I = 0; I < Result.size(); ++I) {
+    const SelectionTree::Node *N = Result[I];
+    Result.insert(Result.end(), N->Children.begin(), N->Children.end());
+  }
+  return Result;
+}
+
+// Returns true if Common is a descendent of Root.
+// Verifies nothing is selected above Common.
+bool verifyCommonAncestor(const SelectionTree::Node *Root,
+                          const SelectionTree::Node *Common,
+                          StringRef MarkedCode) {
+  if (Root == Common)
+    return true;
+  if (Root->Selected)
+    ADD_FAILURE() << "Selected nodes outside common ancestor\n" << MarkedCode;
+  bool Seen = false;
+  for (const SelectionTree::Node *Child : Root->Children)
+    if (verifyCommonAncestor(Child, Common, MarkedCode)) {
+      if (Seen)
+        ADD_FAILURE() << "Saw common ancestor twice\n" << MarkedCode;
+      Seen = true;
+    }
+  return Seen;
+}
+
+TEST(SelectionTest, CommonAncestor) {
+  struct Case {
+    // Selection is between ^marks^.
+    // common ancestor marked with a [[range]].
+    const char *Code;
+    const char *CommonAncestorKind;
+  };
+  Case Cases[] = {
+      {
+          R"cpp(
+            struct AAA { struct BBB { static int ccc(); };};
+            int x = AAA::[[B^B^B]]::ccc();
+          )cpp",
+          "TypeLoc",
+      },
+      {
+          R"cpp(
+            struct AAA { struct BBB { static int ccc(); };};
+            int x = AAA::[[B^BB^]]::ccc();
+          )cpp",
+          "TypeLoc",
+      },
+      {
+          R"cpp(
+            struct AAA { struct BBB { static int ccc(); };};
+            int x = [[AAA::BBB::c^c^c]]();
+          )cpp",
+          "DeclRefExpr",
+      },
+      {
+          R"cpp(
+            struct AAA { struct BBB { static int ccc(); };};
+            int x = [[AAA::BBB::cc^c(^)]];
+          )cpp",
+          "CallExpr",
+      },
+
+      {
+          R"cpp(
+            void foo() { [[if (1^11) { return; } else {^ }]] }
+          )cpp",
+          "IfStmt",
+      },
+      {
+          R"cpp(
+            void foo();
+            #define CALL_FUNCTION(X) X()
+            void bar() { CALL_FUNCTION([[f^o^o]]); }
+          )cpp",
+          "DeclRefExpr",
+      },
+      {
+          R"cpp(
+            void foo();
+            #define CALL_FUNCTION(X) X()
+            void bar() { CALL_FUNC^TION([[fo^o]]); }
+          )cpp",
+          "DeclRefExpr",
+      },
+      {
+          R"cpp(
+            void foo();
+            #define CALL_FUNCTION(X) X()
+            void bar() [[{ C^ALL_FUNC^TION(foo); }]]
+          )cpp",
+          "CompoundStmt",
+      },
+      {
+          R"cpp(
+            void foo();
+            #define CALL_FUNCTION(X) X^()^
+            void bar() { CALL_FUNCTION(foo); }
+          )cpp",
+          nullptr,
+      },
+
+      // Point selections.
+      {"void foo() { [[^foo]](); }", "DeclRefExpr"},
+      {"void foo() { [[f^oo]](); }", "DeclRefExpr"},
+      {"void foo() { [[fo^o]](); }", "DeclRefExpr"},
+      {"void foo() { [[foo^()]]; }", "CallExpr"},
+      {"void foo() { [[foo^]] (); }", "DeclRefExpr"},
+      {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"},
+      {"[[^void]] foo();", "TypeLoc"},
+      {"^", nullptr},
+      {"void foo() { [[foo^^]] (); }", "DeclRefExpr"},
+
+      // FIXME: Ideally we'd get a declstmt or the VarDecl itself here.
+      // This doesn't happen now; the RAV doesn't traverse a node containing ;.
+      {"int x = 42;^", nullptr},
+      {"int x = 42^;", nullptr},
+
+      // Node types that have caused problems in the past.
+      {"template <typename T> void foo() { [[^T]] t; }", "TypeLoc"},
+
+      // No crash
+      {
+          R"cpp(
+            template <class T> struct Foo {};
+            template <[[template<class> class /*cursor here*/^U]]>
+             struct Foo<U<int>*> {};
+          )cpp",
+          "TemplateTemplateParmDecl"
+      },
+  };
+  for (const Case &C : Cases) {
+    Annotations Test(C.Code);
+    auto AST = TestTU::withCode(Test.code()).build();
+    auto T = makeSelectionTree(C.Code, AST);
+
+    if (Test.ranges().empty()) {
+      // If no [[range]] is marked in the example, there should be no selection.
+      EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T;
+      EXPECT_FALSE(T.root()) << C.Code << "\n" << T;
+    } else {
+      // If there is an expected selection, both common ancestor and root
+      // should exist with the appropriate node types in them.
+      EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
+          << C.Code << "\n"
+          << T;
+      EXPECT_EQ("TranslationUnitDecl", nodeKind(T.root())) << C.Code;
+      // Convert the reported common ancestor to a range and verify it.
+      EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range())
+          << C.Code << "\n"
+          << T;
+
+      // Check that common ancestor is reachable on exactly one path from root,
+      // and no nodes outside it are selected.
+      EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
+          << C.Code;
+    }
+  }
+}
+
+TEST(SelectionTest, Selected) {
+  // Selection with ^marks^.
+  // Partially selected nodes marked with a [[range]].
+  // Completely selected nodes marked with a $C[[range]].
+  const char *Cases[] = {
+      R"cpp( int abc, xyz = [[^ab^c]]; )cpp",
+      R"cpp( int abc, xyz = [[a^bc^]]; )cpp",
+      R"cpp( int abc, xyz = $C[[^abc^]]; )cpp",
+      R"cpp(
+        void foo() {
+          [[if ([[1^11]]) $C[[{
+            $C[[return]];
+          }]] else [[{^
+          }]]]]
+        }
+      )cpp",
+      R"cpp(
+          template <class T>
+          struct unique_ptr {};
+          void foo(^$C[[unique_ptr<unique_ptr<$C[[int]]>>]]^ a) {}
+      )cpp",
+  };
+  for (const char *C : Cases) {
+    Annotations Test(C);
+    auto AST = TestTU::withCode(Test.code()).build();
+    auto T = makeSelectionTree(C, AST);
+
+    std::vector<Range> Complete, Partial;
+    for (const SelectionTree::Node *N : allNodes(T))
+      if (N->Selected == SelectionTree::Complete)
+        Complete.push_back(nodeRange(N, AST));
+      else if (N->Selected == SelectionTree::Partial)
+        Partial.push_back(nodeRange(N, AST));
+    EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges("C"))) << C;
+    EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/SerializationTests.cpp b/clangd/unittests/SerializationTests.cpp
similarity index 91%
rename from unittests/clangd/SerializationTests.cpp
rename to clangd/unittests/SerializationTests.cpp
index a8ffaa1..792da77 100644
--- a/unittests/clangd/SerializationTests.cpp
+++ b/clangd/unittests/SerializationTests.cpp
@@ -1,9 +1,8 @@
 //===-- SerializationTests.cpp - Binary and YAML serialization unit tests -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,11 +13,11 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using testing::_;
-using testing::AllOf;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-using testing::UnorderedElementsAreArray;
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Pair;
+using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
 
 namespace clang {
 namespace clangd {
@@ -41,8 +40,8 @@
   End:
     Line: 1
     Column: 1
-Origin:    4
-Flags:    1
+Origin:    128
+Flags:    129
 Documentation:    'Foo doc'
 ReturnType:    'int'
 IncludeHeaders:
@@ -116,7 +115,8 @@
   EXPECT_EQ(Sym1.Documentation, "Foo doc");
   EXPECT_EQ(Sym1.ReturnType, "int");
   EXPECT_EQ(StringRef(Sym1.CanonicalDeclaration.FileURI), "file:///path/foo.h");
-  EXPECT_EQ(Sym1.Origin, SymbolOrigin::Static);
+  EXPECT_EQ(Sym1.Origin, static_cast<SymbolOrigin>(1 << 7));
+  EXPECT_EQ(static_cast<uint8_t>(Sym1.Flags), 129);
   EXPECT_TRUE(Sym1.Flags & Symbol::IndexedForCodeCompletion);
   EXPECT_FALSE(Sym1.Flags & Symbol::Deprecated);
   EXPECT_THAT(Sym1.IncludeHeaders,
@@ -135,7 +135,7 @@
   EXPECT_THAT(
       *ParsedYAML->Refs,
       UnorderedElementsAre(Pair(cantFail(SymbolID::fromStr("057557CEBF6E6B2D")),
-                                testing::SizeIs(1))));
+                                ::testing::SizeIs(1))));
   auto Ref1 = ParsedYAML->Refs->begin()->second.front();
   EXPECT_EQ(Ref1.Kind, RefKind::Reference);
   EXPECT_EQ(StringRef(Ref1.Location.FileURI), "file:///path/foo.cc");
diff --git a/clangd/unittests/SourceCodeTests.cpp b/clangd/unittests/SourceCodeTests.cpp
new file mode 100644
index 0000000..9ca6fa1
--- /dev/null
+++ b/clangd/unittests/SourceCodeTests.cpp
@@ -0,0 +1,409 @@
+//===-- SourceCodeTests.cpp  ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "Annotations.h"
+#include "Context.h"
+#include "Protocol.h"
+#include "SourceCode.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using llvm::Failed;
+using llvm::HasValue;
+using ::testing::UnorderedElementsAreArray;
+
+MATCHER_P2(Pos, Line, Col, "") {
+  return arg.line == int(Line) && arg.character == int(Col);
+}
+
+/// A helper to make tests easier to read.
+Position position(int line, int character) {
+  Position Pos;
+  Pos.line = line;
+  Pos.character = character;
+  return Pos;
+}
+
+Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
+  Range range;
+  range.start = position(p1.first, p1.second);
+  range.end = position(p2.first, p2.second);
+  return range;
+}
+
+TEST(SourceCodeTests, lspLength) {
+  EXPECT_EQ(lspLength(""), 0UL);
+  EXPECT_EQ(lspLength("ascii"), 5UL);
+  // BMP
+  EXPECT_EQ(lspLength("↓"), 1UL);
+  EXPECT_EQ(lspLength("¥"), 1UL);
+  // astral
+  EXPECT_EQ(lspLength("😂"), 2UL);
+
+  WithContextValue UTF8(kCurrentOffsetEncoding, OffsetEncoding::UTF8);
+  EXPECT_EQ(lspLength(""), 0UL);
+  EXPECT_EQ(lspLength("ascii"), 5UL);
+  // BMP
+  EXPECT_EQ(lspLength("↓"), 3UL);
+  EXPECT_EQ(lspLength("¥"), 2UL);
+  // astral
+  EXPECT_EQ(lspLength("😂"), 4UL);
+
+  WithContextValue UTF32(kCurrentOffsetEncoding, OffsetEncoding::UTF32);
+  EXPECT_EQ(lspLength(""), 0UL);
+  EXPECT_EQ(lspLength("ascii"), 5UL);
+  // BMP
+  EXPECT_EQ(lspLength("↓"), 1UL);
+  EXPECT_EQ(lspLength("¥"), 1UL);
+  // astral
+  EXPECT_EQ(lspLength("😂"), 1UL);
+}
+
+// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
+const char File[] = R"(0:0 = 0
+1:0 → 8
+2:0 🡆 18)";
+struct Line {
+  unsigned Number;
+  unsigned Offset;
+  unsigned Length;
+};
+Line FileLines[] = {Line{0, 0, 7}, Line{1, 8, 9}, Line{2, 18, 11}};
+
+TEST(SourceCodeTests, PositionToOffset) {
+  // line out of bounds
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
+  // first line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
+                       llvm::HasValue(0)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
+                       llvm::HasValue(3)); // middle character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
+                       llvm::HasValue(6)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
+                       llvm::HasValue(7)); // the newline itself
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
+                       llvm::HasValue(7));
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
+                       llvm::HasValue(7)); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
+                       llvm::Failed()); // out of range
+  // middle line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
+                       llvm::HasValue(8)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
+                       llvm::HasValue(11)); // middle character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
+                       llvm::HasValue(11));
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
+                       llvm::HasValue(16)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
+                       llvm::HasValue(17)); // the newline itself
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
+                       llvm::HasValue(17)); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
+                       llvm::Failed()); // out of range
+  // last line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
+                       llvm::HasValue(18)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
+                       llvm::HasValue(21)); // middle character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
+                       llvm::Failed()); // middle of surrogate pair
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
+                       llvm::HasValue(26)); // middle of surrogate pair
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
+                       llvm::HasValue(26)); // end of surrogate pair
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
+                       llvm::HasValue(28)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
+                       llvm::HasValue(29)); // EOF
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
+                       llvm::Failed()); // out of range
+  // line out of bounds
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
+
+  // Codepoints are similar, except near astral characters.
+  WithContextValue UTF32(kCurrentOffsetEncoding, OffsetEncoding::UTF32);
+  // line out of bounds
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
+  // first line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
+                       llvm::HasValue(0)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
+                       llvm::HasValue(3)); // middle character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
+                       llvm::HasValue(6)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
+                       llvm::HasValue(7)); // the newline itself
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
+                       llvm::HasValue(7));
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
+                       llvm::HasValue(7)); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
+                       llvm::Failed()); // out of range
+  // middle line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
+                       llvm::HasValue(8)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
+                       llvm::HasValue(11)); // middle character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
+                       llvm::HasValue(11));
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
+                       llvm::HasValue(16)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
+                       llvm::HasValue(17)); // the newline itself
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
+                       llvm::HasValue(17)); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
+                       llvm::Failed()); // out of range
+  // last line
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
+                       llvm::Failed()); // out of range
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
+                       llvm::HasValue(18)); // first character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 4)),
+                       llvm::HasValue(22)); // Before astral character.
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
+                       llvm::HasValue(26)); // after astral character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 7)),
+                       llvm::HasValue(28)); // last character
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
+                       llvm::HasValue(29)); // EOF
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9), false),
+                       llvm::Failed()); // out of range
+  // line out of bounds
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
+
+  // Test UTF-8, where transformations are trivial.
+  WithContextValue UTF8(kCurrentOffsetEncoding, OffsetEncoding::UTF8);
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
+  for (Line L : FileLines) {
+    EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, -1)),
+                         llvm::Failed()); // out of range
+    for (unsigned I = 0; I <= L.Length; ++I)
+      EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, I)),
+                           llvm::HasValue(L.Offset + I));
+    EXPECT_THAT_EXPECTED(positionToOffset(File, position(L.Number, L.Length+1)),
+                         llvm::HasValue(L.Offset + L.Length));
+    EXPECT_THAT_EXPECTED(
+        positionToOffset(File, position(L.Number, L.Length + 1), false),
+        llvm::Failed()); // out of range
+  }
+}
+
+TEST(SourceCodeTests, OffsetToPosition) {
+  EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
+  EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
+  EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
+  EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
+  EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
+  EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
+  EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
+  EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
+  EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
+  EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
+  EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
+  EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
+  EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
+  EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
+  EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
+  EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
+  EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
+  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
+
+  // Codepoints are similar, except near astral characters.
+  WithContextValue UTF32(kCurrentOffsetEncoding, OffsetEncoding::UTF32);
+  EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
+  EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
+  EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
+  EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
+  EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
+  EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
+  EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
+  EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
+  EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
+  EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
+  EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
+  EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
+  EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
+  EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 5)) << "in astral char";
+  EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 5)) << "after astral char";
+  EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 7)) << "end of last line";
+  EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 8)) << "EOF";
+  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 8)) << "out of bounds";
+
+  WithContextValue UTF8(kCurrentOffsetEncoding, OffsetEncoding::UTF8);
+  for (Line L : FileLines) {
+    for (unsigned I = 0; I <= L.Length; ++I)
+      EXPECT_THAT(offsetToPosition(File, L.Offset + I), Pos(L.Number, I));
+  }
+  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 11)) << "out of bounds";
+}
+
+TEST(SourceCodeTests, IsRangeConsecutive) {
+  EXPECT_TRUE(isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
+  EXPECT_FALSE(
+      isRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
+  EXPECT_FALSE(
+      isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
+}
+
+TEST(SourceCodeTests, SourceLocationInMainFile) {
+  Annotations Source(R"cpp(
+    ^in^t ^foo
+    ^bar
+    ^baz ^() {}  {} {} {} { }^
+)cpp");
+
+  SourceManagerForFile Owner("foo.cpp", Source.code());
+  SourceManager &SM = Owner.get();
+
+  SourceLocation StartOfFile = SM.getLocForStartOfFile(SM.getMainFileID());
+  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 0)),
+                       HasValue(StartOfFile));
+  // End of file.
+  EXPECT_THAT_EXPECTED(
+      sourceLocationInMainFile(SM, position(4, 0)),
+      HasValue(StartOfFile.getLocWithOffset(Source.code().size())));
+  // Column number is too large.
+  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 1)), Failed());
+  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 100)),
+                       Failed());
+  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(4, 1)), Failed());
+  // Line number is too large.
+  EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(5, 0)), Failed());
+  // Check all positions mentioned in the test return valid results.
+  for (auto P : Source.points()) {
+    size_t Offset = llvm::cantFail(positionToOffset(Source.code(), P));
+    EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, P),
+                         HasValue(StartOfFile.getLocWithOffset(Offset)));
+  }
+}
+
+TEST(SourceCodeTests, CollectIdentifiers) {
+  auto Style = format::getLLVMStyle();
+  auto IDs = collectIdentifiers(R"cpp(
+  #include "a.h"
+  void foo() { int xyz; int abc = xyz; return foo(); }
+  )cpp",
+                                Style);
+  EXPECT_EQ(IDs.size(), 7u);
+  EXPECT_EQ(IDs["include"], 1u);
+  EXPECT_EQ(IDs["void"], 1u);
+  EXPECT_EQ(IDs["int"], 2u);
+  EXPECT_EQ(IDs["xyz"], 2u);
+  EXPECT_EQ(IDs["abc"], 1u);
+  EXPECT_EQ(IDs["return"], 1u);
+  EXPECT_EQ(IDs["foo"], 2u);
+}
+
+TEST(SourceCodeTests, CollectWords) {
+  auto Words = collectWords(R"cpp(
+  #define FIZZ_BUZZ
+  // this is a comment
+  std::string getSomeText() { return "magic word"; }
+  )cpp");
+  std::set<std::string> ActualWords(Words.keys().begin(), Words.keys().end());
+  std::set<std::string> ExpectedWords = {"define",  "fizz",    "buzz",  "this",
+                                         "comment", "string", "some", "text",
+                                         "return",  "magic",  "word"};
+  EXPECT_EQ(ActualWords, ExpectedWords);
+}
+
+TEST(SourceCodeTests, VisibleNamespaces) {
+  std::vector<std::pair<const char *, std::vector<std::string>>> Cases = {
+      {
+          R"cpp(
+            // Using directive resolved against enclosing namespaces.
+            using namespace foo;
+            namespace ns {
+            using namespace bar;
+          )cpp",
+          {"ns", "", "bar", "foo", "ns::bar"},
+      },
+      {
+          R"cpp(
+            // Don't include namespaces we've closed, ignore namespace aliases.
+            using namespace clang;
+            using std::swap;
+            namespace clang {
+            namespace clangd {}
+            namespace ll = ::llvm;
+            }
+            namespace clang {
+          )cpp",
+          {"clang", ""},
+      },
+      {
+          R"cpp(
+            // Using directives visible even if a namespace is reopened.
+            // Ignore anonymous namespaces.
+            namespace foo{ using namespace bar; }
+            namespace foo{ namespace {
+          )cpp",
+          {"foo", "", "bar", "foo::bar"},
+      },
+      {
+          R"cpp(
+            // Mismatched braces
+            namespace foo{}
+            }}}
+            namespace bar{
+          )cpp",
+          {"bar", ""},
+      },
+      {
+          R"cpp(
+            // Namespaces with multiple chunks.
+            namespace a::b {
+              using namespace c::d;
+              namespace e::f {
+          )cpp",
+          {
+              "a::b::e::f",
+              "",
+              "a",
+              "a::b",
+              "a::b::c::d",
+              "a::b::e",
+              "a::c::d",
+              "c::d",
+          },
+      },
+  };
+  for (const auto& Case : Cases) {
+    EXPECT_EQ(Case.second,
+              visibleNamespaces(Case.first, format::getLLVMStyle()))
+        << Case.first;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/clangd/unittests/SymbolCollectorTests.cpp
similarity index 74%
rename from unittests/clangd/SymbolCollectorTests.cpp
rename to clangd/unittests/SymbolCollectorTests.cpp
index 6f76b17..d372b1d 100644
--- a/unittests/clangd/SymbolCollectorTests.cpp
+++ b/clangd/unittests/SymbolCollectorTests.cpp
@@ -1,9 +1,8 @@
 //===-- SymbolCollectorTests.cpp  -------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,6 +20,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/VirtualFileSystem.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock-more-matchers.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -31,16 +32,16 @@
 namespace clangd {
 namespace {
 
-using testing::_;
-using testing::AllOf;
-using testing::Contains;
-using testing::Eq;
-using testing::Field;
-using testing::IsEmpty;
-using testing::Not;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-using testing::UnorderedElementsAreArray;
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Contains;
+using ::testing::Each;
+using ::testing::ElementsAre;
+using ::testing::Field;
+using ::testing::Not;
+using ::testing::Pair;
+using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
 
 // GMock helpers for matching Symbol.
 MATCHER_P(Labeled, Label, "") {
@@ -52,10 +53,14 @@
   return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
 }
 MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
+MATCHER_P(TemplateArgs, TemplArgs, "") {
+  return arg.TemplateSpecializationArgs == TemplArgs;
+}
 MATCHER_P(DeclURI, P, "") {
   return StringRef(arg.CanonicalDeclaration.FileURI) == P;
 }
 MATCHER_P(DefURI, P, "") { return StringRef(arg.Definition.FileURI) == P; }
+MATCHER(IncludeHeader, "") { return !arg.IncludeHeaders.empty(); }
 MATCHER_P(IncludeHeader, P, "") {
   return (arg.IncludeHeaders.size() == 1) &&
          (arg.IncludeHeaders.begin()->IncludeHeader == P);
@@ -91,16 +96,16 @@
   return static_cast<bool>(arg.Flags & Symbol::VisibleOutsideFile);
 }
 MATCHER(RefRange, "") {
-  const Ref &Pos = testing::get<0>(arg);
-  const Range &Range = testing::get<1>(arg);
+  const Ref &Pos = ::testing::get<0>(arg);
+  const Range &Range = ::testing::get<1>(arg);
   return std::make_tuple(Pos.Location.Start.line(), Pos.Location.Start.column(),
                          Pos.Location.End.line(), Pos.Location.End.column()) ==
          std::make_tuple(Range.start.line, Range.start.character,
                          Range.end.line, Range.end.character);
 }
-testing::Matcher<const std::vector<Ref> &>
+::testing::Matcher<const std::vector<Ref> &>
 HaveRanges(const std::vector<Range> Ranges) {
-  return testing::UnorderedPointwise(RefRange(), Ranges);
+  return ::testing::UnorderedPointwise(RefRange(), Ranges);
 }
 
 class ShouldCollectSymbolTest : public ::testing::Test {
@@ -116,8 +121,8 @@
   // build() must have been called.
   bool shouldCollect(llvm::StringRef Name, bool Qualified = true) {
     assert(AST.hasValue());
-    const NamedDecl& ND = Qualified ? findDecl(*AST, Name) 
-                                    : findUnqualifiedDecl(*AST, Name);
+    const NamedDecl &ND =
+        Qualified ? findDecl(*AST, Name) : findUnqualifiedDecl(*AST, Name);
     ASTContext& Ctx = AST->getASTContext();
     const SourceManager& SM = Ctx.getSourceManager();
     bool MainFile = SM.isWrittenInMainFile(SM.getExpansionLoc(ND.getBeginLoc()));
@@ -213,6 +218,12 @@
         return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
       }
 
+      bool BeginInvocation(CompilerInstance &CI) override {
+        // Make the compiler parse all comments.
+        CI.getLangOpts().CommentOpts.ParseAllComments = true;
+        return WrapperFrontendAction::BeginInvocation(CI);
+      }
+
     private:
       index::IndexingOptions IndexOpts;
       CommentHandler *PragmaHandler;
@@ -241,6 +252,8 @@
     TestFileURI = URI::create(TestFileName).toString();
   }
 
+  // Note that unlike TestTU, no automatic header guard is added.
+  // HeaderCode should start with #pragma once to be treated as modular.
   bool runSymbolCollector(llvm::StringRef HeaderCode, llvm::StringRef MainCode,
                           const std::vector<std::string> &ExtraArgs = {}) {
     llvm::IntrusiveRefCntPtr<FileManager> Files(
@@ -249,9 +262,8 @@
     auto Factory = llvm::make_unique<SymbolIndexActionFactory>(
         CollectorOpts, PragmaHandler.get());
 
-    std::vector<std::string> Args = {
-        "symbol_collector", "-fsyntax-only", "-xc++",
-        "-std=c++11",       "-include",      TestHeaderName};
+    std::vector<std::string> Args = {"symbol_collector", "-fsyntax-only",
+                                     "-xc++", "-include", TestHeaderName};
     Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());
     // This allows to override the "-xc++" with something else, i.e.
     // -xobjective-c++.
@@ -261,8 +273,8 @@
         Args, Factory->create(), Files.get(),
         std::make_shared<PCHContainerOperations>());
 
-    InMemoryFileSystem->addFile(TestHeaderName, 0,
-                                llvm::MemoryBuffer::getMemBuffer(HeaderCode));
+    InMemoryFileSystem->addFile(
+        TestHeaderName, 0, llvm::MemoryBuffer::getMemBuffer(HeaderCode));
     InMemoryFileSystem->addFile(TestFileName, 0,
                                 llvm::MemoryBuffer::getMemBuffer(MainCode));
     Invocation.run();
@@ -326,9 +338,6 @@
     // Namespace alias
     namespace baz = bar;
 
-    // FIXME: using declaration is not supported as the IndexAction will ignore
-    // implicit declarations (the implicit using shadow declaration) by default,
-    // and there is no way to customize this behavior at the moment.
     using bar::v2;
     } // namespace foo
   )";
@@ -355,6 +364,7 @@
                    AllOf(QName("foo::int32_t"), ForCodeCompletion(true)),
                    AllOf(QName("foo::v1"), ForCodeCompletion(true)),
                    AllOf(QName("foo::bar::v2"), ForCodeCompletion(true)),
+                   AllOf(QName("foo::v2"), ForCodeCompletion(true)),
                    AllOf(QName("foo::baz"), ForCodeCompletion(true))}));
 }
 
@@ -389,17 +399,90 @@
 
 TEST_F(SymbolCollectorTest, Template) {
   Annotations Header(R"(
-    // Template is indexed, specialization and instantiation is not.
-    template <class T> struct [[Tmpl]] {T $xdecl[[x]] = 0;};
-    template <> struct Tmpl<int> {};
-    extern template struct Tmpl<float>;
-    template struct Tmpl<double>;
+    // Primary template and explicit specialization are indexed, instantiation
+    // is not.
+    template <class T, class U> struct [[Tmpl]] {T $xdecl[[x]] = 0;};
+    template <> struct $specdecl[[Tmpl]]<int, bool> {};
+    template <class U> struct $partspecdecl[[Tmpl]]<bool, U> {};
+    extern template struct Tmpl<float, bool>;
+    template struct Tmpl<double, bool>;
   )");
   runSymbolCollector(Header.code(), /*Main=*/"");
   EXPECT_THAT(Symbols,
-              UnorderedElementsAreArray(
-                  {AllOf(QName("Tmpl"), DeclRange(Header.range())),
-                   AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")))}));
+              UnorderedElementsAre(
+                  AllOf(QName("Tmpl"), DeclRange(Header.range()),
+                        ForCodeCompletion(true)),
+                  AllOf(QName("Tmpl"), DeclRange(Header.range("specdecl")),
+                        ForCodeCompletion(false)),
+                  AllOf(QName("Tmpl"), DeclRange(Header.range("partspecdecl")),
+                        ForCodeCompletion(false)),
+                  AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")),
+                        ForCodeCompletion(false))));
+}
+
+TEST_F(SymbolCollectorTest, TemplateArgs) {
+  Annotations Header(R"(
+    template <class X> class $barclasstemp[[Bar]] {};
+    template <class T, class U, template<typename> class Z, int Q>
+    struct [[Tmpl]] { T $xdecl[[x]] = 0; };
+
+    // template-template, non-type and type full spec
+    template <> struct $specdecl[[Tmpl]]<int, bool, Bar, 3> {};
+
+    // template-template, non-type and type partial spec
+    template <class U, int T> struct $partspecdecl[[Tmpl]]<bool, U, Bar, T> {};
+    // instantiation
+    extern template struct Tmpl<float, bool, Bar, 8>;
+    // instantiation
+    template struct Tmpl<double, bool, Bar, 2>;
+
+    template <typename ...> class $fooclasstemp[[Foo]] {};
+    // parameter-packs full spec
+    template<> class $parampack[[Foo]]<Bar<int>, int, double> {};
+    // parameter-packs partial spec
+    template<class T> class $parampackpartial[[Foo]]<T, T> {};
+
+    template <int ...> class $bazclasstemp[[Baz]] {};
+    // non-type parameter-packs full spec
+    template<> class $parampacknontype[[Baz]]<3, 5, 8> {};
+    // non-type parameter-packs partial spec
+    template<int T> class $parampacknontypepartial[[Baz]]<T, T> {};
+
+    template <template <class> class ...> class $fozclasstemp[[Foz]] {};
+    // template-template parameter-packs full spec
+    template<> class $parampacktempltempl[[Foz]]<Bar, Bar> {};
+    // template-template parameter-packs partial spec
+    template<template <class> class T>
+    class $parampacktempltemplpartial[[Foz]]<T, T> {};
+  )");
+  runSymbolCollector(Header.code(), /*Main=*/"");
+  EXPECT_THAT(
+      Symbols,
+      AllOf(
+          Contains(AllOf(QName("Tmpl"), TemplateArgs("<int, bool, Bar, 3>"),
+                         DeclRange(Header.range("specdecl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Tmpl"), TemplateArgs("<bool, U, Bar, T>"),
+                         DeclRange(Header.range("partspecdecl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foo"), TemplateArgs("<Bar<int>, int, double>"),
+                         DeclRange(Header.range("parampack")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foo"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampackpartial")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Baz"), TemplateArgs("<3, 5, 8>"),
+                         DeclRange(Header.range("parampacknontype")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Baz"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampacknontypepartial")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foz"), TemplateArgs("<Bar, Bar>"),
+                         DeclRange(Header.range("parampacktempltempl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foz"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampacktempltemplpartial")),
+                         ForCodeCompletion(false)))));
 }
 
 TEST_F(SymbolCollectorTest, ObjCSymbols) {
@@ -438,6 +521,23 @@
                   QName("MyProtocol"), QName("MyProtocol::someMethodName3:")));
 }
 
+TEST_F(SymbolCollectorTest, ObjCPropertyImpl) {
+  const std::string Header = R"(
+    @interface Container
+    @property(nonatomic) int magic;
+    @end
+
+    @implementation Container
+    @end
+  )";
+  TestFileName = testPath("test.m");
+  runSymbolCollector(Header, /*Main=*/"", {"-xobjective-c++"});
+  EXPECT_THAT(Symbols, Contains(QName("Container")));
+  EXPECT_THAT(Symbols, Contains(QName("Container::magic")));
+  // FIXME: Results also contain Container::_magic on some platforms.
+  //        Figure out why it's platform-dependent.
+}
+
 TEST_F(SymbolCollectorTest, Locations) {
   Annotations Header(R"cpp(
     // Declared in header, defined in main.
@@ -555,19 +655,15 @@
   )";
   CollectorOpts.CountReferences = true;
   runSymbolCollector(Header, Main);
-  EXPECT_THAT(Symbols,
-              UnorderedElementsAreArray(
-                {AllOf(QName("W"), RefCount(1)),
-                 AllOf(QName("X"), RefCount(1)),
-                 AllOf(QName("Y"), RefCount(0)),
-                 AllOf(QName("Z"), RefCount(0)), 
-                 AllOf(QName("y"), RefCount(0)),
-                 AllOf(QName("z"), RefCount(0)),
-                 AllOf(QName("x"), RefCount(0)),
-                 AllOf(QName("w"), RefCount(0)),
-                 AllOf(QName("w2"), RefCount(0)),
-                 AllOf(QName("V"), RefCount(1)),
-                 AllOf(QName("v"), RefCount(0))}));
+  EXPECT_THAT(
+      Symbols,
+      UnorderedElementsAreArray(
+          {AllOf(QName("W"), RefCount(1)), AllOf(QName("X"), RefCount(1)),
+           AllOf(QName("Y"), RefCount(0)), AllOf(QName("Z"), RefCount(0)),
+           AllOf(QName("y"), RefCount(0)), AllOf(QName("z"), RefCount(0)),
+           AllOf(QName("x"), RefCount(0)), AllOf(QName("w"), RefCount(0)),
+           AllOf(QName("w2"), RefCount(0)), AllOf(QName("V"), RefCount(1)),
+           AllOf(QName("v"), RefCount(0))}));
 }
 
 TEST_F(SymbolCollectorTest, SymbolRelativeNoFallback) {
@@ -694,6 +790,31 @@
                                    QName("main_f")));
 }
 
+TEST_F(SymbolCollectorTest, Documentation) {
+  const std::string Header = R"(
+    // Doc Foo
+    class Foo {
+      // Doc f
+      int f();
+    };
+  )";
+  CollectorOpts.StoreAllDocumentation = false;
+  runSymbolCollector(Header, /* Main */ "");
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(
+                  AllOf(QName("Foo"), Doc("Doc Foo"), ForCodeCompletion(true)),
+                  AllOf(QName("Foo::f"), Doc(""), ReturnType(""),
+                        ForCodeCompletion(false))));
+
+  CollectorOpts.StoreAllDocumentation = true;
+  runSymbolCollector(Header, /* Main */ "");
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(
+                  AllOf(QName("Foo"), Doc("Doc Foo"), ForCodeCompletion(true)),
+                  AllOf(QName("Foo::f"), Doc("Doc f"), ReturnType(""),
+                        ForCodeCompletion(false))));
+}
+
 TEST_F(SymbolCollectorTest, ClassMembers) {
   const std::string Header = R"(
     class Foo {
@@ -800,54 +921,22 @@
 
 TEST_F(SymbolCollectorTest, IncludeHeaderSameAsFileURI) {
   CollectorOpts.CollectIncludePath = true;
-  runSymbolCollector("class Foo {};", /*Main=*/"");
+  runSymbolCollector("#pragma once\nclass Foo {};", /*Main=*/"");
   EXPECT_THAT(Symbols, UnorderedElementsAre(
                            AllOf(QName("Foo"), DeclURI(TestHeaderURI))));
   EXPECT_THAT(Symbols.begin()->IncludeHeaders,
               UnorderedElementsAre(IncludeHeaderWithRef(TestHeaderURI, 1u)));
 }
 
-#ifndef _WIN32
 TEST_F(SymbolCollectorTest, CanonicalSTLHeader) {
   CollectorOpts.CollectIncludePath = true;
   CanonicalIncludes Includes;
   addSystemHeadersMapping(&Includes);
   CollectorOpts.Includes = &Includes;
-  // bits/basic_string.h$ should be mapped to <string>
-  TestHeaderName = "/nasty/bits/basic_string.h";
-  TestFileName = "/nasty/bits/basic_string.cpp";
-  TestHeaderURI = URI::create(TestHeaderName).toString();
-  runSymbolCollector("class string {};", /*Main=*/"");
-  EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("string"),
-                                                  DeclURI(TestHeaderURI),
-                                                  IncludeHeader("<string>"))));
-}
-#endif
-
-TEST_F(SymbolCollectorTest, STLiosfwd) {
-  CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  addSystemHeadersMapping(&Includes);
-  CollectorOpts.Includes = &Includes;
-  // Symbols from <iosfwd> should be mapped individually.
-  TestHeaderName = testPath("iosfwd");
-  TestFileName = testPath("iosfwd.cpp");
-  std::string Header = R"(
-    namespace std {
-      class no_map {};
-      class ios {};
-      class ostream {};
-      class filebuf {};
-    } // namespace std
-  )";
-  runSymbolCollector(Header, /*Main=*/"");
+  runSymbolCollector("namespace std { class string {}; }", /*Main=*/"");
   EXPECT_THAT(Symbols,
-              UnorderedElementsAre(
-                  QName("std"),
-                  AllOf(QName("std::no_map"), IncludeHeader("<iosfwd>")),
-                  AllOf(QName("std::ios"), IncludeHeader("<ios>")),
-                  AllOf(QName("std::ostream"), IncludeHeader("<ostream>")),
-                  AllOf(QName("std::filebuf"), IncludeHeader("<fstream>"))));
+              Contains(AllOf(QName("std::string"), DeclURI(TestHeaderURI),
+                             IncludeHeader("<string>"))));
 }
 
 TEST_F(SymbolCollectorTest, IWYUPragma) {
@@ -900,53 +989,85 @@
 
 TEST_F(SymbolCollectorTest, MainFileIsHeaderWhenSkipIncFile) {
   CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  CollectorOpts.Includes = &Includes;
-  TestFileName = testPath("main.h");
-  TestFileURI = URI::create(TestFileName).toString();
-  auto IncFile = testPath("test.inc");
-  auto IncURI = URI::create(IncFile).toString();
-  InMemoryFileSystem->addFile(IncFile, 0,
-                              llvm::MemoryBuffer::getMemBuffer("class X {};"));
-  runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
-                     /*ExtraArgs=*/{"-I", testRoot()});
-  EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
-                                                  IncludeHeader(TestFileURI))));
-}
-
-TEST_F(SymbolCollectorTest, MainFileIsHeaderWithoutExtensionWhenSkipIncFile) {
-  CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  CollectorOpts.Includes = &Includes;
+  // To make this case as hard as possible, we won't tell clang main is a
+  // header. No extension, no -x c++-header.
   TestFileName = testPath("no_ext_main");
   TestFileURI = URI::create(TestFileName).toString();
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
                               llvm::MemoryBuffer::getMemBuffer("class X {};"));
-  runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
+  runSymbolCollector("", R"cpp(
+    // Can't use #pragma once in a main file clang doesn't think is a header.
+    #ifndef MAIN_H_
+    #define MAIN_H_
+    #include "test.inc"
+    #endif
+  )cpp",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
                                                   IncludeHeader(TestFileURI))));
 }
 
-TEST_F(SymbolCollectorTest, FallbackToIncFileWhenIncludingFileIsCC) {
+TEST_F(SymbolCollectorTest, IncFileInNonHeader) {
   CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  CollectorOpts.Includes = &Includes;
+  TestFileName = testPath("main.cc");
+  TestFileURI = URI::create(TestFileName).toString();
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
                               llvm::MemoryBuffer::getMemBuffer("class X {};"));
-  runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
+  runSymbolCollector("", R"cpp(
+    #include "test.inc"
+  )cpp",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
-                                                  IncludeHeader(IncURI))));
+                                                  Not(IncludeHeader()))));
+}
+
+// Features that depend on header-guards are fragile. Header guards are only
+// recognized when the file ends, so we have to defer checking for them.
+TEST_F(SymbolCollectorTest, HeaderGuardDetected) {
+  CollectorOpts.CollectIncludePath = true;
+  CollectorOpts.CollectMacro = true;
+  runSymbolCollector(R"cpp(
+    #ifndef HEADER_GUARD_
+    #define HEADER_GUARD_
+
+    // Symbols are seen before the header guard is complete.
+    #define MACRO
+    int decl();
+
+    #endif // Header guard is recognized here.
+  )cpp",
+                     "");
+  EXPECT_THAT(Symbols, Not(Contains(QName("HEADER_GUARD_"))));
+  EXPECT_THAT(Symbols, Each(IncludeHeader()));
+}
+
+TEST_F(SymbolCollectorTest, NonModularHeader) {
+  auto TU = TestTU::withHeaderCode("int x();");
+  EXPECT_THAT(TU.headerSymbols(), ElementsAre(IncludeHeader()));
+
+  // Files missing include guards aren't eligible for insertion.
+  TU.ImplicitHeaderGuard = false;
+  EXPECT_THAT(TU.headerSymbols(), ElementsAre(Not(IncludeHeader())));
+
+  // We recognize some patterns of trying to prevent insertion.
+  TU = TestTU::withHeaderCode(R"cpp(
+#ifndef SECRET
+#error "This file isn't safe to include directly"
+#endif
+    int x();
+    )cpp");
+  TU.ExtraArgs.push_back("-DSECRET"); // *we're* able to include it.
+  EXPECT_THAT(TU.headerSymbols(), ElementsAre(Not(IncludeHeader())));
 }
 
 TEST_F(SymbolCollectorTest, AvoidUsingFwdDeclsAsCanonicalDecls) {
   CollectorOpts.CollectIncludePath = true;
   Annotations Header(R"(
+    #pragma once
     // Forward declarations of TagDecls.
     class C;
     struct S;
@@ -980,7 +1101,8 @@
 
 TEST_F(SymbolCollectorTest, ClassForwardDeclarationIsCanonical) {
   CollectorOpts.CollectIncludePath = true;
-  runSymbolCollector(/*Header=*/"class X;", /*Main=*/"class X {};");
+  runSymbolCollector(/*Header=*/"#pragma once\nclass X;",
+                     /*Main=*/"class X {};");
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(
                            QName("X"), DeclURI(TestHeaderURI),
                            IncludeHeader(TestHeaderURI), DefURI(TestFileURI))));
@@ -1047,27 +1169,34 @@
 TEST_F(SymbolCollectorTest, CollectMacros) {
   CollectorOpts.CollectIncludePath = true;
   Annotations Header(R"(
+    #pragma once
     #define X 1
     #define $mac[[MAC]](x) int x
     #define $used[[USED]](y) float y;
 
     MAC(p);
   )");
-  const std::string Main = R"(
-    #define MAIN 1  // not indexed
-    USED(t);
-  )";
+
+  Annotations Main(R"(
+    #define $main[[MAIN]] 1
+     USED(t);
+  )");
   CollectorOpts.CountReferences = true;
   CollectorOpts.CollectMacro = true;
-  runSymbolCollector(Header.code(), Main);
-  EXPECT_THAT(Symbols,
-              UnorderedElementsAre(QName("p"), QName("t"),
-                                   AllOf(QName("X"), DeclURI(TestHeaderURI),
-                                         IncludeHeader(TestHeaderURI)),
-                                   AllOf(Labeled("MAC(x)"), RefCount(0),
-                                         DeclRange(Header.range("mac"))),
-                                   AllOf(Labeled("USED(y)"), RefCount(1),
-                                         DeclRange(Header.range("used")))));
+  runSymbolCollector(Header.code(), Main.code());
+  EXPECT_THAT(
+      Symbols,
+      UnorderedElementsAre(
+          QName("p"), QName("t"),
+          AllOf(QName("X"), DeclURI(TestHeaderURI),
+                IncludeHeader(TestHeaderURI)),
+          AllOf(Labeled("MAC(x)"), RefCount(0),
+
+                DeclRange(Header.range("mac")), VisibleOutsideFile()),
+          AllOf(Labeled("USED(y)"), RefCount(1),
+                DeclRange(Header.range("used")), VisibleOutsideFile()),
+          AllOf(Labeled("MAIN"), RefCount(0), DeclRange(Main.range("main")),
+                Not(VisibleOutsideFile()))));
 }
 
 TEST_F(SymbolCollectorTest, DeprecatedSymbols) {
@@ -1096,6 +1225,33 @@
                   AllOf(QName("Public"), Not(ImplementationDetail()))));
 }
 
+TEST_F(SymbolCollectorTest, UsingDecl) {
+  const char *Header = R"(
+  void foo();
+  namespace std {
+    using ::foo;
+  })";
+  runSymbolCollector(Header, /**/ "");
+  EXPECT_THAT(Symbols, Contains(QName("std::foo")));
+}
+
+TEST_F(SymbolCollectorTest, CBuiltins) {
+  // In C, printf in stdio.h is a redecl of an implicit builtin.
+  const char *Header = R"(
+    extern int printf(const char*, ...);
+  )";
+  runSymbolCollector(Header, /**/ "", {"-xc"});
+  EXPECT_THAT(Symbols, Contains(QName("printf")));
+}
+
+TEST_F(SymbolCollectorTest, InvalidSourceLoc) {
+  const char *Header = R"(
+      void operator delete(void*)
+        __attribute__((__externally_visible__));)";
+  runSymbolCollector(Header, /**/ "");
+  EXPECT_THAT(Symbols, Contains(QName("operator delete")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/SymbolInfoTests.cpp b/clangd/unittests/SymbolInfoTests.cpp
similarity index 88%
rename from unittests/clangd/SymbolInfoTests.cpp
rename to clangd/unittests/SymbolInfoTests.cpp
index cbd178e..d8d4043 100644
--- a/unittests/clangd/SymbolInfoTests.cpp
+++ b/clangd/unittests/SymbolInfoTests.cpp
@@ -1,9 +1,8 @@
 //===-- SymbolInfoTests.cpp  -----------------------*- C++ -*--------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
@@ -25,7 +24,7 @@
 namespace clangd {
 namespace {
 
-using testing::ElementsAreArray;
+using ::testing::ElementsAreArray;
 
 auto CreateExpectedSymbolDetails = [](const std::string &name,
                                       const std::string &container,
@@ -150,7 +149,13 @@
           #define MACRO 5\nint i = MAC^RO;
         )cpp",
               {CreateExpectedSymbolDetails("MACRO", "",
-                                           "c:TestTU.cpp@55@macro@MACRO")}},
+                                           "c:TestTU.cpp@38@macro@MACRO")}},
+          {
+              R"cpp( // Macro reference
+          #define MACRO 5\nint i = MACRO^;
+        )cpp",
+              {CreateExpectedSymbolDetails("MACRO", "",
+                                           "c:TestTU.cpp@38@macro@MACRO")}},
           {
               R"cpp( // Multiple symbols returned - using overloaded function name
           void foo() {}
@@ -162,7 +167,8 @@
         )cpp",
               {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
                CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
-               CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#")}},
+               CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"),
+               CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}},
           {
               R"cpp( // Multiple symbols returned - implicit conversion
           struct foo {};
@@ -175,12 +181,8 @@
             func_baz1(f^f);
           }
         )cpp",
-              {
-                  CreateExpectedSymbolDetails(
-                      "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff"),
-                  CreateExpectedSymbolDetails(
-                      "bar", "bar::", "c:@S@bar@F@bar#&1$@S@foo#"),
-              }},
+              {CreateExpectedSymbolDetails(
+                  "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff")}},
           {
               R"cpp( // Type reference - declaration
           struct foo;
@@ -208,14 +210,14 @@
             T^T t;
           };
         )cpp",
-              {/* not implemented */}},
+              {CreateExpectedSymbolDetails("TT", "bar::", "c:TestTU.cpp@65")}},
           {
               R"cpp( // Template parameter reference - type param
           template<int NN> struct bar {
             int a = N^N;
           };
         )cpp",
-              {/* not implemented */}},
+              {CreateExpectedSymbolDetails("NN", "bar::", "c:TestTU.cpp@65")}},
           {
               R"cpp( // Class member reference - objec
           struct foo {
@@ -297,6 +299,12 @@
         )cpp",
               {CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}},
           {
+              R"cpp( // Parameters in declarations
+          void foo(int ba^r);
+        )cpp",
+              {CreateExpectedSymbolDetails("bar", "foo",
+                                           "c:TestTU.cpp@50@F@foo#I#@bar")}},
+          {
               R"cpp( // Type inferrence with auto keyword
           struct foo {};
           foo getfoo() { return foo{}; }
diff --git a/unittests/clangd/SyncAPI.cpp b/clangd/unittests/SyncAPI.cpp
similarity index 86%
rename from unittests/clangd/SyncAPI.cpp
rename to clangd/unittests/SyncAPI.cpp
index 83e6b76..102cecb 100644
--- a/unittests/clangd/SyncAPI.cpp
+++ b/clangd/unittests/SyncAPI.cpp
@@ -1,9 +1,8 @@
 //===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -85,10 +84,10 @@
   return std::move(*Result);
 }
 
-llvm::Expected<std::vector<Location>>
-runFindDefinitions(ClangdServer &Server, PathRef File, Position Pos) {
-  llvm::Optional<llvm::Expected<std::vector<Location>>> Result;
-  Server.findDefinitions(File, Pos, capture(Result));
+llvm::Expected<std::vector<LocatedSymbol>>
+runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos) {
+  llvm::Optional<llvm::Expected<std::vector<LocatedSymbol>>> Result;
+  Server.locateSymbolAt(File, Pos, capture(Result));
   return std::move(*Result);
 }
 
@@ -99,10 +98,10 @@
   return std::move(*Result);
 }
 
-llvm::Expected<std::vector<tooling::Replacement>>
-runRename(ClangdServer &Server, PathRef File, Position Pos,
-          llvm::StringRef NewName) {
-  llvm::Optional<llvm::Expected<std::vector<tooling::Replacement>>> Result;
+llvm::Expected<std::vector<TextEdit>> runRename(ClangdServer &Server,
+                                                PathRef File, Position Pos,
+                                                llvm::StringRef NewName) {
+  llvm::Optional<llvm::Expected<std::vector<TextEdit>>> Result;
   Server.rename(File, Pos, NewName, capture(Result));
   return std::move(*Result);
 }
diff --git a/unittests/clangd/SyncAPI.h b/clangd/unittests/SyncAPI.h
similarity index 84%
rename from unittests/clangd/SyncAPI.h
rename to clangd/unittests/SyncAPI.h
index f336e61..c141652 100644
--- a/unittests/clangd/SyncAPI.h
+++ b/clangd/unittests/SyncAPI.h
@@ -1,9 +1,8 @@
 //===--- SyncAPI.h - Sync version of ClangdServer's API ----------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -33,13 +32,13 @@
 llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server,
                                                PathRef File, Position Pos);
 
-llvm::Expected<std::vector<Location>>
-runFindDefinitions(ClangdServer &Server, PathRef File, Position Pos);
+llvm::Expected<std::vector<LocatedSymbol>>
+runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos);
 
 llvm::Expected<std::vector<DocumentHighlight>>
 runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos);
 
-llvm::Expected<std::vector<tooling::Replacement>>
+llvm::Expected<std::vector<TextEdit>>
 runRename(ClangdServer &Server, PathRef File, Position Pos, StringRef NewName);
 
 std::string runDumpAST(ClangdServer &Server, PathRef File);
diff --git a/unittests/clangd/TUSchedulerTests.cpp b/clangd/unittests/TUSchedulerTests.cpp
similarity index 90%
rename from unittests/clangd/TUSchedulerTests.cpp
rename to clangd/unittests/TUSchedulerTests.cpp
index 27cc637..a7d032c 100644
--- a/unittests/clangd/TUSchedulerTests.cpp
+++ b/clangd/unittests/TUSchedulerTests.cpp
@@ -1,9 +1,8 @@
 //===-- TUSchedulerTests.cpp ------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -22,12 +21,9 @@
 namespace clangd {
 namespace {
 
-using ::testing::_;
-using ::testing::AllOf;
 using ::testing::AnyOf;
 using ::testing::Each;
 using ::testing::ElementsAre;
-using ::testing::Pair;
 using ::testing::Pointee;
 using ::testing::UnorderedElementsAre;
 
@@ -38,8 +34,12 @@
 class TUSchedulerTests : public ::testing::Test {
 protected:
   ParseInputs getInputs(PathRef File, std::string Contents) {
-    return ParseInputs{*CDB.getCompileCommand(File),
-                       buildTestFS(Files, Timestamps), std::move(Contents)};
+    ParseInputs Inputs;
+    Inputs.CompileCommand = *CDB.getCompileCommand(File);
+    Inputs.FS = buildTestFS(Files, Timestamps);
+    Inputs.Contents = std::move(Contents);
+    Inputs.Opts = ParseOptions();
+    return Inputs;
   }
 
   void updateWithCallback(TUScheduler &S, PathRef File,
@@ -101,7 +101,7 @@
     TUSchedulerTests::DiagsCallbackKey;
 
 TEST_F(TUSchedulerTests, MissingFiles) {
-  TUScheduler S(getDefaultAsyncThreadsCount(),
+  TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
                 /*StorePreamblesInMemory=*/true, /*ASTCallbacks=*/nullptr,
                 /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
                 ASTRetentionPolicy());
@@ -152,7 +152,7 @@
     // thread until we've scheduled them all.
     Notification Ready;
     TUScheduler S(
-        getDefaultAsyncThreadsCount(),
+        CDB, getDefaultAsyncThreadsCount(),
         /*StorePreamblesInMemory=*/true, captureDiags(),
         /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
         ASTRetentionPolicy());
@@ -182,7 +182,7 @@
 TEST_F(TUSchedulerTests, Debounce) {
   std::atomic<int> CallbackCount(0);
   {
-    TUScheduler S(getDefaultAsyncThreadsCount(),
+    TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
                   /*StorePreamblesInMemory=*/true, captureDiags(),
                   /*UpdateDebounce=*/std::chrono::seconds(1),
                   ASTRetentionPolicy());
@@ -218,7 +218,7 @@
   {
     Notification InconsistentReadDone; // Must live longest.
     TUScheduler S(
-        getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
+        CDB, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
         /*ASTCallbacks=*/nullptr,
         /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
         ASTRetentionPolicy());
@@ -275,7 +275,7 @@
   {
     Notification Proceed; // Ensure we schedule everything.
     TUScheduler S(
-        getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
+        CDB, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
         /*ASTCallbacks=*/captureDiags(),
         /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
         ASTRetentionPolicy());
@@ -344,7 +344,7 @@
 
   // Run TUScheduler and collect some stats.
   {
-    TUScheduler S(getDefaultAsyncThreadsCount(),
+    TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
                   /*StorePreamblesInMemory=*/true, captureDiags(),
                   /*UpdateDebounce=*/std::chrono::milliseconds(50),
                   ASTRetentionPolicy());
@@ -435,10 +435,11 @@
   std::atomic<int> BuiltASTCounter(0);
   ASTRetentionPolicy Policy;
   Policy.MaxRetainedASTs = 2;
-  TUScheduler S(
-      /*AsyncThreadsCount=*/1, /*StorePreambleInMemory=*/true,
-      /*ASTCallbacks=*/nullptr,
-      /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), Policy);
+  TUScheduler S(CDB,
+                /*AsyncThreadsCount=*/1, /*StorePreambleInMemory=*/true,
+                /*ASTCallbacks=*/nullptr,
+                /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
+                Policy);
 
   llvm::StringLiteral SourceContents = R"cpp(
     int* a;
@@ -485,11 +486,11 @@
 }
 
 TEST_F(TUSchedulerTests, EmptyPreamble) {
-  TUScheduler S(
-      /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
-      /*ASTCallbacks=*/nullptr,
-      /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
-      ASTRetentionPolicy());
+  TUScheduler S(CDB,
+                /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
+                /*ASTCallbacks=*/nullptr,
+                /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
+                ASTRetentionPolicy());
 
   auto Foo = testPath("foo.cpp");
   auto Header = testPath("foo.h");
@@ -530,11 +531,11 @@
 TEST_F(TUSchedulerTests, RunWaitsForPreamble) {
   // Testing strategy: we update the file and schedule a few preamble reads at
   // the same time. All reads should get the same non-null preamble.
-  TUScheduler S(
-      /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
-      /*ASTCallbacks=*/nullptr,
-      /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
-      ASTRetentionPolicy());
+  TUScheduler S(CDB,
+                /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
+                /*ASTCallbacks=*/nullptr,
+                /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
+                ASTRetentionPolicy());
   auto Foo = testPath("foo.cpp");
   auto NonEmptyPreamble = R"cpp(
     #define FOO 1
@@ -562,11 +563,11 @@
 }
 
 TEST_F(TUSchedulerTests, NoopOnEmptyChanges) {
-  TUScheduler S(
-      /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
-      /*StorePreambleInMemory=*/true, captureDiags(),
-      /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
-      ASTRetentionPolicy());
+  TUScheduler S(CDB,
+                /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
+                /*StorePreambleInMemory=*/true, captureDiags(),
+                /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
+                ASTRetentionPolicy());
 
   auto Source = testPath("foo.cpp");
   auto Header = testPath("foo.h");
@@ -615,11 +616,11 @@
 }
 
 TEST_F(TUSchedulerTests, NoChangeDiags) {
-  TUScheduler S(
-      /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
-      /*StorePreambleInMemory=*/true, captureDiags(),
-      /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
-      ASTRetentionPolicy());
+  TUScheduler S(CDB,
+                /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
+                /*StorePreambleInMemory=*/true, captureDiags(),
+                /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
+                ASTRetentionPolicy());
 
   auto FooCpp = testPath("foo.cpp");
   auto Contents = "int a; int b;";
@@ -650,7 +651,7 @@
 }
 
 TEST_F(TUSchedulerTests, Run) {
-  TUScheduler S(/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
+  TUScheduler S(CDB, /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
                 /*StorePreambleInMemory=*/true, /*ASTCallbacks=*/nullptr,
                 /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
                 ASTRetentionPolicy());
@@ -685,10 +686,10 @@
   // We schedule the following tasks in the queue:
   //   [Update] [GoToDefinition]
   Server.addDocument(testPath("foo.cpp"), Code.code(), WantDiagnostics::Yes);
-  Server.findDefinitions(testPath("foo.cpp"), Code.point(),
-                         [](Expected<std::vector<Location>> Result) {
-                           ASSERT_TRUE((bool)Result);
-                         });
+  Server.locateSymbolAt(testPath("foo.cpp"), Code.point(),
+                        [](Expected<std::vector<LocatedSymbol>> Result) {
+                          ASSERT_TRUE((bool)Result);
+                        });
 
   ASSERT_TRUE(Server.blockUntilIdleForTest());
 
diff --git a/unittests/clangd/TestFS.cpp b/clangd/unittests/TestFS.cpp
similarity index 95%
rename from unittests/clangd/TestFS.cpp
rename to clangd/unittests/TestFS.cpp
index 082f15a..c5b2613 100644
--- a/unittests/clangd/TestFS.cpp
+++ b/clangd/unittests/TestFS.cpp
@@ -1,9 +1,8 @@
 //===-- TestFS.cpp ----------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "TestFS.h"
diff --git a/unittests/clangd/TestFS.h b/clangd/unittests/TestFS.h
similarity index 92%
rename from unittests/clangd/TestFS.h
rename to clangd/unittests/TestFS.h
index 0226fc3..eabdddf 100644
--- a/unittests/clangd/TestFS.h
+++ b/clangd/unittests/TestFS.h
@@ -1,9 +1,8 @@
 //===-- TestFS.h ------------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/unittests/TestIndex.cpp b/clangd/unittests/TestIndex.cpp
new file mode 100644
index 0000000..11ac423
--- /dev/null
+++ b/clangd/unittests/TestIndex.cpp
@@ -0,0 +1,118 @@
+//===-- TestIndex.cpp -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestIndex.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/Support/Regex.h"
+
+namespace clang {
+namespace clangd {
+
+Symbol symbol(llvm::StringRef QName) {
+  Symbol Sym;
+  Sym.ID = SymbolID(QName.str());
+  size_t Pos = QName.rfind("::");
+  if (Pos == llvm::StringRef::npos) {
+    Sym.Name = QName;
+    Sym.Scope = "";
+  } else {
+    Sym.Name = QName.substr(Pos + 2);
+    Sym.Scope = QName.substr(0, Pos + 2);
+  }
+  return Sym;
+}
+
+static std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle,
+                           llvm::StringRef Repl) {
+  llvm::SmallVector<llvm::StringRef, 8> Parts;
+  Haystack.split(Parts, Needle);
+  return llvm::join(Parts, Repl);
+}
+
+// Helpers to produce fake index symbols for memIndex() or completions().
+// USRFormat is a regex replacement string for the unqualified part of the USR.
+Symbol sym(llvm::StringRef QName, index::SymbolKind Kind,
+           llvm::StringRef USRFormat) {
+  Symbol Sym;
+  std::string USR = "c:"; // We synthesize a few simple cases of USRs by hand!
+  size_t Pos = QName.rfind("::");
+  if (Pos == llvm::StringRef::npos) {
+    Sym.Name = QName;
+    Sym.Scope = "";
+  } else {
+    Sym.Name = QName.substr(Pos + 2);
+    Sym.Scope = QName.substr(0, Pos + 2);
+    USR += "@N@" + replace(QName.substr(0, Pos), "::", "@N@"); // ns:: -> @N@ns
+  }
+  USR += llvm::Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F@func#
+  Sym.ID = SymbolID(USR);
+  Sym.SymInfo.Kind = Kind;
+  Sym.Flags |= Symbol::IndexedForCodeCompletion;
+  Sym.Origin = SymbolOrigin::Static;
+  return Sym;
+}
+
+Symbol func(llvm::StringRef Name) { // Assumes the function has no args.
+  return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args
+}
+
+Symbol cls(llvm::StringRef Name) {
+  return sym(Name, index::SymbolKind::Class, "@S@\\0");
+}
+
+Symbol var(llvm::StringRef Name) {
+  return sym(Name, index::SymbolKind::Variable, "@\\0");
+}
+
+Symbol ns(llvm::StringRef Name) {
+  return sym(Name, index::SymbolKind::Namespace, "@N@\\0");
+}
+
+SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames) {
+  SymbolSlab::Builder Slab;
+  for (llvm::StringRef QName : QualifiedNames)
+    Slab.insert(symbol(QName));
+  return std::move(Slab).build();
+}
+
+SymbolSlab generateNumSymbols(int Begin, int End) {
+  std::vector<std::string> Names;
+  for (int i = Begin; i <= End; i++)
+    Names.push_back(std::to_string(i));
+  return generateSymbols(Names);
+}
+
+std::string getQualifiedName(const Symbol &Sym) {
+  return (Sym.Scope + Sym.Name + Sym.TemplateSpecializationArgs).str();
+}
+
+std::vector<std::string> match(const SymbolIndex &I,
+                               const FuzzyFindRequest &Req, bool *Incomplete) {
+  std::vector<std::string> Matches;
+  bool IsIncomplete = I.fuzzyFind(Req, [&](const Symbol &Sym) {
+    Matches.push_back(clang::clangd::getQualifiedName(Sym));
+  });
+  if (Incomplete)
+    *Incomplete = IsIncomplete;
+  return Matches;
+}
+
+// Returns qualified names of symbols with any of IDs in the index.
+std::vector<std::string> lookup(const SymbolIndex &I,
+                                llvm::ArrayRef<SymbolID> IDs) {
+  LookupRequest Req;
+  Req.IDs.insert(IDs.begin(), IDs.end());
+  std::vector<std::string> Results;
+  I.lookup(Req, [&](const Symbol &Sym) {
+    Results.push_back(getQualifiedName(Sym));
+  });
+  return Results;
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/TestIndex.h b/clangd/unittests/TestIndex.h
similarity index 66%
rename from unittests/clangd/TestIndex.h
rename to clangd/unittests/TestIndex.h
index 01dcc08..01de089 100644
--- a/unittests/clangd/TestIndex.h
+++ b/clangd/unittests/TestIndex.h
@@ -1,9 +1,8 @@
 //===-- IndexHelpers.h ------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,6 +18,19 @@
 // Creates Symbol instance and sets SymbolID to given QualifiedName.
 Symbol symbol(llvm::StringRef QName);
 
+// Helpers to produce fake index symbols with proper SymbolID.
+// USRFormat is a regex replacement string for the unqualified part of the USR.
+Symbol sym(llvm::StringRef QName, index::SymbolKind Kind,
+           llvm::StringRef USRFormat);
+// Creats a function symbol assuming no function arg.
+Symbol func(llvm::StringRef Name);
+// Creates a class symbol.
+Symbol cls(llvm::StringRef Name);
+// Creates a variable symbol.
+Symbol var(llvm::StringRef Name);
+// Creates a namespace symbol.
+Symbol ns(llvm::StringRef Name);
+
 // Create a slab of symbols with the given qualified names as IDs and names.
 SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames);
 
diff --git a/unittests/clangd/TestScheme.h b/clangd/unittests/TestScheme.h
similarity index 100%
rename from unittests/clangd/TestScheme.h
rename to clangd/unittests/TestScheme.h
diff --git a/unittests/clangd/TestTU.cpp b/clangd/unittests/TestTU.cpp
similarity index 76%
rename from unittests/clangd/TestTU.cpp
rename to clangd/unittests/TestTU.cpp
index 6706c44..8f48eab 100644
--- a/unittests/clangd/TestTU.cpp
+++ b/clangd/unittests/TestTU.cpp
@@ -1,9 +1,8 @@
 //===--- TestTU.cpp - Scratch source files for testing --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "index/MemIndex.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Frontend/Utils.h"
 
 namespace clang {
@@ -21,13 +19,25 @@
 
 ParsedAST TestTU::build() const {
   std::string FullFilename = testPath(Filename),
-              FullHeaderName = testPath(HeaderFilename);
+              FullHeaderName = testPath(HeaderFilename),
+              ImportThunk = testPath("import_thunk.h");
+  // We want to implicitly include HeaderFilename without messing up offsets.
+  // -include achieves this, but sometimes we want #import (to simulate a header
+  // guard without messing up offsets). In this case, use an intermediate file.
+  std::string ThunkContents = "#import \"" + FullHeaderName + "\"\n";
+
+  llvm::StringMap<std::string> Files(AdditionalFiles);
+  Files[FullFilename] = Code;
+  Files[FullHeaderName] = HeaderCode;
+  Files[ImportThunk] = ThunkContents;
+
   std::vector<const char *> Cmd = {"clang", FullFilename.c_str()};
   // FIXME: this shouldn't need to be conditional, but it breaks a
   // GoToDefinition test for some reason (getMacroArgExpandedLocation fails).
   if (!HeaderCode.empty()) {
     Cmd.push_back("-include");
-    Cmd.push_back(FullHeaderName.c_str());
+    Cmd.push_back(ImplicitHeaderGuard ? ImportThunk.c_str()
+                                      : FullHeaderName.c_str());
   }
   Cmd.insert(Cmd.end(), ExtraArgs.begin(), ExtraArgs.end());
   ParseInputs Inputs;
@@ -35,17 +45,21 @@
   Inputs.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
   Inputs.CompileCommand.Directory = testRoot();
   Inputs.Contents = Code;
-  Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}});
-  auto PCHs = std::make_shared<PCHContainerOperations>();
+  Inputs.FS = buildTestFS(Files);
+  Inputs.Opts = ParseOptions();
+  Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks;
+  Inputs.Index = ExternalIndex;
+  if (Inputs.Index)
+    Inputs.Opts.SuggestMissingIncludes = true;
   auto CI = buildCompilerInvocation(Inputs);
   assert(CI && "Failed to build compilation invocation.");
   auto Preamble =
       buildPreamble(FullFilename, *CI,
                     /*OldPreamble=*/nullptr,
-                    /*OldCompileCommand=*/Inputs.CompileCommand, Inputs, PCHs,
+                    /*OldCompileCommand=*/Inputs.CompileCommand, Inputs,
                     /*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
   auto AST = buildAST(FullFilename, createInvocationFromCommandLine(Cmd),
-                      Inputs, Preamble, PCHs);
+                      Inputs, Preamble);
   if (!AST.hasValue()) {
     ADD_FAILURE() << "Failed to build code:\n" << Code;
     llvm_unreachable("Failed to build TestTU!");
@@ -55,13 +69,15 @@
 
 SymbolSlab TestTU::headerSymbols() const {
   auto AST = build();
-  return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr());
+  return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr(),
+                            AST.getCanonicalIncludes());
 }
 
 std::unique_ptr<SymbolIndex> TestTU::index() const {
   auto AST = build();
   auto Idx = llvm::make_unique<FileIndex>(/*UseDex=*/true);
-  Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr());
+  Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr(),
+                      AST.getCanonicalIncludes());
   Idx->updateMain(Filename, AST);
   return std::move(Idx);
 }
diff --git a/unittests/clangd/TestTU.h b/clangd/unittests/TestTU.h
similarity index 77%
rename from unittests/clangd/TestTU.h
rename to clangd/unittests/TestTU.h
index ced612f..6ac4c86 100644
--- a/unittests/clangd/TestTU.h
+++ b/clangd/unittests/TestTU.h
@@ -1,9 +1,8 @@
 //===--- TestTU.h - Scratch source files for testing -------------*- C++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -19,8 +18,13 @@
 #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H
 
 #include "ClangdUnit.h"
+#include "Path.h"
 #include "index/Index.h"
+#include "llvm/ADT/StringMap.h"
 #include "gtest/gtest.h"
+#include <string>
+#include <utility>
+#include <vector>
 
 namespace clang {
 namespace clangd {
@@ -46,9 +50,19 @@
   std::string HeaderCode;
   std::string HeaderFilename = "TestTU.h";
 
+  // Name and contents of each file.
+  llvm::StringMap<std::string> AdditionalFiles;
+
   // Extra arguments for the compiler invocation.
   std::vector<const char *> ExtraArgs;
 
+  llvm::Optional<std::string> ClangTidyChecks;
+  // Index to use when building AST.
+  const SymbolIndex *ExternalIndex = nullptr;
+
+  // Simulate a header guard of the header (using an #import directive).
+  bool ImplicitHeaderGuard = true;
+
   ParsedAST build() const;
   SymbolSlab headerSymbols() const;
   std::unique_ptr<SymbolIndex> index() const;
diff --git a/unittests/clangd/ThreadingTests.cpp b/clangd/unittests/ThreadingTests.cpp
similarity index 89%
rename from unittests/clangd/ThreadingTests.cpp
rename to clangd/unittests/ThreadingTests.cpp
index dd27dcc..18b9146 100644
--- a/unittests/clangd/ThreadingTests.cpp
+++ b/clangd/unittests/ThreadingTests.cpp
@@ -1,9 +1,8 @@
 //===-- ThreadingTests.cpp --------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/TraceTests.cpp b/clangd/unittests/TraceTests.cpp
similarity index 94%
rename from unittests/clangd/TraceTests.cpp
rename to clangd/unittests/TraceTests.cpp
index 9811565..1871e6a 100644
--- a/unittests/clangd/TraceTests.cpp
+++ b/clangd/unittests/TraceTests.cpp
@@ -1,9 +1,8 @@
 //===-- TraceTests.cpp - Tracing unit tests ---------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/unittests/TweakTests.cpp b/clangd/unittests/TweakTests.cpp
new file mode 100644
index 0000000..baa6029
--- /dev/null
+++ b/clangd/unittests/TweakTests.cpp
@@ -0,0 +1,190 @@
+//===-- TweakTests.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Annotations.h"
+#include "SourceCode.h"
+#include "TestTU.h"
+#include "refactor/Tweak.h"
+#include "clang/AST/Expr.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <cassert>
+
+using llvm::Failed;
+using llvm::HasValue;
+using llvm::Succeeded;
+
+namespace clang {
+namespace clangd {
+namespace {
+
+std::string markRange(llvm::StringRef Code, Range R) {
+  size_t Begin = llvm::cantFail(positionToOffset(Code, R.start));
+  size_t End = llvm::cantFail(positionToOffset(Code, R.end));
+  assert(Begin <= End);
+  if (Begin == End) // Mark a single point.
+    return (Code.substr(0, Begin) + "^" + Code.substr(Begin)).str();
+  // Mark a range.
+  return (Code.substr(0, Begin) + "[[" + Code.substr(Begin, End - Begin) +
+          "]]" + Code.substr(End))
+      .str();
+}
+
+void checkAvailable(StringRef ID, llvm::StringRef Input, bool Available) {
+  Annotations Code(Input);
+  ASSERT_TRUE(0 < Code.points().size() || 0 < Code.ranges().size())
+      << "no points of interest specified";
+  TestTU TU;
+  TU.Filename = "foo.cpp";
+  TU.Code = Code.code();
+
+  ParsedAST AST = TU.build();
+
+  auto CheckOver = [&](Range Selection) {
+    unsigned Begin = cantFail(positionToOffset(Code.code(), Selection.start));
+    unsigned End = cantFail(positionToOffset(Code.code(), Selection.end));
+    auto T = prepareTweak(ID, Tweak::Selection(AST, Begin, End));
+    if (Available)
+      EXPECT_THAT_EXPECTED(T, Succeeded())
+          << "code is " << markRange(Code.code(), Selection);
+    else
+      EXPECT_THAT_EXPECTED(T, Failed())
+          << "code is " << markRange(Code.code(), Selection);
+  };
+  for (auto P : Code.points())
+    CheckOver(Range{P, P});
+  for (auto R : Code.ranges())
+    CheckOver(R);
+}
+
+/// Checks action is available at every point and range marked in \p Input.
+void checkAvailable(StringRef ID, llvm::StringRef Input) {
+  return checkAvailable(ID, Input, /*Available=*/true);
+}
+
+/// Same as checkAvailable, but checks the action is not available.
+void checkNotAvailable(StringRef ID, llvm::StringRef Input) {
+  return checkAvailable(ID, Input, /*Available=*/false);
+}
+llvm::Expected<std::string> apply(StringRef ID, llvm::StringRef Input) {
+  Annotations Code(Input);
+  Range SelectionRng;
+  if (Code.points().size() != 0) {
+    assert(Code.ranges().size() == 0 &&
+           "both a cursor point and a selection range were specified");
+    SelectionRng = Range{Code.point(), Code.point()};
+  } else {
+    SelectionRng = Code.range();
+  }
+  TestTU TU;
+  TU.Filename = "foo.cpp";
+  TU.Code = Code.code();
+
+  ParsedAST AST = TU.build();
+  unsigned Begin = cantFail(positionToOffset(Code.code(), SelectionRng.start));
+  unsigned End = cantFail(positionToOffset(Code.code(), SelectionRng.end));
+  Tweak::Selection S(AST, Begin, End);
+
+  auto T = prepareTweak(ID, S);
+  if (!T)
+    return T.takeError();
+  auto Replacements = (*T)->apply(S);
+  if (!Replacements)
+    return Replacements.takeError();
+  return applyAllReplacements(Code.code(), *Replacements);
+}
+
+void checkTransform(llvm::StringRef ID, llvm::StringRef Input,
+                    llvm::StringRef Output) {
+  EXPECT_THAT_EXPECTED(apply(ID, Input), HasValue(Output))
+      << "action id is" << ID;
+}
+
+TEST(TweakTest, SwapIfBranches) {
+  llvm::StringLiteral ID = "SwapIfBranches";
+
+  checkAvailable(ID, R"cpp(
+    void test() {
+      ^i^f^^(^t^r^u^e^) { return 100; } ^e^l^s^e^ { continue; }
+    }
+  )cpp");
+
+  checkNotAvailable(ID, R"cpp(
+    void test() {
+      if (true) {^return ^100;^ } else { ^continue^;^ }
+    }
+  )cpp");
+
+  llvm::StringLiteral Input = R"cpp(
+    void test() {
+      ^if (true) { return 100; } else { continue; }
+    }
+  )cpp";
+  llvm::StringLiteral Output = R"cpp(
+    void test() {
+      if (true) { continue; } else { return 100; }
+    }
+  )cpp";
+  checkTransform(ID, Input, Output);
+
+  Input = R"cpp(
+    void test() {
+      ^if () { return 100; } else { continue; }
+    }
+  )cpp";
+  Output = R"cpp(
+    void test() {
+      if () { continue; } else { return 100; }
+    }
+  )cpp";
+  checkTransform(ID, Input, Output);
+
+  // Available in subexpressions of the condition.
+  checkAvailable(ID, R"cpp(
+    void test() {
+      if(2 + [[2]] + 2) { return 2 + 2 + 2; } else { continue; }
+    }
+  )cpp");
+  // But not as part of the branches.
+  checkNotAvailable(ID, R"cpp(
+    void test() {
+      if(2 + 2 + 2) { return 2 + [[2]] + 2; } else { continue; }
+    }
+  )cpp");
+  // Range covers the "else" token, so available.
+  checkAvailable(ID, R"cpp(
+    void test() {
+      if(2 + 2 + 2) { return 2 + [[2 + 2; } else { continue;]] }
+    }
+  )cpp");
+  // Not available in compound statements in condition.
+  checkNotAvailable(ID, R"cpp(
+    void test() {
+      if([]{return [[true]];}()) { return 2 + 2 + 2; } else { continue; }
+    }
+  )cpp");
+  // Not available if both sides aren't braced.
+  checkNotAvailable(ID, R"cpp(
+    void test() {
+      ^if (1) return; else { return; }
+    }
+  )cpp");
+  // Only one if statement is supported!
+  checkNotAvailable(ID, R"cpp(
+    [[if(1){}else{}if(2){}else{}]]
+  )cpp");
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/unittests/TypeHierarchyTests.cpp b/clangd/unittests/TypeHierarchyTests.cpp
new file mode 100644
index 0000000..9fcb94a
--- /dev/null
+++ b/clangd/unittests/TypeHierarchyTests.cpp
@@ -0,0 +1,455 @@
+//===-- TypeHierarchyTests.cpp  ---------------------------*- C++ -*-------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "Annotations.h"
+#include "ClangdUnit.h"
+#include "Compiler.h"
+#include "Matchers.h"
+#include "SyncAPI.h"
+#include "TestFS.h"
+#include "TestTU.h"
+#include "XRefs.h"
+#include "index/FileIndex.h"
+#include "index/SymbolCollector.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Index/IndexingAction.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::AllOf;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::Matcher;
+using ::testing::Pointee;
+using ::testing::UnorderedElementsAreArray;
+
+// GMock helpers for matching TypeHierarchyItem.
+MATCHER_P(WithName, N, "") { return arg.name == N; }
+MATCHER_P(WithKind, Kind, "") { return arg.kind == Kind; }
+MATCHER_P(SelectionRangeIs, R, "") { return arg.selectionRange == R; }
+template <class... ParentMatchers>
+::testing::Matcher<TypeHierarchyItem> Parents(ParentMatchers... ParentsM) {
+  return Field(&TypeHierarchyItem::parents, HasValue(ElementsAre(ParentsM...)));
+}
+
+TEST(FindRecordTypeAt, TypeOrVariable) {
+  Annotations Source(R"cpp(
+struct Ch^ild2 {
+  int c;
+};
+
+int main() {
+  Ch^ild2 ch^ild2;
+  ch^ild2.c = 1;
+}
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  for (Position Pt : Source.points()) {
+    const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt);
+    EXPECT_EQ(&findDecl(AST, "Child2"), static_cast<const NamedDecl *>(RD));
+  }
+}
+
+TEST(FindRecordTypeAt, Method) {
+  Annotations Source(R"cpp(
+struct Child2 {
+  void met^hod ();
+  void met^hod (int x);
+};
+
+int main() {
+  Child2 child2;
+  child2.met^hod(5);
+}
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  for (Position Pt : Source.points()) {
+    const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt);
+    EXPECT_EQ(&findDecl(AST, "Child2"), static_cast<const NamedDecl *>(RD));
+  }
+}
+
+TEST(FindRecordTypeAt, Field) {
+  Annotations Source(R"cpp(
+struct Child2 {
+  int fi^eld;
+};
+
+int main() {
+  Child2 child2;
+  child2.fi^eld = 5;
+}
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  for (Position Pt : Source.points()) {
+    const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt);
+    // A field does not unambiguously specify a record type
+    // (possible associated reocrd types could be the field's type,
+    // or the type of the record that the field is a member of).
+    EXPECT_EQ(nullptr, RD);
+  }
+}
+
+TEST(TypeParents, SimpleInheritance) {
+  Annotations Source(R"cpp(
+struct Parent {
+  int a;
+};
+
+struct Child1 : Parent {
+  int b;
+};
+
+struct Child2 : Child1 {
+  int c;
+};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent"));
+  const CXXRecordDecl *Child1 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Child1"));
+  const CXXRecordDecl *Child2 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Child2"));
+
+  EXPECT_THAT(typeParents(Parent), ElementsAre());
+  EXPECT_THAT(typeParents(Child1), ElementsAre(Parent));
+  EXPECT_THAT(typeParents(Child2), ElementsAre(Child1));
+}
+
+TEST(TypeParents, MultipleInheritance) {
+  Annotations Source(R"cpp(
+struct Parent1 {
+  int a;
+};
+
+struct Parent2 {
+  int b;
+};
+
+struct Parent3 : Parent2 {
+  int c;
+};
+
+struct Child : Parent1, Parent3 {
+  int d;
+};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent1 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent1"));
+  const CXXRecordDecl *Parent2 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent2"));
+  const CXXRecordDecl *Parent3 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent3"));
+  const CXXRecordDecl *Child = dyn_cast<CXXRecordDecl>(&findDecl(AST, "Child"));
+
+  EXPECT_THAT(typeParents(Parent1), ElementsAre());
+  EXPECT_THAT(typeParents(Parent2), ElementsAre());
+  EXPECT_THAT(typeParents(Parent3), ElementsAre(Parent2));
+  EXPECT_THAT(typeParents(Child), ElementsAre(Parent1, Parent3));
+}
+
+TEST(TypeParents, ClassTemplate) {
+  Annotations Source(R"cpp(
+struct Parent {};
+
+template <typename T>
+struct Child : Parent {};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent"));
+  const CXXRecordDecl *Child =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Child"))->getTemplatedDecl();
+
+  EXPECT_THAT(typeParents(Child), ElementsAre(Parent));
+}
+
+MATCHER_P(ImplicitSpecOf, ClassTemplate, "") {
+  const ClassTemplateSpecializationDecl *CTS =
+      dyn_cast<ClassTemplateSpecializationDecl>(arg);
+  return CTS &&
+         CTS->getSpecializedTemplate()->getTemplatedDecl() == ClassTemplate &&
+         CTS->getSpecializationKind() == TSK_ImplicitInstantiation;
+}
+
+// This is similar to findDecl(AST, QName), but supports using
+// a template-id as a query.
+const NamedDecl &findDeclWithTemplateArgs(ParsedAST &AST,
+                                          llvm::StringRef Query) {
+  return findDecl(AST, [&Query](const NamedDecl &ND) {
+    std::string QName;
+    llvm::raw_string_ostream OS(QName);
+    PrintingPolicy Policy(ND.getASTContext().getLangOpts());
+    // Use getNameForDiagnostic() which includes the template
+    // arguments in the printed name.
+    ND.getNameForDiagnostic(OS, Policy, /*Qualified=*/true);
+    OS.flush();
+    return QName == Query;
+  });
+}
+
+TEST(TypeParents, TemplateSpec1) {
+  Annotations Source(R"cpp(
+template <typename T>
+struct Parent {};
+
+template <>
+struct Parent<int> {};
+
+struct Child1 : Parent<float> {};
+
+struct Child2 : Parent<int> {};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Parent"))->getTemplatedDecl();
+  const CXXRecordDecl *ParentSpec =
+      dyn_cast<CXXRecordDecl>(&findDeclWithTemplateArgs(AST, "Parent<int>"));
+  const CXXRecordDecl *Child1 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Child1"));
+  const CXXRecordDecl *Child2 =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Child2"));
+
+  EXPECT_THAT(typeParents(Child1), ElementsAre(ImplicitSpecOf(Parent)));
+  EXPECT_THAT(typeParents(Child2), ElementsAre(ParentSpec));
+}
+
+TEST(TypeParents, TemplateSpec2) {
+  Annotations Source(R"cpp(
+struct Parent {};
+
+template <typename T>
+struct Child {};
+
+template <>
+struct Child<int> : Parent {};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent =
+      dyn_cast<CXXRecordDecl>(&findDecl(AST, "Parent"));
+  const CXXRecordDecl *Child =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Child"))->getTemplatedDecl();
+  const CXXRecordDecl *ChildSpec =
+      dyn_cast<CXXRecordDecl>(&findDeclWithTemplateArgs(AST, "Child<int>"));
+
+  EXPECT_THAT(typeParents(Child), ElementsAre());
+  EXPECT_THAT(typeParents(ChildSpec), ElementsAre(Parent));
+}
+
+TEST(TypeParents, DependentBase) {
+  Annotations Source(R"cpp(
+template <typename T>
+struct Parent {};
+
+template <typename T>
+struct Child1 : Parent<T> {};
+
+template <typename T>
+struct Child2 : Parent<T>::Type {};
+
+template <typename T>
+struct Child3 : T {};
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  const CXXRecordDecl *Parent =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Parent"))->getTemplatedDecl();
+  const CXXRecordDecl *Child1 =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Child1"))->getTemplatedDecl();
+  const CXXRecordDecl *Child2 =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Child2"))->getTemplatedDecl();
+  const CXXRecordDecl *Child3 =
+      dyn_cast<ClassTemplateDecl>(&findDecl(AST, "Child3"))->getTemplatedDecl();
+
+  // For "Parent<T>", use the primary template as a best-effort guess.
+  EXPECT_THAT(typeParents(Child1), ElementsAre(Parent));
+  // For "Parent<T>::Type", there is nothing we can do.
+  EXPECT_THAT(typeParents(Child2), ElementsAre());
+  // Likewise for "T".
+  EXPECT_THAT(typeParents(Child3), ElementsAre());
+}
+
+// Parts of getTypeHierarchy() are tested in more detail by the
+// FindRecordTypeAt.* and TypeParents.* tests above. This test exercises the
+// entire operation.
+TEST(TypeHierarchy, Parents) {
+  Annotations Source(R"cpp(
+struct $Parent1Def[[Parent1]] {
+  int a;
+};
+
+struct $Parent2Def[[Parent2]] {
+  int b;
+};
+
+struct $Parent3Def[[Parent3]] : Parent2 {
+  int c;
+};
+
+struct Ch^ild : Parent1, Parent3 {
+  int d;
+};
+
+int main() {
+  Ch^ild  ch^ild;
+
+  ch^ild.a = 1;
+}
+)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  for (Position Pt : Source.points()) {
+    // Set ResolveLevels to 0 because it's only used for Children;
+    // for Parents, getTypeHierarchy() always returns all levels.
+    llvm::Optional<TypeHierarchyItem> Result = getTypeHierarchy(
+        AST, Pt, /*ResolveLevels=*/0, TypeHierarchyDirection::Parents);
+    ASSERT_TRUE(bool(Result));
+    EXPECT_THAT(
+        *Result,
+        AllOf(
+            WithName("Child"), WithKind(SymbolKind::Struct),
+            Parents(AllOf(WithName("Parent1"), WithKind(SymbolKind::Struct),
+                          SelectionRangeIs(Source.range("Parent1Def")),
+                          Parents()),
+                    AllOf(WithName("Parent3"), WithKind(SymbolKind::Struct),
+                          SelectionRangeIs(Source.range("Parent3Def")),
+                          Parents(AllOf(
+                              WithName("Parent2"), WithKind(SymbolKind::Struct),
+                              SelectionRangeIs(Source.range("Parent2Def")),
+                              Parents()))))));
+  }
+}
+
+TEST(TypeHierarchy, RecursiveHierarchyUnbounded) {
+  Annotations Source(R"cpp(
+  template <int N>
+  struct $SDef[[S]] : S<N + 1> {};
+
+  S^<0> s;
+  )cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  // The compiler should produce a diagnostic for hitting the
+  // template instantiation depth.
+  ASSERT_TRUE(!AST.getDiagnostics().empty());
+
+  // Make sure getTypeHierarchy() doesn't get into an infinite recursion.
+  // FIXME(nridge): It would be preferable if the type hierarchy gave us type
+  // names (e.g. "S<0>" for the child and "S<1>" for the parent) rather than
+  // template names (e.g. "S").
+  llvm::Optional<TypeHierarchyItem> Result = getTypeHierarchy(
+      AST, Source.points()[0], 0, TypeHierarchyDirection::Parents);
+  ASSERT_TRUE(bool(Result));
+  EXPECT_THAT(
+      *Result,
+      AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+            Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+                          SelectionRangeIs(Source.range("SDef")), Parents()))));
+}
+
+TEST(TypeHierarchy, RecursiveHierarchyBounded) {
+  Annotations Source(R"cpp(
+  template <int N>
+  struct $SDef[[S]] : S<N - 1> {};
+
+  template <>
+  struct S<0>{};
+
+  S$SRefConcrete^<2> s;
+
+  template <int N>
+  struct Foo {
+    S$SRefDependent^<N> s;
+  };)cpp");
+
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+
+  ASSERT_TRUE(AST.getDiagnostics().empty());
+
+  // Make sure getTypeHierarchy() doesn't get into an infinite recursion
+  // for either a concrete starting point or a dependent starting point.
+  llvm::Optional<TypeHierarchyItem> Result = getTypeHierarchy(
+      AST, Source.point("SRefConcrete"), 0, TypeHierarchyDirection::Parents);
+  ASSERT_TRUE(bool(Result));
+  EXPECT_THAT(
+      *Result,
+      AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+            Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+                          SelectionRangeIs(Source.range("SDef")), Parents()))));
+  Result = getTypeHierarchy(AST, Source.point("SRefDependent"), 0,
+                            TypeHierarchyDirection::Parents);
+  ASSERT_TRUE(bool(Result));
+  EXPECT_THAT(
+      *Result,
+      AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+            Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
+                          SelectionRangeIs(Source.range("SDef")), Parents()))));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/clangd/URITests.cpp b/clangd/unittests/URITests.cpp
similarity index 96%
rename from unittests/clangd/URITests.cpp
rename to clangd/unittests/URITests.cpp
index ae84d56..52ca7b4 100644
--- a/unittests/clangd/URITests.cpp
+++ b/clangd/unittests/URITests.cpp
@@ -1,9 +1,8 @@
 //===-- URITests.cpp  ---------------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/XRefsTests.cpp b/clangd/unittests/XRefsTests.cpp
similarity index 74%
rename from unittests/clangd/XRefsTests.cpp
rename to clangd/unittests/XRefsTests.cpp
index 88394b6..77fa042 100644
--- a/unittests/clangd/XRefsTests.cpp
+++ b/clangd/unittests/XRefsTests.cpp
@@ -1,9 +1,8 @@
 //===-- XRefsTests.cpp  ---------------------------*- C++ -*--------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
@@ -18,6 +17,7 @@
 #include "index/SymbolCollector.h"
 #include "clang/Index/IndexingAction.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/ScopedPrinter.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -25,11 +25,10 @@
 namespace clangd {
 namespace {
 
-using testing::ElementsAre;
-using testing::Field;
-using testing::IsEmpty;
-using testing::Matcher;
-using testing::UnorderedElementsAreArray;
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+using ::testing::Matcher;
+using ::testing::UnorderedElementsAreArray;
 
 class IgnoreDiagnostics : public DiagnosticsConsumer {
   void onDiagnosticsReady(PathRef File,
@@ -87,6 +86,10 @@
           auto *X = &[[foo]];
         }
       )cpp",
+
+      R"cpp(// Function parameter in decl
+        void foo(int [[^bar]]);
+      )cpp",
   };
   for (const char *Test : Tests) {
     Annotations T(Test);
@@ -96,9 +99,35 @@
   }
 }
 
+MATCHER_P3(Sym, Name, Decl, DefOrNone, "") {
+  llvm::Optional<Range> Def = DefOrNone;
+  if (Name != arg.Name) {
+    *result_listener << "Name is " << arg.Name;
+    return false;
+  }
+  if (Decl != arg.PreferredDeclaration.range) {
+    *result_listener << "Declaration is "
+                     << llvm::to_string(arg.PreferredDeclaration);
+    return false;
+  }
+  if (Def && !arg.Definition) {
+    *result_listener << "Has no definition";
+    return false;
+  }
+  if (Def && arg.Definition->range != *Def) {
+    *result_listener << "Definition is " << llvm::to_string(arg.Definition);
+    return false;
+  }
+  return true;
+}
+::testing::Matcher<LocatedSymbol> Sym(std::string Name, Range Decl) {
+  return Sym(Name, Decl, llvm::None);
+}
+MATCHER_P(Sym, Name, "") { return arg.Name == Name; }
+
 MATCHER_P(RangeIs, R, "") { return arg.range == R; }
 
-TEST(GoToDefinition, WithIndex) {
+TEST(LocateSymbol, WithIndex) {
   Annotations SymbolHeader(R"cpp(
         class $forward[[Forward]];
         class $foo[[Foo]] {};
@@ -116,9 +145,9 @@
   TU.Code = SymbolCpp.code();
   TU.HeaderCode = SymbolHeader.code();
   auto Index = TU.index();
-  auto runFindDefinitionsWithIndex = [&Index](const Annotations &Main) {
+  auto LocateWithIndex = [&Index](const Annotations &Main) {
     auto AST = TestTU::withCode(Main.code()).build();
-    return clangd::findDefinitions(AST, Main.point(), Index.get());
+    return clangd::locateSymbolAt(AST, Main.point(), Index.get());
   };
 
   Annotations Test(R"cpp(// only declaration in AST.
@@ -127,9 +156,8 @@
           ^f1();
         }
       )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-              testing::ElementsAreArray(
-                  {RangeIs(SymbolCpp.range("f1")), RangeIs(Test.range())}));
+  EXPECT_THAT(LocateWithIndex(Test),
+              ElementsAre(Sym("f1", Test.range(), SymbolCpp.range("f1"))));
 
   Test = Annotations(R"cpp(// definition in AST.
         void [[f1]]() {}
@@ -137,30 +165,63 @@
           ^f1();
         }
       )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-              testing::ElementsAreArray(
-                  {RangeIs(Test.range()), RangeIs(SymbolHeader.range("f1"))}));
+  EXPECT_THAT(LocateWithIndex(Test),
+              ElementsAre(Sym("f1", SymbolHeader.range("f1"), Test.range())));
 
   Test = Annotations(R"cpp(// forward declaration in AST.
         class [[Foo]];
         F^oo* create();
       )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-              testing::ElementsAreArray(
-                  {RangeIs(SymbolHeader.range("foo")), RangeIs(Test.range())}));
+  EXPECT_THAT(LocateWithIndex(Test),
+              ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range("foo"))));
 
   Test = Annotations(R"cpp(// defintion in AST.
         class [[Forward]] {};
         F^orward create();
       )cpp");
-  EXPECT_THAT(runFindDefinitionsWithIndex(Test),
-              testing::ElementsAreArray({
-                  RangeIs(Test.range()),
-                  RangeIs(SymbolHeader.range("forward")),
-              }));
+  EXPECT_THAT(
+      LocateWithIndex(Test),
+      ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range())));
 }
 
-TEST(GoToDefinition, All) {
+TEST(LocateSymbol, WithIndexPreferredLocation) {
+  Annotations SymbolHeader(R"cpp(
+        class $p[[Proto]] {};
+        void $f[[func]]() {};
+      )cpp");
+  TestTU TU;
+  TU.HeaderCode = SymbolHeader.code();
+  TU.HeaderFilename = "x.proto"; // Prefer locations in codegen files.
+  auto Index = TU.index();
+
+  Annotations Test(R"cpp(// only declaration in AST.
+        // Shift to make range different.
+        class Proto;
+        void func() {}
+        P$p^roto* create() {
+          fu$f^nc();
+          return nullptr;
+        }
+      )cpp");
+
+  auto AST = TestTU::withCode(Test.code()).build();
+  {
+    auto Locs = clangd::locateSymbolAt(AST, Test.point("p"), Index.get());
+    auto CodeGenLoc = SymbolHeader.range("p");
+    EXPECT_THAT(Locs, ElementsAre(Sym("Proto", CodeGenLoc, CodeGenLoc)));
+  }
+  {
+    auto Locs = clangd::locateSymbolAt(AST, Test.point("f"), Index.get());
+    auto CodeGenLoc = SymbolHeader.range("f");
+    EXPECT_THAT(Locs, ElementsAre(Sym("func", CodeGenLoc, CodeGenLoc)));
+  }
+}
+
+TEST(LocateSymbol, All) {
+  // Ranges in tests:
+  //   $decl is the declaration location (if absent, no symbol is located)
+  //   $def is the definition location (if absent, symbol has no definition)
+  //   unnamed range becomes both $decl and $def.
   const char *Tests[] = {
       R"cpp(// Local variable
         int main() {
@@ -187,7 +248,7 @@
       )cpp",
 
       R"cpp(// Function declaration via call
-        int [[foo]](int);
+        int $decl[[foo]](int);
         int main() {
           return ^foo(42);
         }
@@ -223,7 +284,7 @@
       )cpp",
 
       R"cpp(// Method call
-        struct Foo { int [[x]](); };
+        struct Foo { int $decl[[x]](); };
         int main() {
           Foo bar;
           bar.^x();
@@ -231,20 +292,24 @@
       )cpp",
 
       R"cpp(// Typedef
-        typedef int [[Foo]];
+        typedef int $decl[[Foo]];
         int main() {
           ^Foo bar;
         }
       )cpp",
 
-      /* FIXME: clangIndex doesn't handle template type parameters
       R"cpp(// Template type parameter
-        template <[[typename T]]>
+        template <typename [[T]]>
         void foo() { ^T t; }
-      )cpp", */
+      )cpp",
+
+      R"cpp(// Template template type parameter
+        template <template<typename> class [[T]]>
+        void foo() { ^T<int> t; }
+      )cpp",
 
       R"cpp(// Namespace
-        namespace [[ns]] {
+        namespace $decl[[ns]] {
         struct Foo { static void bar(); }
         } // namespace ns
         int main() { ^ns::Foo::bar(); }
@@ -302,61 +367,137 @@
          FF();
          void f() { T^est a; }
       )cpp",
+
+      R"cpp(// explicit template specialization
+        template <typename T>
+        struct Foo { void bar() {} };
+
+        template <>
+        struct [[Foo]]<int> { void bar() {} };
+
+        void foo() {
+          Foo<char> abc;
+          Fo^o<int> b;
+        }
+      )cpp",
+
+      R"cpp(// implicit template specialization
+        template <typename T>
+        struct [[Foo]] { void bar() {} };
+        template <>
+        struct Foo<int> { void bar() {} };
+        void foo() {
+          Fo^o<char> abc;
+          Foo<int> b;
+        }
+      )cpp",
+
+      R"cpp(// partial template specialization
+        template <typename T>
+        struct Foo { void bar() {} };
+        template <typename T>
+        struct [[Foo]]<T*> { void bar() {} };
+        ^Foo<int*> x;
+      )cpp",
+
+      R"cpp(// function template specializations
+        template <class T>
+        void foo(T) {}
+        template <>
+        void [[foo]](int) {}
+        void bar() {
+          fo^o(10);
+        }
+      )cpp",
+
+      R"cpp(// variable template decls
+        template <class T>
+        T var = T();
+
+        template <>
+        double [[var]]<int> = 10;
+
+        double y = va^r<int>;
+      )cpp",
+
+      R"cpp(// No implicit constructors
+        class X {
+          X(X&& x) = default;
+        };
+        X [[makeX]]() {}
+        void foo() {
+          auto x = m^akeX();
+        }
+      )cpp",
   };
   for (const char *Test : Tests) {
     Annotations T(Test);
+    llvm::Optional<Range> WantDecl;
+    llvm::Optional<Range> WantDef;
+    if (!T.ranges().empty())
+      WantDecl = WantDef = T.range();
+    if (!T.ranges("decl").empty())
+      WantDecl = T.range("decl");
+    if (!T.ranges("def").empty())
+      WantDef = T.range("def");
+
     auto AST = TestTU::withCode(T.code()).build();
-    std::vector<Matcher<Location>> ExpectedLocations;
-    for (const auto &R : T.ranges())
-      ExpectedLocations.push_back(RangeIs(R));
-    EXPECT_THAT(findDefinitions(AST, T.point()),
-                ElementsAreArray(ExpectedLocations))
-        << Test;
+    auto Results = locateSymbolAt(AST, T.point());
+
+    if (!WantDecl) {
+      EXPECT_THAT(Results, IsEmpty()) << Test;
+    } else {
+      ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
+      EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
+      llvm::Optional<Range> GotDef;
+      if (Results[0].Definition)
+        GotDef = Results[0].Definition->range;
+      EXPECT_EQ(WantDef, GotDef) << Test;
+    }
   }
 }
 
-TEST(GoToDefinition, Rank) {
+TEST(LocateSymbol, Ambiguous) {
   auto T = Annotations(R"cpp(
-    struct $foo1[[Foo]] {
-      $foo2[[Foo]]();
-      $foo3[[Foo]](Foo&&);
-      $foo4[[Foo]](const char*);
+    struct Foo {
+      Foo();
+      Foo(Foo&&);
+      Foo(const char*);
     };
 
-    Foo $f[[f]]();
+    Foo f();
 
-    void $g[[g]](Foo foo);
+    void g(Foo foo);
 
     void call() {
-      const char* $str[[str]] = "123";
+      const char* str = "123";
       Foo a = $1^str;
       Foo b = Foo($2^str);
       Foo c = $3^f();
       $4^g($5^f());
       g($6^str);
+      Foo ab$7^c;
+      Foo ab$8^cd("asdf");
+      Foo foox = Fo$9^o("asdf");
     }
   )cpp");
   auto AST = TestTU::withCode(T.code()).build();
-  EXPECT_THAT(findDefinitions(AST, T.point("1")),
-              ElementsAre(RangeIs(T.range("str")), RangeIs(T.range("foo4"))));
-  EXPECT_THAT(findDefinitions(AST, T.point("2")),
-              ElementsAre(RangeIs(T.range("str"))));
-  EXPECT_THAT(findDefinitions(AST, T.point("3")),
-              ElementsAre(RangeIs(T.range("f")), RangeIs(T.range("foo3"))));
-  EXPECT_THAT(findDefinitions(AST, T.point("4")),
-              ElementsAre(RangeIs(T.range("g"))));
-  EXPECT_THAT(findDefinitions(AST, T.point("5")),
-              ElementsAre(RangeIs(T.range("f")), RangeIs(T.range("foo3"))));
-
-  auto DefinitionAtPoint6 = findDefinitions(AST, T.point("6"));
-  EXPECT_EQ(3ul, DefinitionAtPoint6.size());
-  EXPECT_THAT(DefinitionAtPoint6, HasSubsequence(RangeIs(T.range("str")),
-                                                 RangeIs(T.range("foo4"))));
-  EXPECT_THAT(DefinitionAtPoint6, HasSubsequence(RangeIs(T.range("str")),
-                                                 RangeIs(T.range("foo3"))));
+  // Ordered assertions are deliberate: we expect a predictable order.
+  EXPECT_THAT(locateSymbolAt(AST, T.point("1")), ElementsAre(Sym("str")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("3")), ElementsAre(Sym("f")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("5")), ElementsAre(Sym("f")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("6")), ElementsAre(Sym("str")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("7")), ElementsAre(Sym("abc")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("8")),
+              ElementsAre(Sym("Foo"), Sym("abcd")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("9")),
+              // First one is class definition, second is the constructor.
+              ElementsAre(Sym("Foo"), Sym("Foo")));
 }
 
-TEST(GoToDefinition, RelPathsInCompileCommand) {
+TEST(LocateSymbol, RelPathsInCompileCommand) {
   // The source is in "/clangd-test/src".
   // We build in "/clangd-test/build".
 
@@ -398,24 +539,23 @@
 
   // Go to a definition in main source file.
   auto Locations =
-      runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p1"));
+      runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p1"));
   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooCpp, SourceAnnotations.range())));
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo", SourceAnnotations.range())));
 
   // Go to a definition in header_in_preamble.h.
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p2"));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p2"));
   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(HeaderInPreambleH,
-                                    HeaderInPreambleAnnotations.range())));
+  EXPECT_THAT(
+      *Locations,
+      ElementsAre(Sym("bar_preamble", HeaderInPreambleAnnotations.range())));
 
   // Go to a definition in header_not_in_preamble.h.
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p3"));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p3"));
   EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
   EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(HeaderNotInPreambleH,
-                                    HeaderNotInPreambleAnnotations.range())));
+              ElementsAre(Sym("bar_not_preamble",
+                              HeaderNotInPreambleAnnotations.range())));
 }
 
 TEST(Hover, All) {
@@ -616,7 +756,25 @@
             #define MACRO 2
             #undef macro
           )cpp",
-          "#define MACRO",
+          "#define MACRO 1",
+      },
+      {
+          R"cpp(// Macro
+            #define MACRO 0
+            #define MACRO2 ^MACRO
+          )cpp",
+          "#define MACRO 0",
+      },
+      {
+          R"cpp(// Macro
+            #define MACRO {\
+              return 0;\
+            }
+            int main() ^MACRO
+          )cpp",
+          R"cpp(#define MACRO {\
+              return 0;\
+            })cpp",
       },
       {
           R"cpp(// Forward class declaration
@@ -1062,46 +1220,51 @@
   Server.addDocument(FooCpp, SourceAnnotations.code());
 
   // Test include in preamble.
-  auto Locations =
-      runFindDefinitions(Server, FooCpp, SourceAnnotations.point());
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  auto Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point());
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 
   // Test include in preamble, last char.
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("2"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("2"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("3"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("3"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 
   // Test include outside of preamble.
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("6"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("6"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 
   // Test a few positions that do not result in Locations.
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("4"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("4"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
   EXPECT_THAT(*Locations, IsEmpty());
 
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("5"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("5"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 
-  Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("7"));
-  ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error";
-  EXPECT_THAT(*Locations,
-              ElementsAre(FileRange(FooH, HeaderAnnotations.range())));
+  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("7"));
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
+
+  // Objective C #import directive.
+  Annotations ObjC(R"objc(
+  #import "^foo.h"
+  )objc");
+  auto FooM = testPath("foo.m");
+  FS.Files[FooM] = ObjC.code();
+
+  Server.addDocument(FooM, ObjC.code());
+  Locations = runLocateSymbolAt(Server, FooM, ObjC.point());
+  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
+  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
 }
 
-TEST(GoToDefinition, WithPreamble) {
+TEST(LocateSymbol, WithPreamble) {
   // Test stragety: AST should always use the latest preamble instead of last
   // good preamble.
   MockFSProvider FS;
@@ -1121,18 +1284,18 @@
   FS.Files[FooH] = FooHeader.code();
 
   runAddDocument(Server, FooCpp, FooWithHeader.code());
-  // GoToDefinition goes to a #include file: the result comes from the preamble.
+  // LocateSymbol goes to a #include file: the result comes from the preamble.
   EXPECT_THAT(
-      cantFail(runFindDefinitions(Server, FooCpp, FooWithHeader.point())),
-      ElementsAre(FileRange(FooH, FooHeader.range())));
+      cantFail(runLocateSymbolAt(Server, FooCpp, FooWithHeader.point())),
+      ElementsAre(Sym("foo.h", FooHeader.range())));
 
   // Only preamble is built, and no AST is built in this request.
   Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::No);
   // We build AST here, and it should use the latest preamble rather than the
   // stale one.
   EXPECT_THAT(
-      cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())),
-      ElementsAre(FileRange(FooCpp, FooWithoutHeader.range())));
+      cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
+      ElementsAre(Sym("foo", FooWithoutHeader.range())));
 
   // Reset test environment.
   runAddDocument(Server, FooCpp, FooWithHeader.code());
@@ -1140,8 +1303,8 @@
   Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::Yes);
   // Use the AST being built in above request.
   EXPECT_THAT(
-      cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())),
-      ElementsAre(FileRange(FooCpp, FooWithoutHeader.range())));
+      cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
+      ElementsAre(Sym("foo", FooWithoutHeader.range())));
 }
 
 TEST(FindReferences, WithinAST) {
@@ -1199,6 +1362,15 @@
         }
       )cpp",
 
+      R"cpp(// Constructor
+        struct Foo {
+          [[F^oo]](int);
+        };
+        void foo() {
+          Foo f = [[Foo]](42);
+        }
+      )cpp",
+
       R"cpp(// Typedef
         typedef int [[Foo]];
         int main() {
diff --git a/clangd/unittests/lit.cfg.py b/clangd/unittests/lit.cfg.py
new file mode 100644
index 0000000..754835e
--- /dev/null
+++ b/clangd/unittests/lit.cfg.py
@@ -0,0 +1,21 @@
+import lit.formats
+config.name = "Clangd Unit Tests"
+config.test_format = lit.formats.GoogleTest('.', 'Tests')
+config.test_source_root = config.clangd_binary_dir + "/unittests"
+config.test_exec_root = config.clangd_binary_dir + "/unittests"
+
+# Point the dynamic loader at dynamic libraries in 'lib'.
+# FIXME: it seems every project has a copy of this logic. Move it somewhere.
+import platform
+if platform.system() == 'Darwin':
+    shlibpath_var = 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+    shlibpath_var = 'PATH'
+else:
+    shlibpath_var = 'LD_LIBRARY_PATH'
+config.environment[shlibpath_var] = os.path.pathsep.join((
+    "@SHLIBDIR@", "@LLVM_LIBS_DIR@",
+    config.environment.get(shlibpath_var,'')))
+
+
+
diff --git a/clangd/unittests/lit.site.cfg.py.in b/clangd/unittests/lit.site.cfg.py.in
new file mode 100644
index 0000000..3fdf084
--- /dev/null
+++ b/clangd/unittests/lit.site.cfg.py.in
@@ -0,0 +1,11 @@
+@LIT_SITE_CFG_IN_HEADER@
+# This is a shim to run the gtest unittests in ../unittests using lit.
+
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.shlibdir = "@SHLIBDIR@"
+
+config.clangd_source_dir = "@CMAKE_CURRENT_SOURCE_DIR@/.."
+config.clangd_binary_dir = "@CMAKE_CURRENT_BINARY_DIR@/.."
+
+# Delegate logic to lit.cfg.py.
+lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")
diff --git a/unittests/clangd/xpc/CMakeLists.txt b/clangd/unittests/xpc/CMakeLists.txt
similarity index 79%
rename from unittests/clangd/xpc/CMakeLists.txt
rename to clangd/unittests/xpc/CMakeLists.txt
index 229ad5a..21a1667 100644
--- a/unittests/clangd/xpc/CMakeLists.txt
+++ b/clangd/unittests/xpc/CMakeLists.txt
@@ -8,7 +8,8 @@
   ${CLANGD_SOURCE_DIR}
   )
 
-add_extra_unittest(ClangdXpcTests
+add_custom_target(ClangdXpcUnitTests)
+add_unittest(ClangdXpcUnitTests ClangdXpcTests
   ConversionTests.cpp
   )
 
diff --git a/unittests/clangd/xpc/ConversionTests.cpp b/clangd/unittests/xpc/ConversionTests.cpp
similarity index 80%
rename from unittests/clangd/xpc/ConversionTests.cpp
rename to clangd/unittests/xpc/ConversionTests.cpp
index 7acdc61..5d0efd8 100644
--- a/unittests/clangd/xpc/ConversionTests.cpp
+++ b/clangd/unittests/xpc/ConversionTests.cpp
@@ -1,9 +1,8 @@
 //===-- ConversionTests.cpp  --------------------------*- C++ -*-----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/xpc/CMakeLists.txt b/clangd/xpc/CMakeLists.txt
index 788a66f..f05767c 100644
--- a/clangd/xpc/CMakeLists.txt
+++ b/clangd/xpc/CMakeLists.txt
@@ -20,10 +20,10 @@
 
 add_clang_library(clangdXpcJsonConversions
   Conversion.cpp
+  LINK_LIBS clangDaemon
   )
 
 add_clang_library(clangdXpcTransport
   XPCTransport.cpp
-  DEPENDS clangdXpcJsonConversions
-  LINK_LIBS clangdXpcJsonConversions
+  LINK_LIBS clangDaemon clangdXpcJsonConversions
   )
diff --git a/clangd/xpc/Conversion.cpp b/clangd/xpc/Conversion.cpp
index 45bb11a..3e8d36b 100644
--- a/clangd/xpc/Conversion.cpp
+++ b/clangd/xpc/Conversion.cpp
@@ -1,9 +1,8 @@
 //===--- Conversion.cpp - LSP data (de-)serialization through XPC - C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/xpc/Conversion.h b/clangd/xpc/Conversion.h
index 936f51b..fccc095 100644
--- a/clangd/xpc/Conversion.h
+++ b/clangd/xpc/Conversion.h
@@ -1,9 +1,8 @@
 //===--- Conversion.h - LSP data (de-)serialization through XPC -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/xpc/XPCTransport.cpp b/clangd/xpc/XPCTransport.cpp
index 496d8e4..f7df8a9 100644
--- a/clangd/xpc/XPCTransport.cpp
+++ b/clangd/xpc/XPCTransport.cpp
@@ -1,9 +1,8 @@
 //===--- XPCTransport.cpp - sending and receiving LSP messages over XPC ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "Conversion.h"
diff --git a/clangd/xpc/framework/CMakeLists.txt b/clangd/xpc/framework/CMakeLists.txt
index a20340f..7e1ce87 100644
--- a/clangd/xpc/framework/CMakeLists.txt
+++ b/clangd/xpc/framework/CMakeLists.txt
@@ -1,6 +1,7 @@
 
 set(SOURCES
-    ClangdXPC.cpp)
+  ClangdXPC.cpp
+)
 add_clang_library(ClangdXPCLib SHARED
   ${SOURCES}
   DEPENDS
diff --git a/clangd/xpc/framework/ClangdXPC.cpp b/clangd/xpc/framework/ClangdXPC.cpp
index 6c68f5c..3b86164 100644
--- a/clangd/xpc/framework/ClangdXPC.cpp
+++ b/clangd/xpc/framework/ClangdXPC.cpp
@@ -1,3 +1,10 @@
+//===-- ClangdXPC.cpp --------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
 
 /// Returns the bundle identifier of the Clangd XPC service.
 extern "C" const char *clangd_xpc_get_bundle_identifier() {
diff --git a/clangd/xpc/test-client/ClangdXPCTestClient.cpp b/clangd/xpc/test-client/ClangdXPCTestClient.cpp
index da204a6..1cddd06 100644
--- a/clangd/xpc/test-client/ClangdXPCTestClient.cpp
+++ b/clangd/xpc/test-client/ClangdXPCTestClient.cpp
@@ -1,3 +1,11 @@
+//===-- ClangdXPCTestClient.cpp ----------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
 #include "xpc/Conversion.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/SmallString.h"
@@ -41,8 +49,10 @@
   // Open the ClangdXPC dylib in the framework.
   std::string LibPath = getLibraryPath();
   void *dlHandle = dlopen(LibPath.c_str(), RTLD_LOCAL | RTLD_FIRST);
-  if (!dlHandle)
+  if (!dlHandle) {
+    llvm::errs() << "Failed to load framework from \'" << LibPath << "\'\n";
     return 1;
+  }
 
   // Lookup the XPC service bundle name, and launch it.
   clangd_xpc_get_bundle_identifier_t clangd_xpc_get_bundle_identifier =
diff --git a/docs/README.txt b/docs/README.txt
index 4b60777..cebbf63 100644
--- a/docs/README.txt
+++ b/docs/README.txt
@@ -1,11 +1,10 @@
--------------------------------------------------------------
-Documentation for the tools of clang-tools-extra repo project
--------------------------------------------------------------
+----------------------------------
+Documentation in clang-tools-extra
+----------------------------------
 
-Sphinx and doxygen documentation is generated by executing make.
+To generate documentation in HTML format from files in clang-tools-extra/docs,
+build the docs-clang-tools-html target.
 
-Sphinx html files can be generated separately using make html.
+To generate documentation from the source code using Doxygen, build the
+doxygen-clang-tools target.
 
-Doxygen html files can also be generated using make doxygen.
-
-The generated documentation will be placed in _build/html.
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 8731dc7..bb18c6e 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
 ===================================================
-Extra Clang Tools 8.0.0 (In-Progress) Release Notes
+Extra Clang Tools 9.0.0 (In-Progress) Release Notes
 ===================================================
 
 .. contents::
@@ -10,7 +10,7 @@
 
 .. warning::
 
-   These are in-progress notes for the upcoming Extra Clang Tools 8 release.
+   These are in-progress notes for the upcoming Extra Clang Tools 9 release.
    Release notes for previous releases can be found on
    `the Download Page <https://releases.llvm.org/download.html>`_.
 
@@ -18,7 +18,7 @@
 ============
 
 This document contains the release notes for the Extra Clang Tools, part of the
-Clang release 8.0.0. Here we describe the status of the Extra Clang Tools in
+Clang release 9.0.0. Here we describe the status of the Extra Clang Tools in
 some detail, including major improvements from the previous release and new
 feature work. All LLVM releases may be downloaded from the `LLVM releases web
 site <https://llvm.org/releases/>`_.
@@ -32,7 +32,7 @@
 the current one. To see the release notes for a specific release, please
 see the `releases page <https://llvm.org/releases/>`_.
 
-What's New in Extra Clang Tools 8.0.0?
+What's New in Extra Clang Tools 9.0.0?
 ======================================
 
 Some of the major new features and improvements to Extra Clang Tools are listed
@@ -57,47 +57,7 @@
 Improvements to clang-query
 ---------------------------
 
-- A new command line parameter ``--preload`` was added to
-  run commands from a file and then start the interactive interpreter.
-
-- The command ``q`` can was added as an alias for ``quit`` to exit the
-  ``clang-query`` interpreter.
-
-- It is now possible to bind to named values (the result of ``let``
-  expressions). For example:
-
-  .. code-block:: none
-
-    let fn functionDecl()
-    match fn.bind("foo")
-
-- It is now possible to write comments in ``clang-query`` code. This
-  is primarily useful when using script-mode. Comments are all content
-  following the ``#`` character on a line:
-
-  .. code-block:: none
-
-    # This is a comment
-    match fn.bind("foo") # This is a trailing comment
-
-- The new ``set print-matcher true`` command now causes ``clang-query`` to
-  print the evaluated matcher together with the resulting bindings.
-
-- A new output mode ``detailed-ast`` was added to ``clang-query``. The
-  existing ``dump`` output mode is now a deprecated alias
-  for ``detailed-ast``
-
-- Output modes can now be enabled or disabled non-exclusively.  For example,
-
-  .. code-block:: none
-
-    # Enable detailed-ast without disabling other output, such as diag
-    enable output detailed-ast
-    m functionDecl()
-
-    # Disable detailed-ast only
-    disable output detailed-ast
-    m functionDecl()
+- ...
 
 Improvements to clang-rename
 ----------------------------
@@ -107,204 +67,105 @@
 Improvements to clang-tidy
 --------------------------
 
-- New :doc:`abseil-duration-comparison
-  <clang-tidy/checks/abseil-duration-comparison>` check.
+- New OpenMP module.
 
-  Checks for comparisons which should be done in the ``absl::Duration`` domain
-  instead of the float of integer domains.
+  For checks specific to `OpenMP <https://www.openmp.org/>`_ API.
 
-- New :doc:`abseil-duration-division
-  <clang-tidy/checks/abseil-duration-division>` check.
+- New :doc:`abseil-duration-addition
+  <clang-tidy/checks/abseil-duration-addition>` check.
 
-  Checks for uses of ``absl::Duration`` division that is done in a
-  floating-point context, and recommends the use of a function that
-  returns a floating-point value.
+  Checks for cases where addition should be performed in the ``absl::Time``
+  domain.
 
-- New :doc:`abseil-duration-factory-float
-  <clang-tidy/checks/abseil-duration-factory-float>` check.
+- New :doc:`abseil-duration-conversion-cast
+  <clang-tidy/checks/abseil-duration-conversion-cast>` check.
 
-  Checks for cases where the floating-point overloads of various
-  ``absl::Duration`` factory functions are called when the more-efficient
-  integer versions could be used instead.
+  Checks for casts of ``absl::Duration`` conversion functions, and recommends
+  the right conversion function instead.
 
-- New :doc:`abseil-duration-factory-scale
-  <clang-tidy/checks/abseil-duration-factory-scale>` check.
+- New :doc:`abseil-duration-unnecessary-conversion
+  <clang-tidy/checks/abseil-duration-unnecessary-conversion>` check.
 
-  Checks for cases where arguments to ``absl::Duration`` factory functions are
-  scaled internally and could be changed to a different factory function.
+  Finds and fixes cases where ``absl::Duration`` values are being converted to
+  numeric types and back again.
 
-- New :doc:`abseil-duration-subtraction
-  <clang-tidy/checks/abseil-duration-subtraction>` check.
+- New :doc:`abseil-time-comparison
+  <clang-tidy/checks/abseil-time-comparison>` check.
 
-  Checks for cases where subtraction should be performed in the
-  ``absl::Duration`` domain.
+  Prefer comparisons in the ``absl::Time`` domain instead of the integer
+  domain.
 
-- New :doc:`abseil-faster-strsplit-delimiter
-  <clang-tidy/checks/abseil-faster-strsplit-delimiter>` check.
+- New :doc:`abseil-time-subtraction
+  <clang-tidy/checks/abseil-time-subtraction>` check.
 
-  Finds instances of ``absl::StrSplit()`` or ``absl::MaxSplits()`` where the
-  delimiter is a single character string literal and replaces with a character.
+  Finds and fixes ``absl::Time`` subtraction expressions to do subtraction
+  in the Time domain instead of the numeric domain.
 
-- New :doc:`abseil-no-internal-dependencies
-  <clang-tidy/checks/abseil-no-internal-dependencies>` check.
+- New :doc:`google-readability-avoid-underscore-in-googletest-name
+  <clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name>`
+  check.
 
-  Gives a warning if code using Abseil depends on internal details.
+  Checks whether there are underscores in googletest test and test case names in
+  test macros, which is prohibited by the Googletest FAQ.
 
-- New :doc:`abseil-no-namespace
-  <clang-tidy/checks/abseil-no-namespace>` check.
+- New :doc:`objc-super-self <clang-tidy/checks/objc-super-self>` check.
 
-  Ensures code does not open ``namespace absl`` as that violates Abseil's
-  compatibility guidelines.
+  Finds invocations of ``-self`` on super instances in initializers of
+  subclasses of ``NSObject`` and recommends calling a superclass initializer
+  instead.
 
-- New :doc:`abseil-redundant-strcat-calls
-  <clang-tidy/checks/abseil-redundant-strcat-calls>` check.
+- New alias :doc:`cppcoreguidelines-explicit-virtual-functions
+  <clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions>` to
+  :doc:`modernize-use-override
+  <clang-tidy/checks/modernize-use-override>` was added.
 
-  Suggests removal of unnecessary calls to ``absl::StrCat`` when the result is
-  being passed to another ``absl::StrCat`` or ``absl::StrAppend``.
+- The :doc:`bugprone-argument-comment
+  <clang-tidy/checks/bugprone-argument-comment>` now supports
+  `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`,
+  `CommentUserDefiniedLiterals`, `CommentStringLiterals`,
+  `CommentCharacterLiterals` & `CommentNullPtrs` options.
 
-- New :doc:`abseil-str-cat-append
-  <clang-tidy/checks/abseil-str-cat-append>` check.
+- The :doc:`bugprone-too-small-loop-variable
+  <clang-tidy/checks/bugprone-too-small-loop-variable>` now supports
+  `MagnitudeBitsUpperLimit` option. The default value was set to 16,
+  which greatly reduces warnings related to loops which are unlikely to
+  cause an actual functional bug.
 
-  Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
-  ``absl::StrAppend()`` should be used instead.
+- The :doc:`google-runtime-int <clang-tidy/checks/google-runtime-int>`
+  check has been disabled in Objective-C++.
 
-- New :doc:`abseil-upgrade-duration-conversions
-  <clang-tidy/checks/abseil-upgrade-duration-conversions>` check.
+- The `Acronyms` and `IncludeDefaultAcronyms` options for the
+  :doc:`objc-property-declaration <clang-tidy/checks/objc-property-declaration>`
+  check have been removed.
 
-  Finds calls to ``absl::Duration`` arithmetic operators and factories whose
-  argument needs an explicit cast to continue compiling after upcoming API
-  changes.
+- The :doc:`modernize-use-override
+  <clang-tidy/checks/modernize-use-override>` now supports `OverrideSpelling`
+  and `FinalSpelling` options.
 
-- New :doc:`bugprone-too-small-loop-variable
-  <clang-tidy/checks/bugprone-too-small-loop-variable>` check.
+- New :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
+  <clang-tidy/checks/llvm-prefer-isa-or-dyn-cast-in-conditionals>` check.
 
-  Detects those ``for`` loops that have a loop variable with a "too small" type
-  which means this type can't represent all values which are part of the
-  iteration range.
+  Looks at conditionals and finds and replaces cases of ``cast<>``,
+  which will assert rather than return a null pointer, and
+  ``dyn_cast<>`` where the return value is not captured. Additionally,
+  finds and replaces cases that match the pattern ``var &&
+  isa<X>(var)``, where ``var`` is evaluated twice.
 
-- New :doc:`cppcoreguidelines-macro-usage
-  <clang-tidy/checks/cppcoreguidelines-macro-usage>` check.
+- New :doc:`openmp-exception-escape
+  <clang-tidy/checks/openmp-exception-escape>` check.
 
-  Finds macro usage that is considered problematic because better language
-  constructs exist for the task.
+  Analyzes OpenMP Structured Blocks and checks that no exception escapes
+  out of the Structured Block it was thrown in.
 
-- New :doc:`google-objc-function-naming
-  <clang-tidy/checks/google-objc-function-naming>` check.
+- New :doc:`openmp-use-default-none
+  <clang-tidy/checks/openmp-use-default-none>` check.
 
-  Checks that function names in function declarations comply with the naming
-  conventions described in the Google Objective-C Style Guide.
+  Finds OpenMP directives that are allowed to contain a ``default`` clause,
+  but either don't specify it or the clause is specified but with the kind
+  other than ``none``, and suggests to use the ``default(none)`` clause.
 
-- New :doc:`misc-non-private-member-variables-in-classes
-  <clang-tidy/checks/misc-non-private-member-variables-in-classes>` check.
-
-  Finds classes that not only contain the data (non-static member variables),
-  but also have logic (non-static member functions), and diagnoses all member
-  variables that have any other scope other than ``private``.
-
-- New :doc:`modernize-avoid-c-arrays
-  <clang-tidy/checks/modernize-avoid-c-arrays>` check.
-
-  Finds C-style array types and recommend to use ``std::array<>`` /
-  ``std::vector<>``.
-
-- New :doc:`modernize-concat-nested-namespaces
-  <clang-tidy/checks/modernize-concat-nested-namespaces>` check.
-
-  Checks for uses of nested namespaces in the form of
-  ``namespace a { namespace b { ... }}`` and offers change to
-  syntax introduced in C++17 standard: ``namespace a::b { ... }``.
-
-- New :doc:`modernize-deprecated-ios-base-aliases
-  <clang-tidy/checks/modernize-deprecated-ios-base-aliases>` check.
-
-  Detects usage of the deprecated member types of ``std::ios_base`` and replaces
-  those that have a non-deprecated equivalent.
-
-- New :doc:`modernize-use-nodiscard
-  <clang-tidy/checks/modernize-use-nodiscard>` check.
-
-  Adds ``[[nodiscard]]`` attributes (introduced in C++17) to member functions
-  to highlight at compile time which return values should not be ignored.
-
-- New :doc:`readability-isolate-decl
-  <clang-tidy/checks/readability-isolate-declaration>` check.
-
-  Detects local variable declarations declaring more than one variable and
-  tries to refactor the code to one statement per declaration.
-
-- New :doc:`readability-const-return-type
-  <clang-tidy/checks/readability-const-return-type>` check.
-
-  Checks for functions with a ``const``-qualified return type and recommends
-  removal of the ``const`` keyword.
-
-- New :doc:`readability-magic-numbers
-  <clang-tidy/checks/readability-magic-numbers>` check.
-
-  Detects usage of magic numbers, numbers that are used as literals instead of
-  introduced via constants or symbols.
-
-- New :doc:`readability-redundant-preprocessor
-  <clang-tidy/checks/readability-redundant-preprocessor>` check.
-
-  Finds potentially redundant preprocessor directives.
-
-- New :doc:`readability-uppercase-literal-suffix
-  <clang-tidy/checks/readability-uppercase-literal-suffix>` check.
-
-  Detects when the integral literal or floating point literal has non-uppercase
-  suffix, and suggests to make the suffix uppercase. The list of destination
-  suffixes can be optionally provided.
-
-- New alias :doc:`cert-dcl16-c
-  <clang-tidy/checks/cert-dcl16-c>` to :doc:`readability-uppercase-literal-suffix
-  <clang-tidy/checks/readability-uppercase-literal-suffix>`
-  added.
-
-- New alias :doc:`cppcoreguidelines-avoid-c-arrays
-  <clang-tidy/checks/cppcoreguidelines-avoid-c-arrays>`
-  to :doc:`modernize-avoid-c-arrays
-  <clang-tidy/checks/modernize-avoid-c-arrays>` added.
-
-- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes
-  <clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes>`
-  to :doc:`misc-non-private-member-variables-in-classes
-  <clang-tidy/checks/misc-non-private-member-variables-in-classes>`
-  added.
-
-- New alias :doc:`hicpp-avoid-c-arrays
-  <clang-tidy/checks/hicpp-avoid-c-arrays>`
-  to :doc:`modernize-avoid-c-arrays
-  <clang-tidy/checks/modernize-avoid-c-arrays>` added.
-
-- New alias :doc:`hicpp-uppercase-literal-suffix
-  <clang-tidy/checks/hicpp-uppercase-literal-suffix>` to
-  :doc:`readability-uppercase-literal-suffix
-  <clang-tidy/checks/readability-uppercase-literal-suffix>`
-  added.
-
-- The :doc:`cppcoreguidelines-narrowing-conversions
-  <clang-tidy/checks/cppcoreguidelines-narrowing-conversions>` check now
-  detects more narrowing conversions:
-  - integer to narrower signed integer (this is compiler implementation defined),
-  - integer - floating point narrowing conversions,
-  - floating point - integer narrowing conversions,
-  - constants with narrowing conversions (even in ternary operator).
-
-- The :doc:`objc-property-declaration
-  <clang-tidy/checks/objc-property-declaration>` check now ignores the
-  `Acronyms` and `IncludeDefaultAcronyms` options.
-
-- The :doc:`readability-redundant-smartptr-get
-  <clang-tidy/checks/readability-redundant-smartptr-get>` check does not warn
-  about calls inside macros anymore by default.
-
-- The :doc:`readability-uppercase-literal-suffix
-  <clang-tidy/checks/readability-uppercase-literal-suffix>` check does not warn
-  about literal suffixes inside macros anymore by default.
-
-Improvements to include-fixer
------------------------------
+Improvements to clang-include-fixer
+-----------------------------------
 
 The improvements are...
 
@@ -312,3 +173,9 @@
 --------------------------
 
 The improvements are...
+
+Improvements to pp-trace
+------------------------
+
+- Added a new option `-callbacks` to filter preprocessor callbacks. It replaces
+  the `-ignore` option.
diff --git a/docs/_static/clang-tools-extra-styles.css b/docs/_static/clang-tools-extra-styles.css
new file mode 100644
index 0000000..1a6cd71
--- /dev/null
+++ b/docs/_static/clang-tools-extra-styles.css
@@ -0,0 +1,23 @@
+details {
+  background-color: rgba(50, 150, 220, 0.08);
+  margin-bottom: 0.5em;
+  padding: 0 1em;
+  overflow-y: hidden; /* Suppress margin-collapsing */
+}
+details[open] {
+  border-bottom: 1px solid rgba(0, 0, 128, 0.2);
+  margin-bottom: 1em;
+}
+details summary {
+  font-weight: bold;
+  background-color: rgba(50, 150, 220, 0.1);
+  border-color: rgba(0, 0, 128, 0.2);
+  border-width: 1px;
+  border-style: solid none;
+  padding: 0.2em;
+  margin: 0 -1em;
+}
+details summary:hover {
+  background-color: rgba(50, 150, 220, 0.2);
+  cursor: pointer;
+}
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
new file mode 100644
index 0000000..b4f5b4e
--- /dev/null
+++ b/docs/_templates/layout.html
@@ -0,0 +1,3 @@
+{% extends "!layout.html" %}
+
+{% set css_files = css_files + ['_static/clang-tools-extra-styles.css'] %}
diff --git a/docs/clang-doc.rst b/docs/clang-doc.rst
index f891b71..9612068 100644
--- a/docs/clang-doc.rst
+++ b/docs/clang-doc.rst
@@ -20,10 +20,10 @@
 =====
 
 :program:`clang-doc` is a `LibTooling
-<http://clang.llvm.org/docs/LibTooling.html>`_-based tool, and so requires a
+<https://clang.llvm.org/docs/LibTooling.html>`_-based tool, and so requires a
 compile command database for your project (for an example of how to do this 
 see `How To Setup Tooling For LLVM
-<http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_).
+<https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_).
 
 The tool can be used on a single file or multiple files as defined in 
 the compile commands database:
diff --git a/docs/include-fixer.rst b/docs/clang-include-fixer.rst
similarity index 95%
rename from docs/include-fixer.rst
rename to docs/clang-include-fixer.rst
index fcd2998..783f45e 100644
--- a/docs/include-fixer.rst
+++ b/docs/clang-include-fixer.rst
@@ -32,7 +32,7 @@
 ``compile_commands.json`` as generated by CMake does not include header files,
 so only implementation files can be handled by tools.
 
-.. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
 
 Creating a Symbol Index From a Compilation Database
 ---------------------------------------------------
@@ -49,7 +49,7 @@
   $ ninja clang-include-fixer // build clang-include-fixer tool.
   $ ls compile_commands.json # Make sure compile_commands.json exists.
     compile_commands.json
-  $ path/to/llvm/source/tools/clang/tools/extra/include-fixer/find-all-symbols/tool/run-find-all-symbols.py
+  $ path/to/llvm/source/tools/clang/tools/extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py
     ... wait as clang indexes the code base ...
   $ ln -s $PWD/find_all_symbols_db.yaml path/to/llvm/source/ # Link database into the source tree.
   $ ln -s $PWD/compile_commands.json path/to/llvm/source/ # Also link compilation database if it's not there already.
@@ -64,7 +64,7 @@
 
 .. code-block:: console
 
-  noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/clang-include-fixer.py<cr>
+  noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/clang-include-fixer/tool/clang-include-fixer.py<cr>
 
 This enables `clang-include-fixer` for NORMAL and VISUAL mode. Change
 `<leader>cf` to another binding if you need clang-include-fixer on a different
@@ -118,7 +118,7 @@
 
 .. code-block:: console
 
- (add-to-list 'load-path "path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/"
+ (add-to-list 'load-path "path/to/llvm/source/tools/clang/tools/extra/clang-include-fixer/tool/"
  (require 'clang-include-fixer)
 
 Within Emacs the tool can be invoked with the command
diff --git a/docs/clang-rename.rst b/docs/clang-rename.rst
index f622779..2796141 100644
--- a/docs/clang-rename.rst
+++ b/docs/clang-rename.rst
@@ -24,10 +24,10 @@
 ==================
 
 :program:`clang-rename` is a `LibTooling
-<http://clang.llvm.org/docs/LibTooling.html>`_-based tool, and it's easier to
+<https://clang.llvm.org/docs/LibTooling.html>`_-based tool, and it's easier to
 work with if you set up a compile command database for your project (for an
 example of how to do this see `How To Setup Tooling For LLVM
-<http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_). You can also
+<https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_). You can also
 specify compilation options on the command line after `--`:
 
 .. code-block:: console
@@ -139,8 +139,8 @@
 
 You can call :program:`clang-rename` directly from Vim! To set up
 :program:`clang-rename` integration for Vim see
-`clang-rename/tool/clang-rename.py
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-rename/tool/clang-rename.py>`_.
+`clang/tools/clang-rename/clang-rename.py
+<https://github.com/llvm/llvm-project/blob/master/clang/tools/clang-rename/clang-rename.py>`_.
 
 Please note that **you have to save all buffers, in which the replacement will
 happen before running the tool**.
@@ -157,7 +157,7 @@
 You can also use :program:`clang-rename` while using Emacs! To set up
 :program:`clang-rename` integration for Emacs see
 `clang-rename/tool/clang-rename.el
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-rename/tool/clang-rename.el>`_.
+<https://github.com/llvm/llvm-project/blob/master/clang/tools/clang-rename/clang-rename.el>`_.
 
 Once installed, you can point your cursor to symbols you want to rename, press
 `M-X`, type `clang-rename` and new desired name.
diff --git a/docs/clang-tidy.rst b/docs/clang-tidy.rst
index bcd2bf1..b9a1806 100644
--- a/docs/clang-tidy.rst
+++ b/docs/clang-tidy.rst
@@ -3,4 +3,4 @@
 .. meta::
    :http-equiv=refresh: 0;URL='clang-tidy/'
 
-clang-tidy documentation has moved here: http://clang.llvm.org/extra/clang-tidy/
+clang-tidy documentation has moved here: https://clang.llvm.org/extra/clang-tidy/
diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst
new file mode 100644
index 0000000..09ff1f6
--- /dev/null
+++ b/docs/clang-tidy/Contributing.rst
@@ -0,0 +1,513 @@
+================
+Getting Involved
+================
+
+:program:`clang-tidy` has several own checks and can run Clang static analyzer
+checks, but its power is in the ability to easily write custom checks.
+
+Checks are organized in modules, which can be linked into :program:`clang-tidy`
+with minimal or no code changes in :program:`clang-tidy`.
+
+Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_
+or on the AST level using `AST Matchers`_. When an error is found, checks can
+report them in a way similar to how Clang diagnostics work. A fix-it hint can be
+attached to a diagnostic message.
+
+The interface provided by :program:`clang-tidy` makes it easy to write useful
+and precise checks in just a few lines of code. If you have an idea for a good
+check, the rest of this document explains how to do this.
+
+There are a few tools particularly useful when developing clang-tidy checks:
+  * ``add_new_check.py`` is a script to automate the process of adding a new
+    check, it will create the check, update the CMake file and create a test;
+  * ``rename_check.py`` does what the script name suggests, renames an existing
+    check;
+  * :program:`clang-query` is invaluable for interactive prototyping of AST
+    matchers and exploration of the Clang AST;
+  * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``)
+    provides a convenient way to dump AST of a C++ program.
+
+If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``,
+:program:`clang-tidy` will not be built with support for the
+``clang-analyzer-*`` checks or the ``mpi-*`` checks.
+
+
+.. _AST Matchers: https://clang.llvm.org/docs/LibASTMatchers.html
+.. _PPCallbacks: https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html
+.. _clang-check: https://clang.llvm.org/docs/ClangCheck.html
+
+
+Choosing the Right Place for your Check
+---------------------------------------
+
+If you have an idea of a check, you should decide whether it should be
+implemented as a:
+
++ *Clang diagnostic*: if the check is generic enough, targets code patterns that
+  most probably are bugs (rather than style or readability issues), can be
+  implemented effectively and with extremely low false positive rate, it may
+  make a good Clang diagnostic.
+
++ *Clang static analyzer check*: if the check requires some sort of control flow
+  analysis, it should probably be implemented as a static analyzer check.
+
++ *clang-tidy check* is a good choice for linter-style checks, checks that are
+  related to a certain coding style, checks that address code readability, etc.
+
+
+Preparing your Workspace
+------------------------
+
+If you are new to LLVM development, you should read the `Getting Started with
+the LLVM System`_, `Using Clang Tools`_ and `How To Setup Clang Tooling For
+LLVM`_ documents to check out and build LLVM, Clang and Clang Extra Tools with
+CMake.
+
+Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and
+let's start!
+
+.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
+.. _Using Clang Tools: https://clang.llvm.org/docs/ClangTools.html
+.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+
+
+The Directory Structure
+-----------------------
+
+:program:`clang-tidy` source code resides in the
+``llvm/tools/clang/tools/extra`` directory and is structured as follows:
+
+::
+
+  clang-tidy/                       # Clang-tidy core.
+  |-- ClangTidy.h                   # Interfaces for users.
+  |-- ClangTidyCheck.h              # Interfaces for checks.
+  |-- ClangTidyModule.h             # Interface for clang-tidy modules.
+  |-- ClangTidyModuleRegistry.h     # Interface for registering of modules.
+     ...
+  |-- google/                       # Google clang-tidy module.
+  |-+
+    |-- GoogleTidyModule.cpp
+    |-- GoogleTidyModule.h
+          ...
+  |-- llvm/                         # LLVM clang-tidy module.
+  |-+
+    |-- LLVMTidyModule.cpp
+    |-- LLVMTidyModule.h
+          ...
+  |-- objc/                         # Objective-C clang-tidy module.
+  |-+
+    |-- ObjCTidyModule.cpp
+    |-- ObjCTidyModule.h
+          ...
+  |-- tool/                         # Sources of the clang-tidy binary.
+          ...
+  test/clang-tidy/                  # Integration tests.
+      ...
+  unittests/clang-tidy/             # Unit tests.
+  |-- ClangTidyTest.h
+  |-- GoogleModuleTest.cpp
+  |-- LLVMModuleTest.cpp
+  |-- ObjCModuleTest.cpp
+      ...
+
+
+Writing a clang-tidy Check
+--------------------------
+
+So you have an idea of a useful check for :program:`clang-tidy`.
+
+First, if you're not familiar with LLVM development, read through the `Getting
+Started with LLVM`_ document for instructions on setting up your workflow and
+the `LLVM Coding Standards`_ document to familiarize yourself with the coding
+style used in the project. For code reviews we mostly use `LLVM Phabricator`_.
+
+.. _Getting Started with LLVM: https://llvm.org/docs/GettingStarted.html
+.. _LLVM Coding Standards: https://llvm.org/docs/CodingStandards.html
+.. _LLVM Phabricator: https://llvm.org/docs/Phabricator.html
+
+Next, you need to decide which module the check belongs to. Modules
+are located in subdirectories of `clang-tidy/
+<https://github.com/llvm/llvm-project/tree/master/clang-tools-extra/clang-tidy/>`_
+and contain checks targeting a certain aspect of code quality (performance,
+readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.)
+or a widely used API (e.g. MPI). Their names are same as user-facing check
+groups names described :ref:`above <checks-groups-table>`.
+
+After choosing the module and the name for the check, run the
+``clang-tidy/add_new_check.py`` script to create the skeleton of the check and
+plug it to :program:`clang-tidy`. It's the recommended way of adding new checks.
+
+If we want to create a `readability-awesome-function-names`, we would run:
+
+.. code-block:: console
+
+  $ clang-tidy/add_new_check.py readability awesome-function-names
+
+
+The ``add_new_check.py`` script will:
+  * create the class for your check inside the specified module's directory and
+    register it in the module and in the build system;
+  * create a lit test file in the ``test/clang-tidy/`` directory;
+  * create a documentation file and include it into the
+    ``docs/clang-tidy/checks/list.rst``.
+
+Let's see in more detail at the check class definition:
+
+.. code-block:: c++
+
+  ...
+
+  #include "../ClangTidyCheck.h"
+
+  namespace clang {
+  namespace tidy {
+  namespace readability {
+
+  ...
+  class AwesomeFunctionNamesCheck : public ClangTidyCheck {
+  public:
+    AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context)
+        : ClangTidyCheck(Name, Context) {}
+    void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+    void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  };
+
+  } // namespace readability
+  } // namespace tidy
+  } // namespace clang
+
+  ...
+
+Constructor of the check receives the ``Name`` and ``Context`` parameters, and
+must forward them to the ``ClangTidyCheck`` constructor.
+
+In our case the check needs to operate on the AST level and it overrides the
+``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the
+preprocessor level, we'd need instead to override the ``registerPPCallbacks``
+method.
+
+In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_
+for more information) that will find the pattern in the AST that we want to
+inspect. The results of the matching are passed to the ``check`` method, which
+can further inspect them and report diagnostics.
+
+.. code-block:: c++
+
+  using namespace ast_matchers;
+
+  void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) {
+    Finder->addMatcher(functionDecl().bind("x"), this);
+  }
+
+  void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) {
+    const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");
+    if (MatchedDecl->getName().startswith("awesome_"))
+      return;
+    diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome")
+        << MatchedDecl
+        << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
+  }
+
+(If you want to see an example of a useful check, look at
+`clang-tidy/google/ExplicitConstructorCheck.h
+<https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h>`_
+and `clang-tidy/google/ExplicitConstructorCheck.cpp
+<https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_).
+
+
+Registering your Check
+----------------------
+
+(The ``add_new_check.py`` takes care of registering the check in an existing
+module. If you want to create a new module or know the details, read on.)
+
+The check should be registered in the corresponding module with a distinct name:
+
+.. code-block:: c++
+
+  class MyModule : public ClangTidyModule {
+   public:
+    void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+      CheckFactories.registerCheck<ExplicitConstructorCheck>(
+          "my-explicit-constructor");
+    }
+  };
+
+Now we need to register the module in the ``ClangTidyModuleRegistry`` using a
+statically initialized variable:
+
+.. code-block:: c++
+
+  static ClangTidyModuleRegistry::Add<MyModule> X("my-module",
+                                                  "Adds my lint checks.");
+
+
+When using LLVM build system, we need to use the following hack to ensure the
+module is linked into the :program:`clang-tidy` binary:
+
+Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable:
+
+.. code-block:: c++
+
+  // This anchor is used to force the linker to link in the generated object file
+  // and thus register the MyModule.
+  volatile int MyModuleAnchorSource = 0;
+
+And this to the main translation unit of the :program:`clang-tidy` binary (or
+the binary you link the ``clang-tidy`` library in)
+``clang-tidy/tool/ClangTidyMain.cpp``:
+
+.. code-block:: c++
+
+  // This anchor is used to force the linker to link the MyModule.
+  extern volatile int MyModuleAnchorSource;
+  static int MyModuleAnchorDestination = MyModuleAnchorSource;
+
+
+Configuring Checks
+------------------
+
+If a check needs configuration options, it can access check-specific options
+using the ``Options.get<Type>("SomeOption", DefaultValue)`` call in the check
+constructor. In this case the check should also override the
+``ClangTidyCheck::storeOptions`` method to make the options provided by the
+check discoverable. This method lets :program:`clang-tidy` know which options
+the check implements and what the current values are (e.g. for the
+``-dump-config`` command line option).
+
+.. code-block:: c++
+
+  class MyCheck : public ClangTidyCheck {
+    const unsigned SomeOption1;
+    const std::string SomeOption2;
+
+  public:
+    MyCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context),
+        SomeOption(Options.get("SomeOption1", -1U)),
+        SomeOption(Options.get("SomeOption2", "some default")) {}
+
+    void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
+      Options.store(Opts, "SomeOption1", SomeOption1);
+      Options.store(Opts, "SomeOption2", SomeOption2);
+    }
+    ...
+
+Assuming the check is registered with the name "my-check", the option can then
+be set in a ``.clang-tidy`` file in the following way:
+
+.. code-block:: yaml
+
+  CheckOptions:
+    - key: my-check.SomeOption1
+      value: 123
+    - key: my-check.SomeOption2
+      value: 'some other value'
+
+If you need to specify check options on a command line, you can use the inline
+YAML format:
+
+.. code-block:: console
+
+  $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ...
+
+
+Testing Checks
+--------------
+
+To run tests for :program:`clang-tidy` use the command:
+
+.. code-block:: console
+
+  $ ninja check-clang-tools
+
+:program:`clang-tidy` checks can be tested using either unit tests or
+`lit`_ tests. Unit tests may be more convenient to test complex replacements
+with strict checks. `Lit`_ tests allow using partial text matching and regular
+expressions which makes them more suitable for writing compact tests for
+diagnostic messages.
+
+The ``check_clang_tidy.py`` script provides an easy way to test both
+diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test
+file, runs :program:`clang-tidy` and verifies messages and fixes with two
+separate `FileCheck`_ invocations: once with FileCheck's directive
+prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages,
+and once with the directive prefix set to ``CHECK-FIXES``, running
+against the fixed code (i.e., the code after generated fix-its are
+applied). In particular, ``CHECK-FIXES:`` can be used to check
+that code was not modified by fix-its, by checking that it is present
+unchanged in the fixed code. The full set of `FileCheck`_ directives
+is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though
+typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``)
+are sufficient for clang-tidy tests. Note that the `FileCheck`_
+documentation mostly assumes the default prefix (``CHECK``), and hence
+describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc.
+Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for
+clang-tidy tests.
+
+An additional check enabled by ``check_clang_tidy.py`` ensures that
+if `CHECK-MESSAGES:` is used in a file then every warning or error
+must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:``
+instead, if you want to **also** ensure that all the notes are checked.
+
+To use the ``check_clang_tidy.py`` script, put a .cpp file with the
+appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use
+``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against
+diagnostic messages and fixed code.
+
+It's advised to make the checks as specific as possible to avoid checks matching
+to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]``
+substitutions and distinct function and variable names in the test code.
+
+Here's an example of a test using the ``check_clang_tidy.py`` script (the full
+source code is at `test/clang-tidy/google-readability-casting.cpp`_):
+
+.. code-block:: c++
+
+  // RUN: %check_clang_tidy %s google-readability-casting %t
+
+  void f(int a) {
+    int b = (int)a;
+    // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting]
+    // CHECK-FIXES: int b = a;
+  }
+
+To check more than one scenario in the same test file use
+``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or
+``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``.
+With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*``
+directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``.
+
+Here's an example:
+
+.. code-block:: c++
+
+   // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A
+   // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B
+   // RUN: %check_clang_tidy %s misc-unused-using-decls %t
+   ...
+   // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}}
+   // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}}
+   // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}}
+   // CHECK-FIXES-USING-A-NOT: using a::A;$
+   // CHECK-FIXES-USING-B-NOT: using a::B;$
+   // CHECK-FIXES-NOT: using a::C;$
+
+
+There are many dark corners in the C++ language, and it may be difficult to make
+your check work perfectly in all cases, especially if it issues fix-it hints. The
+most frequent pitfalls are macros and templates:
+
+1. code written in a macro body/template definition may have a different meaning
+   depending on the macro expansion/template instantiation;
+2. multiple macro expansions/template instantiations may result in the same code
+   being inspected by the check multiple times (possibly, with different
+   meanings, see 1), and the same warning (or a slightly different one) may be
+   issued by the check multiple times; :program:`clang-tidy` will deduplicate
+   _identical_ warnings, but if the warnings are slightly different, all of them
+   will be shown to the user (and used for applying fixes, if any);
+3. making replacements to a macro body/template definition may be fine for some
+   macro expansions/template instantiations, but easily break some other
+   expansions/instantiations.
+
+.. _lit: https://llvm.org/docs/CommandGuide/lit.html
+.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html
+.. _test/clang-tidy/google-readability-casting.cpp: https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp
+
+
+Running clang-tidy on LLVM
+--------------------------
+
+To test a check it's best to try it out on a larger code base. LLVM and Clang
+are the natural targets as you already have the source code around. The most
+convenient way to run :program:`clang-tidy` is with a compile command database;
+CMake can automatically generate one, for a description of how to enable it see
+`How To Setup Clang Tooling For LLVM`_. Once ``compile_commands.json`` is in
+place and a working version of :program:`clang-tidy` is in ``PATH`` the entire
+code base can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script
+executes :program:`clang-tidy` with the default set of checks on every
+translation unit in the compile command database and displays the resulting
+warnings and errors. The script provides multiple configuration flags.
+
+.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+
+
+* The default set of checks can be overridden using the ``-checks`` argument,
+  taking the identical format as :program:`clang-tidy` does. For example
+  ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override``
+  check only.
+
+* To restrict the files examined you can provide one or more regex arguments
+  that the file names are matched against.
+  ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy
+  checks. It may also be necessary to restrict the header files warnings are
+  displayed from using the ``-header-filter`` flag. It has the same behavior
+  as the corresponding :program:`clang-tidy` flag.
+
+* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers
+  all changes in a temporary directory and applies them. Passing ``-format``
+  will run clang-format over changed lines.
+
+
+On checks profiling
+-------------------
+
+:program:`clang-tidy` can collect per-check profiling info, and output it
+for each processed source file (translation unit).
+
+To enable profiling info collection, use the ``-enable-check-profile`` argument.
+The timings will be output to ``stderr`` as a table. Example output:
+
+.. code-block:: console
+
+  $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp
+  ===-------------------------------------------------------------------------===
+                            clang-tidy checks profiling
+  ===-------------------------------------------------------------------------===
+    Total Execution Time: 1.0282 seconds (1.0258 wall clock)
+
+     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
+     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  readability-function-size
+     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  Total
+
+It can also store that data as JSON files for further processing. Example output:
+
+.. code-block:: console
+
+  $ clang-tidy -enable-check-profile -store-check-profile=.  -checks=-*,readability-function-size source.cpp
+  $ # Note that there won't be timings table printed to the console.
+  $ ls /tmp/out/
+  20180516161318717446360-source.cpp.json
+  $ cat 20180516161318717446360-source.cpp.json
+  {
+  "file": "/path/to/source.cpp",
+  "timestamp": "2018-05-16 16:13:18.717446360",
+  "profile": {
+    "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
+    "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
+    "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
+  }
+  }
+
+There is only one argument that controls profile storage:
+
+* ``-store-check-profile=<prefix>``
+
+  By default reports are printed in tabulated format to stderr. When this option
+  is passed, these per-TU profiles are instead stored as JSON.
+  If the prefix is not an absolute path, it is considered to be relative to the
+  directory from where you have run :program:`clang-tidy`. All ``.`` and ``..``
+  patterns in the path are collapsed, and symlinks are resolved.
+
+  Example:
+  Let's suppose you have a source file named ``example.cpp``, located in the
+  ``/source`` directory. Only the input filename is used, not the full path
+  to the source file. Additionally, it is prefixed with the current timestamp.
+
+  * If you specify ``-store-check-profile=/tmp``, then the profile will be saved
+    to ``/tmp/<ISO8601-like timestamp>-example.cpp.json``
+
+  * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify
+    ``-store-check-profile=.``, then the profile will still be saved to
+    ``/foo/<ISO8601-like timestamp>-example.cpp.json``
diff --git a/docs/clang-tidy/Integrations.rst b/docs/clang-tidy/Integrations.rst
new file mode 100644
index 0000000..ba08bf7
--- /dev/null
+++ b/docs/clang-tidy/Integrations.rst
@@ -0,0 +1,117 @@
+==================================
+Clang-tidy IDE/Editor Integrations
+==================================
+
+.. _Clangd: https://clang.llvm.org/extra/clangd.html
+
+Apart from being a standalone tool, :program:`clang-tidy` is integrated into
+various IDEs, code analyzers, and editors. Besides, it is currently being
+integrated into Clangd_. The following table shows the most
+well-known :program:`clang-tidy` integrations in detail.
+
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|                                      |        Feature                                                                                                                                           |
++======================================+========================+=================================+==========================+=========================================+==========================+
+|  **Tool**                            | On-the-fly inspection  | Check list configuration (GUI)  | Options to checks (GUI)  | Configuration via ``.clang-tidy`` files | Custom clang-tidy binary |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|A.L.E. for Vim                        |         \+\            |               \-\               |           \-\            |                 \-\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Clang Power Tools for Visual Studio   |         \-\            |               \+\               |           \-\            |                 \+\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Clangd                                |         \+\            |               \-\               |           \-\            |                 \-\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|CLion IDE                             |         \+\            |               \+\               |           \+\            |                 \+\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|CodeChecker                           |         \-\            |               \-\               |           \-\            |                 \-\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|CPPCheck                              |         \-\            |               \-\               |           \-\            |                 \-\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|CPPDepend                             |         \-\            |               \-\               |           \-\            |                 \-\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Flycheck for Emacs                    |         \+\            |               \-\               |           \-\            |                 \+\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|KDevelop IDE                          |         \-\            |               \+\               |           \+\            |                 \+\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Qt Creator IDE                        |         \+\            |               \+\               |           \-\            |                 \-\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|ReSharper C++ for Visual Studio       |         \+\            |               \+\               |           \-\            |                 \+\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Syntastic for Vim                     |         \+\            |               \-\               |           \-\            |                 \-\                     |           \+\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+|Visual Assist for Visual Studio       |         \+\            |               \+\               |           \-\            |                 \-\                     |           \-\            |
++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+
+
+**IDEs**
+
+.. _CLion: https://www.jetbrains.com/clion/
+.. _integrates clang-tidy: https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html
+
+CLion_ 2017.2 and later `integrates clang-tidy`_ as an extension to the
+built-in code analyzer. Starting from 2018.2 EAP, CLion allows using
+:program:`clang-tidy` via Clangd. Inspections and applicable quick-fixes are
+performed on the fly, and checks can be configured in standard command line
+format. In this integration, you can switch to the :program:`clang-tidy`
+binary different from the bundled one, pass the configuration in
+``.clang-tidy`` files instead of using the IDE settings, and configure
+options for particular checks.
+
+.. _KDevelop: https://www.kdevelop.org/
+.. _kdev-clang-tidy: https://github.com/KDE/kdev-clang-tidy/
+
+KDevelop_ with the kdev-clang-tidy_ plugin, starting from version 5.1, performs
+static analysis using :program:`clang-tidy`. The plugin launches the
+:program:`clang-tidy` binary from the specified location and parses its
+output to provide a list of issues.
+
+.. _QtCreator: https://www.qt.io/
+.. _Clang Code Model: https://doc.qt.io/qtcreator/creator-clang-codemodel.html
+
+QtCreator_ 4.6 integrates :program:`clang-tidy` warnings into the editor
+diagnostics under the `Clang Code Model`_. To employ :program:`clang-tidy`
+inspection in QtCreator, you need to create a copy of one of the presets and
+choose the checks to be performed in the Clang Code Model Warnings menu.
+
+.. _MS Visual Studio: https://visualstudio.microsoft.com/
+.. _ReSharper C++: https://www.jetbrains.com/help/resharper/Clang_Tidy_Integration.html
+.. _Visual Assist: https://docs.wholetomato.com/default.asp?W761
+.. _Clang Power Tools: https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools
+.. _clang-tidy-vs: https://github.com/llvm/llvm-project/tree/master/clang-tools-extra/clang-tidy-vs
+
+`MS Visual Studio`_ has a native clang-tidy-vs_ plugin and also can integrate
+:program:`clang-tidy` by means of three other tools. The `ReSharper C++`_
+extension, version 2017.3 and later, provides seamless :program:`clang-tidy`
+integration: checks and quick-fixes run alongside native inspections. Apart
+from that, ReSharper C++ incorporates :program:`clang-tidy` as a separate
+step of its code clean-up process. `Visual Assist`_ build 2210 includes a
+subset of :program:`clang-tidy` checklist to inspect the code as you edit.
+Another way to bring :program:`clang-tidy` functionality to Visual Studio is
+the `Clang Power Tools`_ plugin, which includes most of the
+:program:`clang-tidy` checks and runs them during compilation or as a separate
+step of code analysis.
+
+**Editors**
+
+.. _Flycheck: https://github.com/ch1bo/flycheck-clang-tidy
+.. _Syntastic: https://github.com/vim-syntastic/syntastic
+.. _A.L.E.: https://github.com/w0rp/ale
+.. _Emacs24: https://www.gnu.org/s/emacs/
+.. _Vim: https://www.vim.org/
+
+Emacs24_, when expanded with the Flycheck_ plugin, incorporates the
+:program:`clang-tidy` inspection into the syntax analyzer. For Vim_, you can
+use Syntastic_, which includes :program:`clang-tidy`, or `A.L.E.`_,
+a lint engine that applies :program:`clang-tidy` along with other linters.
+
+**Analyzers**
+
+.. _CPPDepend: https://www.cppdepend.com/cppdependv2018
+.. _CPPCheck: https://sourceforge.net/p/cppcheck/news/
+.. _CodeChecker: https://github.com/Ericsson/codechecker
+.. _plugin: https://github.com/Ericsson/CodeCheckerEclipsePlugin
+
+:program:`clang-tidy` is integrated in CPPDepend_ starting from version 2018.1
+and CPPCheck_ 1.82. CPPCheck integration lets you import Visual Studio
+solutions and run the :program:`clang-tidy` inspection on them. The
+CodeChecker_ application of version 5.3 or later, which also comes as a plugin_
+for Eclipse, supports :program:`clang-tidy` as a static analysis instrument and
+allows to use a custom :program:`clang-tidy` binary.
diff --git a/docs/clang-tidy/checks/abseil-duration-addition.rst b/docs/clang-tidy/checks/abseil-duration-addition.rst
new file mode 100644
index 0000000..2f3d805
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-duration-addition.rst
@@ -0,0 +1,21 @@
+.. title:: clang-tidy - abseil-duration-addition
+
+abseil-duration-addition
+========================
+
+Check for cases where addition should be performed in the ``absl::Time`` domain.
+When adding two values, and one is known to be an ``absl::Time``, we can infer
+that the other should be interpreted as an ``absl::Duration`` of a similar
+scale, and make that inference explicit.
+
+Examples:
+
+.. code-block:: c++
+
+  // Original - Addition in the integer domain
+  int x;
+  absl::Time t;
+  int result = absl::ToUnixSeconds(t) + x;
+
+  // Suggestion - Addition in the absl::Time domain
+  int result = absl::TounixSeconds(t + absl::Seconds(x));
diff --git a/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst b/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst
new file mode 100644
index 0000000..3c1a152
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst
@@ -0,0 +1,31 @@
+.. title:: clang-tidy - abseil-duration-conversion-cast
+
+abseil-duration-conversion-cast
+===============================
+
+Checks for casts of ``absl::Duration`` conversion functions, and recommends
+the right conversion function instead.
+
+Examples:
+
+.. code-block:: c++
+
+  // Original - Cast from a double to an integer
+  absl::Duration d;
+  int i = static_cast<int>(absl::ToDoubleSeconds(d));
+
+  // Suggested - Use the integer conversion function directly.
+  int i = absl::ToInt64Seconds(d);
+
+
+  // Original - Cast from a double to an integer
+  absl::Duration d;
+  double x = static_cast<double>(absl::ToInt64Seconds(d));
+
+  // Suggested - Use the integer conversion function directly.
+  double x = absl::ToDoubleSeconds(d);
+
+
+Note: In the second example, the suggested fix could yield a different result,
+as the conversion to integer could truncate.  In practice, this is very rare,
+and you should use ``absl::Trunc`` to perform this operation explicitly instead.
diff --git a/docs/clang-tidy/checks/abseil-duration-subtraction.rst b/docs/clang-tidy/checks/abseil-duration-subtraction.rst
index 884eeb2..b570931 100644
--- a/docs/clang-tidy/checks/abseil-duration-subtraction.rst
+++ b/docs/clang-tidy/checks/abseil-duration-subtraction.rst
@@ -21,7 +21,6 @@
   // Suggestion - Subtraction in the absl::Duration domain instead
   double result = absl::ToDoubleSeconds(d - absl::Seconds(x));
 
-
   // Original - Subtraction of two Durations in the double domain
   absl::Duration d1, d2;
   double result = absl::ToDoubleSeconds(d1) - absl::ToDoubleSeconds(d2);
@@ -29,6 +28,7 @@
   // Suggestion - Subtraction in the absl::Duration domain instead
   double result = absl::ToDoubleSeconds(d1 - d2);
 
+
 Note: As with other ``clang-tidy`` checks, it is possible that multiple fixes
 may overlap (as in the case of nested expressions), so not all occurences can
 be transformed in one run. In particular, this may occur for nested subtraction
diff --git a/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst
new file mode 100644
index 0000000..2f978f4
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst
@@ -0,0 +1,46 @@
+.. title:: clang-tidy - abseil-duration-unnecessary-conversion
+
+abseil-duration-unnecessary-conversion
+======================================
+
+Finds and fixes cases where ``absl::Duration`` values are being converted to
+numeric types and back again.
+
+Floating-point examples:
+
+.. code-block:: c++
+
+  // Original - Conversion to double and back again
+  absl::Duration d1;
+  absl::Duration d2 = absl::Seconds(absl::ToDoubleSeconds(d1));
+
+  // Suggestion - Remove unnecessary conversions
+  absl::Duration d2 = d1;
+
+  // Original - Division to convert to double and back again
+  absl::Duration d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1)));
+
+  // Suggestion - Remove division and conversion
+  absl::Duration d2 = d1;
+
+Integer examples:
+
+.. code-block:: c++
+
+  // Original - Conversion to integer and back again
+  absl::Duration d1;
+  absl::Duration d2 = absl::Hours(absl::ToInt64Hours(d1));
+
+  // Suggestion - Remove unnecessary conversions
+  absl::Duration d2 = d1;
+
+  // Original - Integer division followed by conversion
+  absl::Duration d2 = absl::Seconds(d1 / absl::Seconds(1));
+
+  // Suggestion - Remove division and conversion
+  absl::Duration d2 = d1;
+
+Note: Converting to an integer and back to an ``absl::Duration`` might be a
+truncating operation if the value is not aligned to the scale of conversion.
+In the rare case where this is the intended result, callers should use
+``absl::Trunc`` to truncate explicitly.
diff --git a/docs/clang-tidy/checks/abseil-time-comparison.rst b/docs/clang-tidy/checks/abseil-time-comparison.rst
new file mode 100644
index 0000000..9342e4c
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-time-comparison.rst
@@ -0,0 +1,23 @@
+.. title:: clang-tidy - abseil-time-comparison
+
+abseil-time-comparison
+======================
+
+Prefer comparisons in the ``absl::Time`` domain instead of the integer domain.
+
+N.B.: In cases where an ``absl::Time`` is being converted to an integer,
+alignment may occur. If the comparison depends on this alignment, doing the
+comparison in the ``absl::Time`` domain may yield a different result. In
+practice this is very rare, and still indicates a bug which should be fixed.
+
+Examples:
+
+.. code-block:: c++
+
+  // Original - Comparison in the integer domain
+  int x;
+  absl::Time t;
+  if (x < absl::ToUnixSeconds(t)) ...
+
+  // Suggested - Compare in the absl::Time domain instead
+  if (absl::FromUnixSeconds(x) < t) ...
diff --git a/docs/clang-tidy/checks/abseil-time-subtraction.rst b/docs/clang-tidy/checks/abseil-time-subtraction.rst
new file mode 100644
index 0000000..196c073
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-time-subtraction.rst
@@ -0,0 +1,39 @@
+.. title:: clang-tidy - abseil-time-subtraction
+
+abseil-time-subtraction
+=======================
+
+Finds and fixes ``absl::Time`` subtraction expressions to do subtraction
+in the Time domain instead of the numeric domain.
+
+There are two cases of Time subtraction in which deduce additional type
+information:
+
+- When the result is an ``absl::Duration`` and the first argument is an
+  ``absl::Time``.
+- When the second argument is a ``absl::Time``.
+
+In the first case, we must know the result of the operation, since without that
+the second operand could be either an ``absl::Time`` or an ``absl::Duration``.
+In the second case, the first operand *must* be an ``absl::Time``, because
+subtracting an ``absl::Time`` from an ``absl::Duration`` is not defined.
+
+Examples:
+
+.. code-block:: c++
+
+  int x;
+  absl::Time t;
+
+  // Original - absl::Duration result and first operand is a absl::Time.
+  absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x);
+
+  // Suggestion - Perform subtraction in the Time domain instead.
+  absl::Duration d = t - absl::FromUnixSeconds(x);
+
+
+  // Original - Second operand is an absl::Time.
+  int i = x - absl::ToUnixSeconds(t);
+
+  // Suggestion - Perform subtraction in the Time domain instead.
+  int i = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t);
diff --git a/docs/clang-tidy/checks/bugprone-argument-comment.rst b/docs/clang-tidy/checks/bugprone-argument-comment.rst
index 5f7e5f0..afc1218 100644
--- a/docs/clang-tidy/checks/bugprone-argument-comment.rst
+++ b/docs/clang-tidy/checks/bugprone-argument-comment.rst
@@ -27,3 +27,158 @@
    When zero (default value), the check will ignore leading and trailing
    underscores and case when comparing names -- otherwise they are taken into
    account.
+
+.. option:: CommentBoolLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the boolean literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(bool TurnKey, bool PressButton);
+
+  foo(true, false);
+
+After:
+
+.. code-block:: c++
+
+  void foo(bool TurnKey, bool PressButton);
+
+  foo(/*TurnKey=*/true, /*PressButton=*/false);
+
+.. option:: CommentIntegerLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the integer literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(int MeaningOfLife);
+
+  foo(42);
+
+After:
+
+.. code-block:: c++
+
+  void foo(int MeaningOfLife);
+
+  foo(/*MeaningOfLife=*/42);
+
+.. option:: CommentFloatLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the float/double literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(float Pi);
+
+  foo(3.14159);
+
+After:
+
+.. code-block:: c++
+
+  void foo(float Pi);
+
+  foo(/*Pi=*/3.14159);
+
+.. option:: CommentStringLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the string literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(const char *String);
+  void foo(const wchar_t *WideString);
+
+  foo("Hello World");
+  foo(L"Hello World");
+
+After:
+
+.. code-block:: c++
+
+  void foo(const char *String);
+  void foo(const wchar_t *WideString);
+
+  foo(/*String=*/"Hello World");
+  foo(/*WideString=*/L"Hello World");
+
+.. option:: CommentCharacterLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the character literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(char *Character);
+
+  foo('A');
+
+After:
+
+.. code-block:: c++
+
+  void foo(char *Character);
+
+  foo(/*Character=*/'A');
+
+.. option:: CommentUserDefinedLiterals
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the user defined literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(double Distance);
+
+  double operator"" _km(long double);
+
+  foo(402.0_km);
+
+After:
+
+.. code-block:: c++
+
+  void foo(double Distance);
+
+  double operator"" _km(long double);
+
+  foo(/*Distance=*/402.0_km);
+
+.. option:: CommentNullPtrs
+
+   When true, the check will add argument comments in the format
+   ``/*ParameterName=*/`` right before the nullptr literal argument.
+
+Before:
+
+.. code-block:: c++
+
+  void foo(A* Value);
+
+  foo(nullptr);
+
+After:
+
+.. code-block:: c++
+
+  void foo(A* Value);
+
+  foo(/*Value=*/nullptr);
diff --git a/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst b/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
old mode 100755
new mode 100644
index e1021b1..c352127
--- a/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
+++ b/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst
@@ -8,15 +8,15 @@
 
 .. code-block:: c++
 
-  class A {
+  struct A {
     int virtual foo() {...}
   };
 
-  class B: public A {
+  struct B: public A {
     int foo() override {...}
   };
 
-  class C: public B {
+  struct C: public B {
     int foo() override { A::foo(); }
   //                     ^^^^^^^^
   // warning: qualified name A::foo refers to a member overridden in subclass; did you mean 'B'?  [bugprone-parent-virtual-call]
diff --git a/docs/clang-tidy/checks/bugprone-too-small-loop-variable.rst b/docs/clang-tidy/checks/bugprone-too-small-loop-variable.rst
index 7688a3a..702541d 100644
--- a/docs/clang-tidy/checks/bugprone-too-small-loop-variable.rst
+++ b/docs/clang-tidy/checks/bugprone-too-small-loop-variable.rst
@@ -27,3 +27,20 @@
 
 This algorithm works for small amount of objects, but will lead to freeze for a
 a larger user input.
+
+.. option:: MagnitudeBitsUpperLimit
+
+  Upper limit for the magnitude bits of the loop variable. If it's set the check
+  filters out those catches in which the loop variable's type has more magnitude
+  bits as the specified upper limit. The default value is 16.
+  For example, if the user sets this option to 31 (bits), then a 32-bit ``unsigend int``
+  is ignored by the check, however a 32-bit ``int`` is not (A 32-bit ``signed int``
+  has 31 magnitude bits).
+
+.. code-block:: c++
+
+  int main() {
+    long size = 294967296l;
+    for (unsigned i = 0; i < size; ++i) {} // no warning with MagnitudeBitsUpperLimit = 31 on a system where unsigned is 32-bit
+    for (int i = 0; i < size; ++i) {} // warning with MagnitudeBitsUpperLimit = 31 on a system where int is 32-bit
+  }
diff --git a/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst
new file mode 100644
index 0000000..87a8fe2
--- /dev/null
+++ b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst
@@ -0,0 +1,10 @@
+.. title:: clang-tidy - cppcoreguidelines-explicit-virtual-functions
+.. meta::
+   :http-equiv=refresh: 5;URL=modernize-use-override.html
+
+cppcoreguidelines-explicit-virtual-functions
+============================================
+
+The cppcoreguidelines-explicit-virtual-functions check is an alias, please see
+`modernize-use-override <modernize-use-override.html>`_
+for more information.
diff --git a/docs/clang-tidy/checks/cppcoreguidelines-owning-memory.rst b/docs/clang-tidy/checks/cppcoreguidelines-owning-memory.rst
index 3f6f8c4..cd19016 100644
--- a/docs/clang-tidy/checks/cppcoreguidelines-owning-memory.rst
+++ b/docs/clang-tidy/checks/cppcoreguidelines-owning-memory.rst
@@ -50,7 +50,7 @@
   int* NonOwner = new int(42); // First warning here, since new must land in an owner
   delete NonOwner; // Second warning here, since only owners are allowed to be deleted
 
-  // Example Good, Ownership correclty stated
+  // Example Good, Ownership correctly stated
   gsl::owner<int*> Owner = new int(42); // Good
   delete Owner; // Good as well, statically enforced, that only owners get deleted
   
diff --git a/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst b/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
index 39b0217..884e971 100644
--- a/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
+++ b/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst
@@ -36,4 +36,4 @@
   }
 
 The corresponding style guide rule:
-http://google.github.io/styleguide/objcguide.html#avoid-throwing-exceptions
+https://google.github.io/styleguide/objcguide.html#avoid-throwing-exceptions
diff --git a/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst b/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
index d470370..e4b41fb 100644
--- a/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
+++ b/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst
@@ -7,7 +7,7 @@
 pattern of variable names in Google's Objective-C Style Guide.
 
 The corresponding style guide rule:
-http://google.github.io/styleguide/objcguide.html#variable-names
+https://google.github.io/styleguide/objcguide.html#variable-names
 
 All the global variables should follow the pattern of `g[A-Z].*` (variables) or
 `k[A-Z].*` (constants). The check will suggest a variable name that follows the
diff --git a/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst b/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst
new file mode 100644
index 0000000..75b1a9a
--- /dev/null
+++ b/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - google-readability-avoid-underscore-in-googletest-name
+
+google-readability-avoid-underscore-in-googletest-name
+======================================================
+
+Checks whether there are underscores in googletest test and test case names in
+test macros:
+
+- ``TEST``
+- ``TEST_F``
+- ``TEST_P``
+- ``TYPED_TEST``
+- ``TYPED_TEST_P``
+
+The ``FRIEND_TEST`` macro is not included.
+
+For example:
+
+.. code-block:: c++
+
+  TEST(TestCaseName, Illegal_TestName) {}
+  TEST(Illegal_TestCaseName, TestName) {}
+
+would trigger the check. `Underscores are not allowed`_ in test names nor test
+case names.
+
+The ``DISABLED_`` prefix, which may be used to `disable individual tests`_, is
+ignored when checking test names, but the rest of the rest of the test name is
+still checked.
+
+This check does not propose any fixes.
+
+.. _Underscores are not allowed: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
+.. _disable individual tests: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst
index 080e747..fc28cf6 100644
--- a/docs/clang-tidy/checks/list.rst
+++ b/docs/clang-tidy/checks/list.rst
@@ -4,17 +4,22 @@
 =================
 
 .. toctree::
+   abseil-duration-addition
    abseil-duration-comparison
+   abseil-duration-conversion-cast
    abseil-duration-division
    abseil-duration-factory-float
    abseil-duration-factory-scale
    abseil-duration-subtraction
+   abseil-duration-unnecessary-conversion
    abseil-faster-strsplit-delimiter
    abseil-no-internal-dependencies
    abseil-no-namespace
    abseil-redundant-strcat-calls
    abseil-str-cat-append
    abseil-string-find-startswith
+   abseil-time-comparison
+   abseil-time-subtraction
    abseil-upgrade-duration-conversions
    android-cloexec-accept
    android-cloexec-accept4
@@ -95,6 +100,7 @@
    cppcoreguidelines-avoid-goto
    cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) <cppcoreguidelines-avoid-magic-numbers>
    cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) <cppcoreguidelines-c-copy-assignment-signature>
+   cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) <cppcoreguidelines-explicit-virtual-functions>
    cppcoreguidelines-interfaces-global-init
    cppcoreguidelines-macro-usage
    cppcoreguidelines-narrowing-conversions
@@ -130,6 +136,7 @@
    google-objc-avoid-throwing-exception
    google-objc-function-naming
    google-objc-global-variable-declaration
+   google-readability-avoid-underscore-in-googletest-name
    google-readability-braces-around-statements (redirects to readability-braces-around-statements) <google-readability-braces-around-statements>
    google-readability-casting
    google-readability-function-size (redirects to readability-function-size) <google-readability-function-size>
@@ -171,6 +178,7 @@
    llvm-header-guard
    llvm-include-order
    llvm-namespace-comment
+   llvm-prefer-isa-or-dyn-cast-in-conditionals
    llvm-twine-local
    misc-definitions-in-headers
    misc-misplaced-const
@@ -220,6 +228,9 @@
    objc-avoid-spinlock
    objc-forbidden-subclassing
    objc-property-declaration
+   objc-super-self
+   openmp-exception-escape
+   openmp-use-default-none
    performance-faster-string-find
    performance-for-range-copy
    performance-implicit-conversion-in-loop
diff --git a/docs/clang-tidy/checks/llvm-include-order.rst b/docs/clang-tidy/checks/llvm-include-order.rst
index dba9837..8a215b8 100644
--- a/docs/clang-tidy/checks/llvm-include-order.rst
+++ b/docs/clang-tidy/checks/llvm-include-order.rst
@@ -6,4 +6,4 @@
 
 Checks the correct order of ``#includes``.
 
-See http://llvm.org/docs/CodingStandards.html#include-style
+See https://llvm.org/docs/CodingStandards.html#include-style
diff --git a/docs/clang-tidy/checks/llvm-namespace-comment.rst b/docs/clang-tidy/checks/llvm-namespace-comment.rst
index f6bc598..be90260 100644
--- a/docs/clang-tidy/checks/llvm-namespace-comment.rst
+++ b/docs/clang-tidy/checks/llvm-namespace-comment.rst
@@ -8,7 +8,7 @@
 
 Checks that long namespaces have a closing comment.
 
-http://llvm.org/docs/CodingStandards.html#namespace-indentation
+https://llvm.org/docs/CodingStandards.html#namespace-indentation
 
 https://google.github.io/styleguide/cppguide.html#Namespaces
 
diff --git a/docs/clang-tidy/checks/llvm-prefer-isa-or-dyn-cast-in-conditionals.rst b/docs/clang-tidy/checks/llvm-prefer-isa-or-dyn-cast-in-conditionals.rst
new file mode 100644
index 0000000..70ff0f2
--- /dev/null
+++ b/docs/clang-tidy/checks/llvm-prefer-isa-or-dyn-cast-in-conditionals.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - llvm-prefer-isa-or-dyn-cast-in-conditionals
+
+llvm-prefer-isa-or-dyn-cast-in-conditionals
+===========================================
+
+Looks at conditionals and finds and replaces cases of ``cast<>``,
+which will assert rather than return a null pointer, and
+``dyn_cast<>`` where the return value is not captured. Additionally,
+finds and replaces cases that match the pattern ``var &&
+isa<X>(var)``, where ``var`` is evaluated twice.
+
+.. code-block:: c++
+
+  // Finds these:
+  if (auto x = cast<X>(y)) {}
+  // is replaced by:
+  if (auto x = dyn_cast<X>(y)) {}
+
+  if (cast<X>(y)) {}
+  // is replaced by:
+  if (isa<X>(y)) {}
+
+  if (dyn_cast<X>(y)) {}
+  // is replaced by:
+  if (isa<X>(y)) {}
+
+  if (var && isa<T>(var)) {}
+  // is replaced by:
+  if (isa_and_nonnull<T>(var.foo())) {}
+
+  // Other cases are ignored, e.g.:
+  if (auto f = cast<Z>(y)->foo()) {}
+  if (cast<Z>(y)->foo()) {}
+  if (X.cast(y)) {}
diff --git a/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst b/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
index db88c9b..5799062 100644
--- a/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
+++ b/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
@@ -6,11 +6,11 @@
 `cppcoreguidelines-non-private-member-variables-in-classes` redirects here
 as an alias for this check.
 
-Finds classes that contain non-static data members in addition to non-static
-member functions and diagnose all data members declared with a non-``public``
-access specifier. The data members should be declared as ``private`` and
-accessed through member functions instead of exposed to derived classes or
-class consumers.
+Finds classes that contain non-static data members in addition to user-declared
+non-static member functions and diagnose all data members declared with a
+non-``public`` access specifier. The data members should be declared as
+``private`` and accessed through member functions instead of exposed to derived
+classes or class consumers.
 
 Options
 -------
diff --git a/docs/clang-tidy/checks/misc-throw-by-value-catch-by-reference.rst b/docs/clang-tidy/checks/misc-throw-by-value-catch-by-reference.rst
index 1a6d6b3..91287d8 100644
--- a/docs/clang-tidy/checks/misc-throw-by-value-catch-by-reference.rst
+++ b/docs/clang-tidy/checks/misc-throw-by-value-catch-by-reference.rst
@@ -3,8 +3,8 @@
 misc-throw-by-value-catch-by-reference
 ======================================
 
-"cert-err09-cpp" redirects here as an alias for this check.
-"cert-err61-cpp" redirects here as an alias for this check.
+`cert-err09-cpp` redirects here as an alias for this check.
+`cert-err61-cpp` redirects here as an alias for this check.
 
 Finds violations of the rule "Throw by value, catch by reference" presented for
 example in "C++ Coding Standards" by H. Sutter and A. Alexandrescu.
diff --git a/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst b/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
index 8f856a5..d7bc747 100644
--- a/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
+++ b/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst
@@ -54,3 +54,7 @@
   }
 
   }
+
+Similarly, the ``main()`` function is ignored. Its second and third parameters
+can be either ``char* argv[]`` or ``char** argv``, but can not be
+``std::array<>``.
diff --git a/docs/clang-tidy/checks/modernize-pass-by-value.rst b/docs/clang-tidy/checks/modernize-pass-by-value.rst
index f49648d..e538135 100644
--- a/docs/clang-tidy/checks/modernize-pass-by-value.rst
+++ b/docs/clang-tidy/checks/modernize-pass-by-value.rst
@@ -144,7 +144,7 @@
  +  C(std::string S) : S(std::move(S)) {}
    };
 
-.. _Clang Compiler User’s Manual - Microsoft extensions: http://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
+.. _Clang Compiler User’s Manual - Microsoft extensions: https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
 
 .. seealso::
 
diff --git a/docs/clang-tidy/checks/modernize-use-emplace.rst b/docs/clang-tidy/checks/modernize-use-emplace.rst
index 533125e..447a110 100644
--- a/docs/clang-tidy/checks/modernize-use-emplace.rst
+++ b/docs/clang-tidy/checks/modernize-use-emplace.rst
@@ -10,7 +10,7 @@
 Right now the check doesn't support ``push_front`` and ``insert``.
 It also doesn't support ``insert`` functions for associative containers
 because replacing ``insert`` with ``emplace`` may result in
-`speed regression <http://htmlpreview.github.io/?https://github.com/HowardHinnant/papers/blob/master/insert_vs_emplace.html>`_, but it might get support with some addition flag in the future.
+`speed regression <https://htmlpreview.github.io/?https://github.com/HowardHinnant/papers/blob/master/insert_vs_emplace.html>`_, but it might get support with some addition flag in the future.
 
 By default only ``std::vector``, ``std::deque``, ``std::list`` are considered.
 This list can be modified using the :option:`ContainersWithPushBack` option.
diff --git a/docs/clang-tidy/checks/modernize-use-override.rst b/docs/clang-tidy/checks/modernize-use-override.rst
index f2c778a..4273c6e 100644
--- a/docs/clang-tidy/checks/modernize-use-override.rst
+++ b/docs/clang-tidy/checks/modernize-use-override.rst
@@ -3,5 +3,42 @@
 modernize-use-override
 ======================
 
+Adds ``override`` (introduced in C++11) to overridden virtual functions and
+removes ``virtual`` from those functions as it is not required.
 
-Use C++11's ``override`` and remove ``virtual`` where applicable.
+``virtual`` on non base class implementations was used to help indiciate to the
+user that a function was virtual. C++ compilers did not use the presence of
+this to signify an overriden function.
+
+In C++ 11 ``override`` and ``final`` keywords were introduced to allow
+overridden functions to be marked appropriately. Their presence allows
+compilers to verify that an overridden function correctly overrides a base
+class implementation.
+
+This can be useful as compilers can generate a compile time error when:
+
+ - The base class implementation function signature changes.
+ - The user has not created the override with the correct signature.
+
+Options
+-------
+
+.. option:: IgnoreDestructors
+
+   If set to non-zero, this check will not diagnose destructors. Default is `0`.
+
+.. option:: OverrideSpelling
+
+   Specifies a macro to use instead of ``override``. This is useful when
+   maintaining source code that also needs to compile with a pre-C++11
+   compiler.
+
+.. option:: FinalSpelling
+
+   Specifies a macro to use instead of ``final``. This is useful when
+   maintaining source code that also needs to compile with a pre-C++11
+   compiler.
+
+.. note::
+
+   For more information on the use of ``override`` see https://en.cppreference.com/w/cpp/language/override
diff --git a/docs/clang-tidy/checks/objc-property-declaration.rst b/docs/clang-tidy/checks/objc-property-declaration.rst
index 49df510..60b9c82 100644
--- a/docs/clang-tidy/checks/objc-property-declaration.rst
+++ b/docs/clang-tidy/checks/objc-property-declaration.rst
@@ -40,15 +40,3 @@
    @property(nonatomic, assign) int abc_lowerCamelCase;
 
 The corresponding style rule: https://developer.apple.com/library/content/qa/qa1908/_index.html
-
-
-Options
--------
-
-.. option:: Acronyms
-
-   This option is deprecated and ignored.
-
-.. option:: IncludeDefaultAcronyms
-
-   This option is deprecated and ignored.
diff --git a/docs/clang-tidy/checks/objc-super-self.rst b/docs/clang-tidy/checks/objc-super-self.rst
new file mode 100644
index 0000000..ed0bb29
--- /dev/null
+++ b/docs/clang-tidy/checks/objc-super-self.rst
@@ -0,0 +1,13 @@
+.. title:: clang-tidy - objc-super-self
+
+objc-super-self
+===============
+
+Finds invocations of ``-self`` on super instances in initializers of subclasses
+of ``NSObject`` and recommends calling a superclass initializer instead.
+
+Invoking ``-self`` on super instances in initializers is a common programmer
+error when the programmer's original intent is to call a superclass
+initializer. Failing to call a superclass initializer breaks initializer
+chaining and can result in invalid object initialization.
+
diff --git a/docs/clang-tidy/checks/openmp-exception-escape.rst b/docs/clang-tidy/checks/openmp-exception-escape.rst
new file mode 100644
index 0000000..d85e4fd
--- /dev/null
+++ b/docs/clang-tidy/checks/openmp-exception-escape.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - openmp-exception-escape
+
+openmp-exception-escape
+=======================
+
+Analyzes OpenMP Structured Blocks and checks that no exception escapes
+out of the Structured Block it was thrown in.
+
+As per the OpenMP specification, a structured block is an executable statement,
+possibly compound, with a single entry at the top and a single exit at the
+bottom. Which means, ``throw`` may not be used to to 'exit' out of the
+structured block. If an exception is not caught in the same structured block
+it was thrown in, the behaviour is undefined.
+
+FIXME: this check does not model SEH, ``setjmp``/``longjmp``.
+
+WARNING! This check may be expensive on large source files.
+
+Options
+-------
+
+.. option:: IgnoredExceptions
+
+   Comma-separated list containing type names which are not counted as thrown
+   exceptions in the check. Default value is an empty string.
diff --git a/docs/clang-tidy/checks/openmp-use-default-none.rst b/docs/clang-tidy/checks/openmp-use-default-none.rst
new file mode 100644
index 0000000..4223a10
--- /dev/null
+++ b/docs/clang-tidy/checks/openmp-use-default-none.rst
@@ -0,0 +1,53 @@
+.. title:: clang-tidy - openmp-use-default-none
+
+openmp-use-default-none
+=======================
+
+Finds OpenMP directives that are allowed to contain a ``default`` clause,
+but either don't specify it or the clause is specified but with the kind
+other than ``none``, and suggests to use the ``default(none)`` clause.
+
+Using ``default(none)`` clause forces developers to explicitly specify data
+sharing attributes for the variables referenced in the construct,
+thus making it obvious which variables are referenced, and what is their
+data sharing attribute, thus increasing readability and possibly making errors
+easier to spot.
+
+Example
+-------
+
+.. code-block:: c++
+
+  // ``for`` directive can not have ``default`` clause, no diagnostics.
+  void n0(const int a) {
+  #pragma omp for
+    for (int b = 0; b < a; b++)
+      ;
+  }
+
+  // ``parallel`` directive.
+
+  // ``parallel`` directive can have ``default`` clause, but said clause is not
+  // specified, diagnosed.
+  void p0_0() {
+  #pragma omp parallel
+    ;
+    // WARNING: OpenMP directive ``parallel`` does not specify ``default``
+    //          clause. Consider specifying ``default(none)`` clause.
+  }
+
+  // ``parallel`` directive can have ``default`` clause, and said clause is
+  // specified, with ``none`` kind, all good.
+  void p0_1() {
+  #pragma omp parallel default(none)
+    ;
+  }
+
+  // ``parallel`` directive can have ``default`` clause, and said clause is
+  // specified, but with ``shared`` kind, which is not ``none``, diagnose.
+  void p0_2() {
+  #pragma omp parallel default(shared)
+    ;
+    // WARNING: OpenMP directive ``parallel`` specifies ``default(shared)``
+    //          clause. Consider using ``default(none)`` clause instead.
+  }
diff --git a/docs/clang-tidy/checks/portability-simd-intrinsics.rst b/docs/clang-tidy/checks/portability-simd-intrinsics.rst
index 2cd9d9f..fedd47a 100644
--- a/docs/clang-tidy/checks/portability-simd-intrinsics.rst
+++ b/docs/clang-tidy/checks/portability-simd-intrinsics.rst
@@ -46,4 +46,4 @@
    The namespace used to suggest `P0214`_ alternatives. If not specified, `std::`
    for `-std=c++2a` and `std::experimental::` for `-std=c++11`.
 
-.. _P0214: http://wg21.link/p0214
+.. _P0214: https://wg21.link/p0214
diff --git a/docs/clang-tidy/checks/readability-else-after-return.rst b/docs/clang-tidy/checks/readability-else-after-return.rst
index 949b5bb..c178a6a 100644
--- a/docs/clang-tidy/checks/readability-else-after-return.rst
+++ b/docs/clang-tidy/checks/readability-else-after-return.rst
@@ -3,7 +3,7 @@
 readability-else-after-return
 =============================
 
-`LLVM Coding Standards <http://llvm.org/docs/CodingStandards.html>`_ advises to
+`LLVM Coding Standards <https://llvm.org/docs/CodingStandards.html>`_ advises to
 reduce indentation where possible and where it makes understanding code easier.
 Early exit is one of the suggested enforcements of that. Please do not use
 ``else`` or ``else if`` after something that interrupts control flow - like
@@ -61,4 +61,4 @@
 
 
 This check helps to enforce this `LLVM Coding Standards recommendation
-<http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return>`_.
+<https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return>`_.
diff --git a/docs/clang-tidy/checks/readability-magic-numbers.rst b/docs/clang-tidy/checks/readability-magic-numbers.rst
index 946672e..9968809 100644
--- a/docs/clang-tidy/checks/readability-magic-numbers.rst
+++ b/docs/clang-tidy/checks/readability-magic-numbers.rst
@@ -9,7 +9,7 @@
 Many coding guidelines advise replacing the magic values with symbolic
 constants to improve readability. Here are a few references:
 
-   * `Rule ES.45: Avoid “magic constants”; use symbolic constants in C++ Core Guidelines <http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-magic>`_
+   * `Rule ES.45: Avoid “magic constants”; use symbolic constants in C++ Core Guidelines <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-magic>`_
    * `Rule 5.1.1 Use symbolic names instead of literal values in code in High Integrity C++ <http://www.codingstandard.com/rule/5-1-1-use-symbolic-names-instead-of-literal-values-in-code/>`_
    * Item 17 in "C++ Coding Standards: 101 Rules, Guidelines and Best
      Practices" by Herb Sutter and Andrei Alexandrescu
diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst
index 20b18b4..1b5af60 100644
--- a/docs/clang-tidy/index.rst
+++ b/docs/clang-tidy/index.rst
@@ -10,6 +10,8 @@
    :maxdepth: 1
 
    The list of clang-tidy checks <checks/list>
+   Clang-tidy IDE/Editor Integrations <Integrations>
+   Getting Involved <Contributing>
 
 :program:`clang-tidy` is a clang-based C++ "linter" tool. Its purpose is to
 provide an extensible framework for diagnosing and fixing typical programming
@@ -71,6 +73,7 @@
                        means "C++11") language constructs.
 ``mpi-``               Checks related to MPI (Message Passing Interface).
 ``objc-``              Checks related to Objective-C coding conventions.
+``openmp-``            Checks related to OpenMP API.
 ``performance-``       Checks that target performance-related issues.
 ``portability-``       Checks that target portability-related issues that don't
                        relate to any particular coding style.
@@ -223,7 +226,7 @@
           CMake option to get this output). When no build path is specified,
           a search for compile_commands.json will be attempted through all
           parent paths of the first input file . See:
-          http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
+          https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
           example of setting up Clang Tooling on a source tree.
 
   <source0> ... specify the paths of source files. These paths are
@@ -258,30 +261,51 @@
 Suppressing Undesired Diagnostics
 =================================
 
-:program:`clang-tidy` diagnostics are intended to call out code that does
-not adhere to a coding standard, or is otherwise problematic in some way.
-However, if it is known that the code is correct, the check-specific ways
-to silence the diagnostics could be used, if they are available (e.g.
-bugprone-use-after-move can be silenced by re-initializing the variable after it
-has been moved out, bugprone-string-integer-assignment can be suppressed by
-explicitly casting the integer to char, readability-implicit-bool-conversion can
-also be suppressed by using explicit casts, etc.). If they are not available or
-if changing the semantics of the code is not desired, the ``NOLINT`` or
-``NOLINTNEXTLINE`` comments can be used instead. For example:
+:program:`clang-tidy` diagnostics are intended to call out code that does not
+adhere to a coding standard, or is otherwise problematic in some way.  However,
+if the code is known to be correct, it may be useful to silence the warning.
+Some clang-tidy checks provide a check-specific way to silence the diagnostics,
+e.g.  `bugprone-use-after-move <checks/bugprone-use-after-move.html>`_ can be
+silenced by re-initializing the variable after it has been moved out,
+`bugprone-string-integer-assignment
+<checks/bugprone-string-integer-assignment.html>`_ can be suppressed by
+explicitly casting the integer to ``char``,
+`readability-implicit-bool-conversion
+<checks/readability-implicit-bool-conversion.html>`_ can also be suppressed by
+using explicit casts, etc.
+
+If a specific suppression mechanism is not available for a certain warning, or
+its use is not desired for some reason, :program:`clang-tidy` has a generic
+mechanism to suppress diagnostics using ``NOLINT`` or ``NOLINTNEXTLINE``
+comments.
+
+The ``NOLINT`` comment instructs :program:`clang-tidy` to ignore warnings on the
+*same line* (it doesn't apply to a function, a block of code or any other
+language construct, it applies to the line of code it is on). If introducing the
+comment in the same line would change the formatting in undesired way, the
+``NOLINTNEXTLINE`` comment allows to suppress clang-tidy warnings on the *next
+line*.
+
+Both comments can be followed by an optional list of check names in parentheses
+(see below for the formal syntax).
+
+For example:
 
 .. code-block:: c++
 
-  class Foo
-  {
-    // Silent all the diagnostics for the line
+  class Foo {
+    // Suppress all the diagnostics for the line
     Foo(int param); // NOLINT
 
-    // Silent only the specified checks for the line
+    // Consider explaining the motivation to suppress the warning.
+    Foo(char param); // NOLINT: Allow implicit conversion from `char`, because <some valid reason>.
+
+    // Silence only the specified checks for the line
     Foo(double param); // NOLINT(google-explicit-constructor, google-runtime-int)
 
-    // Silent only the specified diagnostics for the next line
+    // Silence only the specified diagnostics for the next line
     // NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int)
-    Foo(bool param); 
+    Foo(bool param);
   };
 
 The formal syntax of ``NOLINT``/``NOLINTNEXTLINE`` is the following:
@@ -305,516 +329,8 @@
 
 Note that whitespaces between ``NOLINT``/``NOLINTNEXTLINE`` and the opening
 parenthesis are not allowed (in this case the comment will be treated just as
-``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside
-the parenthesis) whitespaces can be used and will be ignored.
+``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside the
+parenthesis) whitespaces can be used and will be ignored.
 
-.. _LibTooling: http://clang.llvm.org/docs/LibTooling.html
-.. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
-
-
-Getting Involved
-================
-
-:program:`clang-tidy` has several own checks and can run Clang static analyzer
-checks, but its power is in the ability to easily write custom checks.
-
-Checks are organized in modules, which can be linked into :program:`clang-tidy`
-with minimal or no code changes in :program:`clang-tidy`.
-
-Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_
-or on the AST level using `AST Matchers`_. When an error is found, checks can
-report them in a way similar to how Clang diagnostics work. A fix-it hint can be
-attached to a diagnostic message.
-
-The interface provided by :program:`clang-tidy` makes it easy to write useful
-and precise checks in just a few lines of code. If you have an idea for a good
-check, the rest of this document explains how to do this.
-
-There are a few tools particularly useful when developing clang-tidy checks:
-  * ``add_new_check.py`` is a script to automate the process of adding a new
-    check, it will create the check, update the CMake file and create a test;
-  * ``rename_check.py`` does what the script name suggests, renames an existing
-    check;
-  * :program:`clang-query` is invaluable for interactive prototyping of AST
-    matchers and exploration of the Clang AST;
-  * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``)
-    provides a convenient way to dump AST of a C++ program.
-
-If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``,
-:program:`clang-tidy` will not be built with support for the 
-``clang-analyzer-*`` checks or the ``mpi-*`` checks.
-
-
-.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html
-.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html
-.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html
-
-
-Choosing the Right Place for your Check
----------------------------------------
-
-If you have an idea of a check, you should decide whether it should be
-implemented as a:
-
-+ *Clang diagnostic*: if the check is generic enough, targets code patterns that
-  most probably are bugs (rather than style or readability issues), can be
-  implemented effectively and with extremely low false positive rate, it may
-  make a good Clang diagnostic.
-
-+ *Clang static analyzer check*: if the check requires some sort of control flow
-  analysis, it should probably be implemented as a static analyzer check.
-
-+ *clang-tidy check* is a good choice for linter-style checks, checks that are
-  related to a certain coding style, checks that address code readability, etc.
-
-
-Preparing your Workspace
-------------------------
-
-If you are new to LLVM development, you should read the `Getting Started with
-the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_
-documents to check out and build LLVM, Clang and Clang Extra Tools with CMake.
-
-Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and
-let's start!
-
-.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html
-.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html
-
-
-The Directory Structure
------------------------
-
-:program:`clang-tidy` source code resides in the
-``llvm/tools/clang/tools/extra`` directory and is structured as follows:
-
-::
-
-  clang-tidy/                       # Clang-tidy core.
-  |-- ClangTidy.h                   # Interfaces for users and checks.
-  |-- ClangTidyModule.h             # Interface for clang-tidy modules.
-  |-- ClangTidyModuleRegistry.h     # Interface for registering of modules.
-     ...
-  |-- google/                       # Google clang-tidy module.
-  |-+
-    |-- GoogleTidyModule.cpp
-    |-- GoogleTidyModule.h
-          ...
-  |-- llvm/                         # LLVM clang-tidy module.
-  |-+
-    |-- LLVMTidyModule.cpp
-    |-- LLVMTidyModule.h
-          ...
-  |-- objc/                         # Objective-C clang-tidy module.
-  |-+
-    |-- ObjCTidyModule.cpp
-    |-- ObjCTidyModule.h
-          ...
-  |-- tool/                         # Sources of the clang-tidy binary.
-          ...
-  test/clang-tidy/                  # Integration tests.
-      ...
-  unittests/clang-tidy/             # Unit tests.
-  |-- ClangTidyTest.h
-  |-- GoogleModuleTest.cpp
-  |-- LLVMModuleTest.cpp
-  |-- ObjCModuleTest.cpp
-      ...
-
-
-Writing a clang-tidy Check
---------------------------
-
-So you have an idea of a useful check for :program:`clang-tidy`.
-
-First, if you're not familiar with LLVM development, read through the `Getting
-Started with LLVM`_ document for instructions on setting up your workflow and
-the `LLVM Coding Standards`_ document to familiarize yourself with the coding
-style used in the project. For code reviews we mostly use `LLVM Phabricator`_.
-
-.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html
-.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html
-.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html
-
-Next, you need to decide which module the check belongs to. Modules
-are located in subdirectories of `clang-tidy/
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/>`_
-and contain checks targeting a certain aspect of code quality (performance,
-readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.)
-or a widely used API (e.g. MPI). Their names are same as user-facing check
-groups names described :ref:`above <checks-groups-table>`.
-
-After choosing the module and the name for the check, run the
-``clang-tidy/add_new_check.py`` script to create the skeleton of the check and
-plug it to :program:`clang-tidy`. It's the recommended way of adding new checks.
-
-If we want to create a `readability-awesome-function-names`, we would run:
-
-.. code-block:: console
-
-  $ clang-tidy/add_new_check.py readability awesome-function-names
-
-
-The ``add_new_check.py`` script will:
-  * create the class for your check inside the specified module's directory and
-    register it in the module and in the build system;
-  * create a lit test file in the ``test/clang-tidy/`` directory;
-  * create a documentation file and include it into the
-    ``docs/clang-tidy/checks/list.rst``.
-
-Let's see in more detail at the check class definition:
-
-.. code-block:: c++
-
-  ...
-
-  #include "../ClangTidy.h"
-
-  namespace clang {
-  namespace tidy {
-  namespace readability {
-
-  ...
-  class AwesomeFunctionNamesCheck : public ClangTidyCheck {
-  public:
-    AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context)
-        : ClangTidyCheck(Name, Context) {}
-    void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-    void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  };
-
-  } // namespace readability
-  } // namespace tidy
-  } // namespace clang
-
-  ...
-
-Constructor of the check receives the ``Name`` and ``Context`` parameters, and
-must forward them to the ``ClangTidyCheck`` constructor.
-
-In our case the check needs to operate on the AST level and it overrides the
-``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the
-preprocessor level, we'd need instead to override the ``registerPPCallbacks``
-method.
-
-In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_
-for more information) that will find the pattern in the AST that we want to
-inspect. The results of the matching are passed to the ``check`` method, which
-can further inspect them and report diagnostics.
-
-.. code-block:: c++
-
-  using namespace ast_matchers;
-
-  void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) {
-    Finder->addMatcher(functionDecl().bind("x"), this);
-  }
-
-  void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) {
-    const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");
-    if (MatchedDecl->getName().startswith("awesome_"))
-      return;
-    diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome")
-        << MatchedDecl
-        << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
-  }
-
-(If you want to see an example of a useful check, look at
-`clang-tidy/google/ExplicitConstructorCheck.h
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.h>`_
-and `clang-tidy/google/ExplicitConstructorCheck.cpp
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_).
-
-
-Registering your Check
-----------------------
-
-(The ``add_new_check.py`` takes care of registering the check in an existing
-module. If you want to create a new module or know the details, read on.)
-
-The check should be registered in the corresponding module with a distinct name:
-
-.. code-block:: c++
-
-  class MyModule : public ClangTidyModule {
-   public:
-    void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
-      CheckFactories.registerCheck<ExplicitConstructorCheck>(
-          "my-explicit-constructor");
-    }
-  };
-
-Now we need to register the module in the ``ClangTidyModuleRegistry`` using a
-statically initialized variable:
-
-.. code-block:: c++
-
-  static ClangTidyModuleRegistry::Add<MyModule> X("my-module",
-                                                  "Adds my lint checks.");
-
-
-When using LLVM build system, we need to use the following hack to ensure the
-module is linked into the :program:`clang-tidy` binary:
-
-Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable:
-
-.. code-block:: c++
-
-  // This anchor is used to force the linker to link in the generated object file
-  // and thus register the MyModule.
-  volatile int MyModuleAnchorSource = 0;
-
-And this to the main translation unit of the :program:`clang-tidy` binary (or
-the binary you link the ``clang-tidy`` library in)
-``clang-tidy/tool/ClangTidyMain.cpp``:
-
-.. code-block:: c++
-
-  // This anchor is used to force the linker to link the MyModule.
-  extern volatile int MyModuleAnchorSource;
-  static int MyModuleAnchorDestination = MyModuleAnchorSource;
-
-
-Configuring Checks
-------------------
-
-If a check needs configuration options, it can access check-specific options
-using the ``Options.get<Type>("SomeOption", DefaultValue)`` call in the check
-constructor. In this case the check should also override the
-``ClangTidyCheck::storeOptions`` method to make the options provided by the
-check discoverable. This method lets :program:`clang-tidy` know which options
-the check implements and what the current values are (e.g. for the
-``-dump-config`` command line option).
-
-.. code-block:: c++
-
-  class MyCheck : public ClangTidyCheck {
-    const unsigned SomeOption1;
-    const std::string SomeOption2;
-
-  public:
-    MyCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context),
-        SomeOption(Options.get("SomeOption1", -1U)),
-        SomeOption(Options.get("SomeOption2", "some default")) {}
-
-    void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
-      Options.store(Opts, "SomeOption1", SomeOption1);
-      Options.store(Opts, "SomeOption2", SomeOption2);
-    }
-    ...
-
-Assuming the check is registered with the name "my-check", the option can then
-be set in a ``.clang-tidy`` file in the following way:
-
-.. code-block:: yaml
-
-  CheckOptions:
-    - key: my-check.SomeOption1
-      value: 123
-    - key: my-check.SomeOption2
-      value: 'some other value'
-
-If you need to specify check options on a command line, you can use the inline
-YAML format:
-
-.. code-block:: console
-
-  $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ...
-
-
-Testing Checks
---------------
-
-To run tests for :program:`clang-tidy` use the command:
-
-.. code-block:: console
-
-  $ ninja check-clang-tools
-
-:program:`clang-tidy` checks can be tested using either unit tests or
-`lit`_ tests. Unit tests may be more convenient to test complex replacements
-with strict checks. `Lit`_ tests allow using partial text matching and regular
-expressions which makes them more suitable for writing compact tests for
-diagnostic messages.
-
-The ``check_clang_tidy.py`` script provides an easy way to test both
-diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test
-file, runs :program:`clang-tidy` and verifies messages and fixes with two
-separate `FileCheck`_ invocations: once with FileCheck's directive
-prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages,
-and once with the directive prefix set to ``CHECK-FIXES``, running
-against the fixed code (i.e., the code after generated fix-its are
-applied). In particular, ``CHECK-FIXES:`` can be used to check
-that code was not modified by fix-its, by checking that it is present
-unchanged in the fixed code. The full set of `FileCheck`_ directives
-is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though
-typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``)
-are sufficient for clang-tidy tests. Note that the `FileCheck`_
-documentation mostly assumes the default prefix (``CHECK``), and hence
-describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc.
-Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for
-clang-tidy tests.
-
-An additional check enabled by ``check_clang_tidy.py`` ensures that
-if `CHECK-MESSAGES:` is used in a file then every warning or error
-must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:``
-instead, if you want to **also** ensure that all the notes are checked.
-
-To use the ``check_clang_tidy.py`` script, put a .cpp file with the
-appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use
-``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against
-diagnostic messages and fixed code.
-
-It's advised to make the checks as specific as possible to avoid checks matching
-to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]``
-substitutions and distinct function and variable names in the test code.
-
-Here's an example of a test using the ``check_clang_tidy.py`` script (the full
-source code is at `test/clang-tidy/google-readability-casting.cpp`_):
-
-.. code-block:: c++
-
-  // RUN: %check_clang_tidy %s google-readability-casting %t
-
-  void f(int a) {
-    int b = (int)a;
-    // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting]
-    // CHECK-FIXES: int b = a;
-  }
-
-To check more than one scenario in the same test file use
-``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or
-``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``.
-With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*``
-directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``.
-
-Here's an example:
-
-.. code-block:: c++
-
-   // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A
-   // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B
-   // RUN: %check_clang_tidy %s misc-unused-using-decls %t
-   ...
-   // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}}
-   // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}}
-   // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}}
-   // CHECK-FIXES-USING-A-NOT: using a::A;$
-   // CHECK-FIXES-USING-B-NOT: using a::B;$
-   // CHECK-FIXES-NOT: using a::C;$
-
-
-There are many dark corners in the C++ language, and it may be difficult to make
-your check work perfectly in all cases, especially if it issues fix-it hints. The
-most frequent pitfalls are macros and templates:
-
-1. code written in a macro body/template definition may have a different meaning
-   depending on the macro expansion/template instantiation;
-2. multiple macro expansions/template instantiations may result in the same code
-   being inspected by the check multiple times (possibly, with different
-   meanings, see 1), and the same warning (or a slightly different one) may be
-   issued by the check multiple times; :program:`clang-tidy` will deduplicate
-   _identical_ warnings, but if the warnings are slightly different, all of them
-   will be shown to the user (and used for applying fixes, if any);
-3. making replacements to a macro body/template definition may be fine for some
-   macro expansions/template instantiations, but easily break some other
-   expansions/instantiations.
-
-.. _lit: http://llvm.org/docs/CommandGuide/lit.html
-.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html
-.. _test/clang-tidy/google-readability-casting.cpp: http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp
-
-
-Running clang-tidy on LLVM
---------------------------
-
-To test a check it's best to try it out on a larger code base. LLVM and Clang
-are the natural targets as you already have the source code around. The most
-convenient way to run :program:`clang-tidy` is with a compile command database;
-CMake can automatically generate one, for a description of how to enable it see
-`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place and
-a working version of :program:`clang-tidy` is in ``PATH`` the entire code base
-can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script executes
-:program:`clang-tidy` with the default set of checks on every translation unit
-in the compile command database and displays the resulting warnings and errors.
-The script provides multiple configuration flags.
-
-* The default set of checks can be overridden using the ``-checks`` argument,
-  taking the identical format as :program:`clang-tidy` does. For example
-  ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override``
-  check only.
-
-* To restrict the files examined you can provide one or more regex arguments
-  that the file names are matched against.
-  ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy
-  checks. It may also be necessary to restrict the header files warnings are
-  displayed from using the ``-header-filter`` flag. It has the same behavior
-  as the corresponding :program:`clang-tidy` flag.
-
-* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers
-  all changes in a temporary directory and applies them. Passing ``-format``
-  will run clang-format over changed lines.
-
-
-On checks profiling
--------------------
-
-:program:`clang-tidy` can collect per-check profiling info, and output it
-for each processed source file (translation unit).
-
-To enable profiling info collection, use the ``-enable-check-profile`` argument.
-The timings will be output to ``stderr`` as a table. Example output:
-
-.. code-block:: console
-
-  $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp
-  ===-------------------------------------------------------------------------===
-                            clang-tidy checks profiling
-  ===-------------------------------------------------------------------------===
-    Total Execution Time: 1.0282 seconds (1.0258 wall clock)
-
-     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
-     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  readability-function-size
-     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  Total
-
-It can also store that data as JSON files for further processing. Example output:
-
-.. code-block:: console
-
-  $ clang-tidy -enable-check-profile -store-check-profile=.  -checks=-*,readability-function-size source.cpp
-  $ # Note that there won't be timings table printed to the console.
-  $ ls /tmp/out/
-  20180516161318717446360-source.cpp.json
-  $ cat 20180516161318717446360-source.cpp.json
-  {
-  "file": "/path/to/source.cpp",
-  "timestamp": "2018-05-16 16:13:18.717446360",
-  "profile": {
-    "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
-    "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
-    "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
-  }
-  }
-
-There is only one argument that controls profile storage:
-
-* ``-store-check-profile=<prefix>``
-
-  By default reports are printed in tabulated format to stderr. When this option
-  is passed, these per-TU profiles are instead stored as JSON.
-  If the prefix is not an absolute path, it is considered to be relative to the
-  directory from where you have run :program:`clang-tidy`. All ``.`` and ``..``
-  patterns in the path are collapsed, and symlinks are resolved.
-
-  Example:
-  Let's suppose you have a source file named ``example.cpp``, located in the
-  ``/source`` directory. Only the input filename is used, not the full path
-  to the source file. Additionally, it is prefixed with the current timestamp.
-
-  * If you specify ``-store-check-profile=/tmp``, then the profile will be saved
-    to ``/tmp/<ISO8601-like timestamp>-example.cpp.json``
-
-  * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify
-    ``-store-check-profile=.``, then the profile will still be saved to
-    ``/foo/<ISO8601-like timestamp>-example.cpp.json``
+.. _LibTooling: https://clang.llvm.org/docs/LibTooling.html
+.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
diff --git a/docs/clangd.rst b/docs/clangd.rst
index 0b27638..7910fac 100644
--- a/docs/clangd.rst
+++ b/docs/clangd.rst
@@ -1,161 +1,6 @@
-============
-Clangd
-============
+:orphan:
 
-.. contents::
+.. meta::
+   :http-equiv=refresh: 0;URL='clangd/'
 
-.. toctree::
-   :maxdepth: 1
-
-:program:`Clangd` is an implementation of the `Language Server Protocol
-<https://github.com/Microsoft/language-server-protocol>`_ leveraging Clang.
-Clangd's goal is to provide language "smartness" features like code completion,
-find references, etc. for clients such as C/C++ Editors.
-
-Using Clangd
-==================
-
-:program:`Clangd` is not meant to be used by C/C++ developers directly but
-rather from a client implementing the protocol. A client would be typically
-implemented in an IDE or an editor.
-
-At the moment, `Visual Studio Code <https://code.visualstudio.com/>`_ is mainly
-used in order to test :program:`Clangd` but more clients are likely to make
-use of :program:`Clangd` in the future as it matures and becomes a production
-quality tool. If you are interested in trying :program:`Clangd` in combination
-with Visual Studio Code, you can start by `installing Clangd`_ or
-`building Clangd`_, then open Visual Studio Code in the clangd-vscode folder and
-launch the extension.
-
-Installing Clangd
-==================
-
-Packages are available for debian-based distributions, see the `LLVM packages
-page <http://apt.llvm.org/>`_. :program:`Clangd` is included in the
-`clang-tools` package.
-However, it is a good idea to check your distribution's packaging system first
-as it might already be available.
-
-Otherwise, you can install :program:`Clangd` by `building Clangd`_ first.
-
-Building Clangd
-==================
-
-You can follow the instructions for `building Clang
-<https://clang.llvm.org/get_started.html>`_ but "extra Clang tools" is **not**
-optional.
-
-Current Status
-==================
-
-Many features could be implemented in :program:`Clangd`.
-Here is a list of features that could be useful with the status of whether or
-not they are already implemented in :program:`Clangd` and specified in the
-Language Server Protocol. Note that for some of the features, it is not clear
-whether or not they should be part of the Language Server Protocol, so those
-features might be eventually developed outside :program:`Clangd` or as an
-extension to the protocol.
-
-+-------------------------------------+------------+----------+
-| C/C++ Editor feature                |  LSP       |  Clangd  |
-+=====================================+============+==========+
-| Formatting                          | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Completion                          | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Diagnostics                         | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Fix-its                             | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Go to Definition                    | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Signature Help                      | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Document Highlights                 | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Rename                              | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Source hover                        | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Find References                     | Yes        |   No     |
-+-------------------------------------+------------+----------+
-| Code Lens                           | Yes        |   No     |
-+-------------------------------------+------------+----------+
-| Document Symbols                    | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Workspace Symbols                   | Yes        |   Yes    |
-+-------------------------------------+------------+----------+
-| Syntax and Semantic Coloring        | No         |   No     |
-+-------------------------------------+------------+----------+
-| Code folding                        | No         |   No     |
-+-------------------------------------+------------+----------+
-| Call hierarchy                      | No         |   No     |
-+-------------------------------------+------------+----------+
-| Type hierarchy                      | No         |   No     |
-+-------------------------------------+------------+----------+
-| Organize Includes                   | No         |   No     |
-+-------------------------------------+------------+----------+
-| Quick Assist                        | No         |   No     |
-+-------------------------------------+------------+----------+
-| Extract Local Variable              | No         |   No     |
-+-------------------------------------+------------+----------+
-| Extract Function/Method             | No         |   No     |
-+-------------------------------------+------------+----------+
-| Hide Method                         | No         |   No     |
-+-------------------------------------+------------+----------+
-| Implement Method                    | No         |   No     |
-+-------------------------------------+------------+----------+
-| Gen. Getters/Setters                | No         |   No     |
-+-------------------------------------+------------+----------+
-
-Editor Integration
-==================
-
-Any full-featured Language Server Protocol Client implementation should work
-with :program:`Clangd`. This `list
-<https://langserver.org/#implementations-client>`_ contains information about
-extensions and plugins that are known to work for different editors.
-
-Vim Integration
----------------
-
-LanguageClient-neovim
-~~~~~~~~~~~~~~~~~~~~~
-
-One of the options of using :program:`Clangd` in :program:`vim` (or
-:program:`nvim`) is to utilize `LanguageClient-neovim
-<https://github.com/autozimu/LanguageClient-neovim>`_ plugin. Please see the
-`Clangd Wiki page
-<https://github.com/autozimu/LanguageClient-neovim/wiki/Clangd>`_ for
-instructions.
-
-VSCode Integration
-------------------
-
-:program:`VSCode` provides `vscode-clangd
-<https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd>`_
-which is published in Visual Studio Marketplace and can be installed direcetly
-from :program:`VSCode`.
-
-Emacs Integration
------------------
-
-:program:`Emacs` provides `lsp-mode <github.com/emacs-lsp/lsp-mode>`_ and
-`Eglot <https://github.com/joaotavora/eglot>`_ plugins for LSP integration.
-
-Getting Involved
-==================
-
-A good place for interested contributors is the `Clangd developer mailing list
-<http://lists.llvm.org/mailman/listinfo/clangd-dev>`_. For discussions with the
-broader community on topics not only related to Clangd, use
-`Clang developer mailing list
-<http://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
-If you're also interested in contributing patches to :program:`Clangd`, take a
-look at the `LLVM Developer Policy
-<http://llvm.org/docs/DeveloperPolicy.html>`_ and `Code Reviews
-<http://llvm.org/docs/Phabricator.html>`_ page. Contributions of new features
-to the `Language Server Protocol
-<https://github.com/Microsoft/language-server-protocol>`_ itself would also be
-very useful, so that :program:`Clangd` can eventually implement them in a
-conforming way.
+All :program:`clangd` documentation was moved to the :doc:`clangd/index` pages.
diff --git a/docs/clangd/ApplyClangTidyFixInVSCode.gif b/docs/clangd/ApplyClangTidyFixInVSCode.gif
new file mode 100644
index 0000000..b07bdeb
--- /dev/null
+++ b/docs/clangd/ApplyClangTidyFixInVSCode.gif
Binary files differ
diff --git a/docs/clangd/ApplyFixInVSCode.gif b/docs/clangd/ApplyFixInVSCode.gif
new file mode 100644
index 0000000..929a98c
--- /dev/null
+++ b/docs/clangd/ApplyFixInVSCode.gif
Binary files differ
diff --git a/docs/clangd/CodeCompletionInEmacsCompanyMode.png b/docs/clangd/CodeCompletionInEmacsCompanyMode.png
new file mode 100644
index 0000000..1accc5a
--- /dev/null
+++ b/docs/clangd/CodeCompletionInEmacsCompanyMode.png
Binary files differ
diff --git a/docs/clangd/CodeCompletionInSublimeText.png b/docs/clangd/CodeCompletionInSublimeText.png
new file mode 100644
index 0000000..b09fed3
--- /dev/null
+++ b/docs/clangd/CodeCompletionInSublimeText.png
Binary files differ
diff --git a/docs/clangd/CodeCompletionInVSCode.png b/docs/clangd/CodeCompletionInVSCode.png
new file mode 100644
index 0000000..bc42e9d
--- /dev/null
+++ b/docs/clangd/CodeCompletionInVSCode.png
Binary files differ
diff --git a/docs/clangd/CodeCompletionInYCM.png b/docs/clangd/CodeCompletionInYCM.png
new file mode 100644
index 0000000..b74508d
--- /dev/null
+++ b/docs/clangd/CodeCompletionInYCM.png
Binary files differ
diff --git a/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif b/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif
new file mode 100644
index 0000000..f0d49d6
--- /dev/null
+++ b/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif
Binary files differ
diff --git a/docs/clangd/DeveloperDocumentation.rst b/docs/clangd/DeveloperDocumentation.rst
new file mode 100644
index 0000000..7584327
--- /dev/null
+++ b/docs/clangd/DeveloperDocumentation.rst
@@ -0,0 +1,29 @@
+==================================
+Developer documentation for clangd
+==================================
+
+.. toctree::
+   :maxdepth: 1
+
+   Extensions
+
+Compiling clangd
+================
+
+To build clangd from source, please follow the instructions for `building Clang
+<https://clang.llvm.org/get_started.html>`_ and include LLVM, Clang, and the
+"extra Clang tools" in your build.
+
+Contributing to clangd
+======================
+
+A good place for interested contributors is the `Clangd developer mailing list
+<https://lists.llvm.org/mailman/listinfo/clangd-dev>`_. For discussions with
+the broader community on topics not only related to Clangd, use `Clang
+developer mailing list <https://lists.llvm.org/mailman/listinfo/cfe-dev>`_.  If
+you're also interested in contributing patches to clangd, take a look at the
+`LLVM Developer Policy <https://llvm.org/docs/DeveloperPolicy.html>`_ and `Code
+Reviews <https://llvm.org/docs/Phabricator.html>`_ page. Contributions of new
+features to the `Language Server Protocol
+<https://github.com/Microsoft/language-server-protocol>`_ itself would also be
+very useful, so that clangd can eventually implement them in a conforming way.
diff --git a/docs/clangd/DiagnosticsInEmacsEglot.png b/docs/clangd/DiagnosticsInEmacsEglot.png
new file mode 100644
index 0000000..f5be84b
--- /dev/null
+++ b/docs/clangd/DiagnosticsInEmacsEglot.png
Binary files differ
diff --git a/docs/clangd/ErrorsInVSCode.png b/docs/clangd/ErrorsInVSCode.png
new file mode 100644
index 0000000..52de402
--- /dev/null
+++ b/docs/clangd/ErrorsInVSCode.png
Binary files differ
diff --git a/docs/clangd/Extensions.rst b/docs/clangd/Extensions.rst
new file mode 100644
index 0000000..6c972eb
--- /dev/null
+++ b/docs/clangd/Extensions.rst
@@ -0,0 +1,175 @@
+===================
+Protocol extensions
+===================
+
+.. contents::
+
+clangd supports some features that are not in the official
+`Language Server Protocol specification
+<https://microsoft.github.io/language-server-protocol/specification>`__.
+
+We cautious about adding extensions. The most important considerations are:
+
+- **Editor support**: How many users will the feature be available to?
+- **Standardization**: Is the feature stable? Is it likely to be adopted by more
+  editors over time?
+- **Utility**: Does the feature provide a lot of value?
+- **Complexity**: Is this hard to implement in clangd, or constrain future work?
+  Is the protocol complicated?
+
+These extensions may evolve or disappear over time. If you use them, try to
+recover gracefully if the structures aren't what's expected.
+
+Switch between the implementation file and the header
+=====================================================
+
+*This extension is supported in clangd 6 and newer.*
+
+Switching between the implementation file and the header is an important
+feature for C++.  A language server that understands C++ can do a better job
+than the editor.
+
+**New client->server request**: ``textDocument/switchSourceHeader``.
+
+Lets editors switch between the main source file (``*.cpp``) and header (``*.h``).
+
+Parameter: ``TextDocumentIdentifier``: an open file.
+
+Result: ``string``: the URI of the corresponding header (if a source file was
+provided) or source file (if a header was provided).
+
+If the corresponding file can't be determined, ``""`` is returned.
+
+File status
+===========
+
+*This extension is supported in clangd 8 and newer.*
+
+It is important to provide feedback to the user when the UI is not responsive.
+
+This extension provides information about activity on clangd's per-file worker
+thread.  This information can be displayed to users to let them know that the
+language server is busy with something.  For example, in clangd, building the
+AST blocks many other operations.
+
+**New server->client notification**: ``textDocument/clangd.fileStatus``
+
+Sent when the current activity for a file changes. Replaces previous activity
+for that file.
+
+Parameter: ``FileStatus`` object with properties:
+
+- ``uri : string``: the document whose status is being updated.
+- ``state : string``: human-readable information about current activity.
+
+**New initialization option**: ``initializationOptions.clangdFileStatus : bool``
+
+Enables receiving ``textDocument/clangd.fileStatus`` notifications.
+
+Compilation commands
+====================
+
+*This extension is supported in clangd 8 and newer.*
+
+clangd relies on knowing accurate compilation options to correctly interpret a
+file. Typically they are found in a ``compile_commands.json`` file in a
+directory that contains the file, or an ancestor directory. The following
+extensions allow editors to supply the commands over LSP instead.
+
+**New initialization option**: ``initializationOptions.compilationDatabasePath : string``
+
+Specifies the directory containing the compilation database (e.g.,
+``compile_commands.json``). This path will be used for all files, instead of
+searching their ancestor directories.
+
+**New initialization option**: ``initializationOptions.fallbackFlags : string[]``
+
+Controls the flags used when no specific compile command is found.  The compile
+command will be approximately ``clang $FILE $fallbackFlags`` in this case.
+
+**New configuration setting**: ``settings.compilationDatabaseChanges : {string: CompileCommand}``
+
+Provides compile commands for files. This can also be provided on startup as
+``initializationOptions.compilationDatabaseChanges``.
+
+Keys are file paths (Not URIs!)
+
+Values are ``{workingDirectory: string, compilationCommand: string[]}``.
+
+Force diagnostics generation
+============================
+
+*This extension is supported in clangd 7 and newer.*
+
+Clangd does not regenerate diagnostics for every version of a file (e.g., after
+every keystroke), as that would be too slow. Its heuristics ensure:
+
+- diagnostics do not get too stale,
+- if you stop editing, diagnostics will catch up.
+
+This extension allows editors to force diagnostics to be generated or not
+generated at a particular revision.
+
+**New property of** ``textDocument/didChange`` **request**: ``wantDiagnostics : bool``
+
+- if true, diagnostics will be produced for exactly this version.
+- if false, diagnostics will not be produced for this version, even if there
+  are no further edits.
+- if unset, diagnostics will be produced for this version or some subsequent
+  one in a bounded amount of time.
+
+Diagnostic categories
+=====================
+
+*This extension is supported in clangd 8 and newer.*
+
+Clang compiler groups diagnostics into categories (e.g., "Inline Assembly
+Issue").  Clangd can emit these categories for interested editors.
+
+**New property of** ``Diagnostic`` **object**: ``category : string``:
+
+A human-readable name for a group of related diagnostics.  Diagnostics with the
+same code will always have the same category.
+
+**New client capability**: ``textDocument.publishDiagnostics.categorySupport``:
+
+Requests that clangd send ``Diagnostic.category``.
+
+Inline fixes for diagnostics
+============================
+
+*This extension is supported in clangd 8 and newer.*
+
+LSP specifies that code actions for diagnostics (fixes) are retrieved
+asynchronously using ``textDocument/codeAction``. clangd always computes fixes
+eagerly.  Providing them alongside diagnostics can improve the UX in editors.
+
+**New property of** ``Diagnostic`` **object**: ``codeActions : CodeAction[]``:
+
+All the code actions that address this diagnostic.
+
+**New client capability**: ``textDocument.publishDiagnostics.codeActionsInline : bool``
+
+Requests clangd to send ``Diagnostic.codeActions``.
+
+Symbol info request
+===================
+
+*This extension is supported in clangd 8 and newer.*
+
+**New client->server request**: ``textDocument/symbolInfo``:
+
+This request attempts to resolve the symbol under the cursor, without
+retrieving further information (like definition location, which may require
+consulting an index).  This request was added to support integration with
+indexes outside clangd.
+
+Parameter: ``TextDocumentPositionParams``
+
+Response: ``SymbolDetails``, an object with properties:
+
+- ``name : string`` the unqualified name of the symbol
+- ``containerName : string`` the enclosing namespace, class etc (without
+  trailing ``::``)
+- ``usr : string``: the clang-specific "unified symbol resolution" identifier
+- ``id : string?``: the clangd-specific opaque symbol ID
diff --git a/docs/clangd/Features.rst b/docs/clangd/Features.rst
new file mode 100644
index 0000000..3e6e745
--- /dev/null
+++ b/docs/clangd/Features.rst
@@ -0,0 +1,267 @@
+========
+Features
+========
+
+.. contents::
+
+.. role:: raw-html(raw)
+   :format: html
+
+Here is what clangd can do for you.  Screenshots below show `VSCode
+<https://code.visualstudio.com/>`__; the available features and UI depend on
+the editor.
+
+Errors and warnings
+===================
+
+clangd runs the clang compiler on your code as you type, and shows errors and
+warnings in-place.  Some errors are suppressed: diagnostics that require
+expanding templates in headers are disabled for performance reasons.
+
+:raw-html:`<details><summary markdown="span">Screenshot</summary>`
+
+.. image:: ErrorsInVSCode.png
+   :align: center
+   :alt: Demonstration of errors
+
+:raw-html:`</details>`
+
+Fixes in errors and warnings
+----------------------------
+
+The compiler can suggest fixes for many common problems automatically, and
+clangd can update the code for you.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: ApplyFixInVSCode.gif
+   :align: center
+   :alt: Applying a fix suggested by the compiler
+
+:raw-html:`</details>`
+
+**(New in v9)**
+If a missing symbol was seen in a file you've edited recently, clangd will
+suggest inserting it.
+
+clang-tidy checks
+-----------------
+
+**(New in v9)**
+clangd embeds `clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`__
+which provides extra hints about code problems: bug-prone patterns,
+performance traps, and style issues.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: ApplyClangTidyFixInVSCode.gif
+   :align: center
+   :alt: Applying a fix suggested by the compiler
+
+:raw-html:`</details>`
+
+clangd respects your project's ``.clang-tidy`` file which controls the checks
+to run. Not all checks work within clangd.  You must pass the ``-clang-tidy``
+flag to enable this feature.
+
+Code completion
+===============
+
+You'll see suggestions as you type based on what methods, variables, etc are
+available in this context.
+
+:raw-html:`<details><summary markdown="span">Screenshot</summary>`
+
+.. image:: CodeCompletionInVSCode.png
+   :align: center
+   :alt: Code completion demonstration
+
+:raw-html:`</details>`
+
+Abbreviating words may help you find the right result faster. If you type in
+``camelCase`` but the function you're looking for is ``snake_case``, that's OK.
+
+Insertion of namespace qualifiers and includes
+----------------------------------------------
+
+**(New in v8)**
+clangd will sometimes suggest results from other files and namespaces. In this
+case the correct qualifier and ``#include`` directive will be inserted.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: CodeCompletionInsertsNamespaceQualifiersInVSCode.gif
+   :align: center
+   :alt: Code completion inserts namespace qualifiers
+
+:raw-html:`</details>`
+
+Signature help
+--------------
+
+Some editors will show you the parameters of the function you're calling, as
+you fill them in.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: SignatureHelpInVSCode.gif
+   :align: center
+   :alt: Demonstration of the signature help feature
+
+:raw-html:`</details>`
+
+Cross-references
+================
+
+The following features let you navigate your codebase.
+
+If there is no project-wide index, cross-references work across the files
+you have opened.
+
+**(New in v9)**
+clangd will also automatically index your whole project.
+
+Find definition/declaration
+---------------------------
+
+Jump to the definition or declaration of a symbol under the cursor.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: GoToDefinitionInVSCode.gif
+   :align: center
+   :alt: Demonstration of the "Go to definition" feature
+
+:raw-html:`</details>`
+
+**(New in v9)**
+Some editors only expose "find definition"; use "find definition" on the
+definition to jump to the declaration.
+
+"Find definition" also works on ``#include`` lines, to jump to the included
+file.
+
+Find references
+---------------
+
+Show all references to a symbol under the cursor.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: FindAllReferencesInVSCode.gif
+   :align: center
+   :alt: Demonstration of the "Find all references" feature
+
+:raw-html:`</details>`
+
+Some editors will automatically highlight local references to the selected
+symbol as you move around a file.
+
+Navigation
+==========
+
+clangd informs the editor of the code structure in the current file.
+Some editors use this to present an outline view:
+
+:raw-html:`<details><summary markdown="span">Screenshot</summary>`
+
+.. image:: OutlineInVSCode.png
+   :align: center
+   :alt: Outline of a file
+
+:raw-html:`</details>`
+
+In VSCode, the outline is also presented as breadcrumbs that allow jumping to a
+symbol within the current file.  Searching for symbols within the scope of the
+whole project is also possible.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: NavigationWithBreadcrumbsInVSCode.gif
+   :align: center
+   :alt: Navigation with breadcrumbs
+
+:raw-html:`</details>`
+
+Formatting
+==========
+
+clangd embeds `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__,
+which can reformat your code: fixing indentation, breaking lines, and reflowing
+comments.
+
+:raw-html:`<details><summary markdown="span">Animated demo</summary>`
+
+.. image:: FormatSelectionInVSCode.gif
+   :align: center
+   :alt: Formatting selected code
+
+:raw-html:`</details>`
+
+clangd respects your project's ``.clang-format`` file which controls styling
+options.
+
+Format-as-you-type is experimental and doesn't work well yet.
+
+Complete list of features
+=========================
+
+Here is a list of features that could be useful for editors, together with the
+implementation status in clangd, and specification in the Language Server
+Protocol.
+
+It is not clear whether or not some of the features mentioned below should be a
+part of the Language Server Protocol; those features might be eventually
+developed outside clangd or become clangd extensions to LSP.
+
++-------------------------------------+------------+----------+
+| C/C++ Editor feature                |  LSP       |  Clangd  |
++=====================================+============+==========+
+| Formatting                          | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Completion                          | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Diagnostics                         | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Fix-its                             | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Go to Definition                    | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Signature Help                      | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Document Highlights                 | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Rename                              | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Source hover                        | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Find References                     | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Document Symbols                    | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Workspace Symbols                   | Yes        |   Yes    |
++-------------------------------------+------------+----------+
+| Code Lens                           | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Code folding                        | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Extract Local Variable              | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Extract Function/Method             | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Quick Assist                        | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Hide Method                         | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Implement Method                    | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Gen. Getters/Setters                | Yes        |   No     |
++-------------------------------------+------------+----------+
+| Syntax and Semantic Coloring        | No         |   No     |
++-------------------------------------+------------+----------+
+| Call hierarchy                      | No         |   No     |
++-------------------------------------+------------+----------+
+| Type hierarchy                      | No         |   No     |
++-------------------------------------+------------+----------+
+| Organize Includes                   | No         |   No     |
++-------------------------------------+------------+----------+
diff --git a/docs/clangd/FindAllReferencesInVSCode.gif b/docs/clangd/FindAllReferencesInVSCode.gif
new file mode 100644
index 0000000..b9eecf3
--- /dev/null
+++ b/docs/clangd/FindAllReferencesInVSCode.gif
Binary files differ
diff --git a/docs/clangd/FormatSelectionInVSCode.gif b/docs/clangd/FormatSelectionInVSCode.gif
new file mode 100644
index 0000000..1d4be41
--- /dev/null
+++ b/docs/clangd/FormatSelectionInVSCode.gif
Binary files differ
diff --git a/docs/clangd/GoToDefinitionInVSCode.gif b/docs/clangd/GoToDefinitionInVSCode.gif
new file mode 100644
index 0000000..396966f
--- /dev/null
+++ b/docs/clangd/GoToDefinitionInVSCode.gif
Binary files differ
diff --git a/docs/clangd/Installation.rst b/docs/clangd/Installation.rst
new file mode 100644
index 0000000..1552efc
--- /dev/null
+++ b/docs/clangd/Installation.rst
@@ -0,0 +1,371 @@
+===========================
+Getting started with clangd
+===========================
+
+.. contents::
+
+.. role:: raw-html(raw)
+   :format: html
+
+To use clangd, you need to:
+
+- install clangd,
+- install a plugin for your editor,
+- tell clangd how your project is built.
+
+Installing clangd
+=================
+
+You need a **recent** version of clangd: 7.0 was the first usable release, and
+8.0 is much better.
+
+After installing, ``clangd --version`` should print ``clangd version 7.0.0`` or
+later.
+
+:raw-html:`<details><summary markdown="span">macOS</summary>`
+
+`Homebrew <https://brew.sh>`__ can install clangd along with LLVM:
+
+.. code-block:: console
+
+  $ brew install llvm
+
+If you don't want to use Homebrew, you can download the a binary release of
+LLVM from `releases.llvm.org <http://releases.llvm.org/download.html>`__.
+Alongside ``bin/clangd`` you will need at least ``lib/clang/*/include``:
+
+.. code-block:: console
+
+  $ cp clang+llvm-7.0.0/bin/clangd /usr/local/bin/clangd
+  $ cp -r clang+llvm-7.0.0/lib/clang/ /usr/local/lib/
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Windows</summary>`
+
+Download and run the LLVM installer from `releases.llvm.org
+<http://releases.llvm.org/download.html>`__.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Debian/Ubuntu</summary>`
+
+The ``clang-tools`` package usually contains an old version of clangd.
+
+Try to install the latest release (8.0):
+
+.. code-block:: console
+
+  $ sudo apt-get install clang-tools-8
+
+If that is not found, at least ``clang-tools-7`` should be available.
+
+The ``clangd`` executable will be installed as ``/usr/bin/clangd-8``. Make it
+the default ``clangd``:
+
+.. code-block:: console
+
+  $ sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-8 100
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Other systems</summary>`
+
+Most distributions include clangd in a ``clang-tools`` package, or in the full
+``llvm`` distribution.
+
+For some platforms, binaries are also avaliable at `releases.llvm.org
+<http://releases.llvm.org/download.html>`__.
+
+:raw-html:`</details>`
+
+Editor plugins
+==============
+
+Language Server plugins are available for many editors. In principle, clangd
+should work with any of them, though the feature set and UI may vary.
+
+Here are some plugins we know work well with clangd.
+
+:raw-html:`<details><summary markdown="span">YouCompleteMe for Vim</summary>`
+
+`YouCompleteMe <https://valloric.github.io/YouCompleteMe/>`__ supports clangd.
+However, clangd support is not turned on by default, so you must install
+YouCompleteMe with ``install.py --clangd-completer``.
+
+We recommend changing a couple of YCM's default settings. In ``.vimrc`` add:
+
+::
+
+  " Let clangd fully control code completion
+  let g:ycm_clangd_uses_ycmd_caching = 0
+  " Use installed clangd, not YCM-bundled clangd which doesn't get updates.
+  let g:ycm_clangd_binary_path = exepath("clangd")
+
+You should see errors highlighted and code completions as you type.
+
+.. image:: CodeCompletionInYCM.png
+   :align: center
+   :alt: Code completion in YouCompleteMe
+
+YouCompleteMe supports many of clangd's features:
+
+- code completion,
+- diagnostics and fixes (``:YcmCompleter FixIt``),
+- find declarations, references, and definitions (``:YcmCompleter GoTo`` etc),
+- rename symbol (``:YcmCompleter RefactorRename``).
+
+**Under the hood**
+
+- **Debug logs**: run ``:YcmDebugInfo`` to see clangd status, and ``:YcmToggleLogs``
+  to view clangd's debug logs.
+- **Command-line flags**: Set ``g:ycm_clangd_args`` in ``.vimrc``, e.g.:
+
+  ::
+
+    let g:ycm_clangd_args = ['-log=verbose', '-pretty']
+
+- **Alternate clangd binary**: set ``g:ycm_clangd_binary_path`` in ``.vimrc``.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">LanguageClient for Vim and Neovim</summary>`
+
+`LanguageClient-neovim <https://github.com/autozimu/LanguageClient-neovim>`__
+has `instructions for using clangd
+<https://github.com/autozimu/LanguageClient-neovim/wiki/Clangd>`__, and **may**
+be easier to install than YouCompleteMe.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Eglot for Emacs</summary>`
+
+`eglot <https://github.com/joaotavora/eglot>`__ can be configured to work with
+clangd.
+
+Install eglot with ``M-x package-install RET eglot RET``.
+
+Add the following to ``~/.emacs`` to enable clangd:
+
+::
+
+  (require 'eglot)
+  (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd"))
+  (add-hook 'c-mode-hook 'eglot-ensure)
+  (add-hook 'c++-mode-hook 'eglot-ensure)
+
+After restarting you should see diagnostics for errors in your code, and ``M-x
+completion-at-point`` should work.
+
+.. image:: DiagnosticsInEmacsEglot.png
+   :align: center
+   :alt: Diagnostics in Emacs
+
+eglot supports many of clangd's features, with caveats:
+
+- code completion, though the interaction is quite poor (even with
+  ``company-mode``, see below),
+- diagnostics and fixes,
+- find definitions and references (``M-x xref-find-definitions`` etc),
+- hover and highlights,
+- code actions (``M-x eglot-code-actions``).
+
+**company-mode**
+
+eglot does have basic integration with company-mode, which provides a more
+fluent completion UI.
+
+You can install it with ``M-x package-install RET company RET``, and enable it
+with ``M-x company-mode``.
+
+**company-clang is enabled by default**, and will interfere with clangd.
+Disable it in ``M-x customize-variable RET company-backends RET``.
+
+Completion still has some major limitations:
+
+- completions are alphabetically sorted, not ranked.
+- only pure-prefix completions are shown - no fuzzy matches.
+- completion triggering seems to be a bit hit-and-miss.
+
+.. image:: CodeCompletionInEmacsCompanyMode.png
+   :align: center
+   :alt: Completion in company-mode
+
+**Under the hood**
+
+- **Debug logs**: available in the ``EGLOT stderr`` buffer.
+- **Command-line flags and alternate binary**: instead of adding ``"clangd"``
+  to ``eglot-server-programs``, add ``("/path/to/clangd" "-log=verbose")`` etc.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Visual Studio Code</summary>`
+
+The official extension is `vscode-clangd
+<https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd>`__
+and can be installed from within VSCode.
+
+Choose **View** --> **Extensions**, then search for "clangd". (Make sure the
+Microsoft C/C++ extension is **not** installed).
+
+After restarting, you should see red underlines underneath errors, and you
+should get rich code completions including e.g. function parameters.
+
+.. image:: CodeCompletionInVSCode.png
+   :align: center
+   :alt: Code completion in VSCode
+
+vscode-clangd has excellent support for all clangd features, including:
+
+- code completion
+- diagnostics and fixes
+- find declarations, references, and definitions
+- find symbol in file (``Ctrl-P @foo``) or workspace (``Ctrl-P #foo``)
+- hover and highlights
+- code actions
+
+**Under the hood**
+
+- **Debug logs**: when clangd is running, you should see "Clang Language
+  Server" in the dropdown of the Output panel (**View** -> **Output**).
+
+- **Command-line flags**: these can be passed in the ``clangd.arguments`` array
+  in your ``settings.json``. (**File** -> **Preferences** -> **Settings**).
+
+- **Alternate clangd binary**: set the ``clangd.path`` string in
+  ``settings.json``.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Sublime Text</summary>`
+
+`tomv564/LSP <https://github.com/tomv564/LSP>`__ works with clangd out of the box.
+
+Select **Tools** --> **Install Package Control** (if you haven't installed it
+yet).
+
+Press ``Ctrl-Shift-P`` and select **Package Control: Install Package**. Select
+**LSP**.
+
+Press ``Ctrl-Shift-P`` and select **LSP: Enable Language Server Globally**.
+Select **clangd**.
+
+Open a C++ file, and you should see diagnostics and completion:
+
+.. image:: CodeCompletionInSublimeText.png
+   :align: center
+   :alt: Code completion in Sublime Text
+
+
+The LSP package has excellent support for all most clangd features, including:
+
+- code completion (a bit noisy due to how snippets are presented)
+- diagnostics and fixes
+- find definition and references
+- hover and highlights
+- code actions
+
+**Under the hood**
+
+Settings can be tweaked under **Preferences** --> **Package Settings** -->
+**LSP**.
+
+- **Debug logs**: add ``"log_stderr": true``
+- **Command-line flags and alternate clangd binary**: inside the ``"clients":
+  {"clangd": { ... } }`` section, add ``"command": ["/path/to/clangd",
+  "-log=verbose"]`` etc.
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Other editors</summary>`
+
+There is a directory of LSP clients at `langserver.org
+<http://langserver.org>`__.
+
+A generic client should be configured to run the command ``clangd``, and
+communicate via the language server protocol on standard input/output.
+
+If you don't have strong feelings about an editor, we suggest you try out
+`VSCode <https://code.visualstudio.com/>`__, it has excellent language server
+support and most faithfully demonstrates what clangd can do.
+
+:raw-html:`</details>`
+
+Project setup
+=============
+
+To understand source code in your project, clangd needs to know the build
+flags.  (This is just a fact of life in C++, source files are not
+self-contained.)
+
+By default, clangd will assume that source code is built as ``clang
+some_file.cc``, and you'll probably get spurious errors about missing
+``#include``\ d files, etc.  There are a couple of ways to fix this.
+
+``compile_commands.json``
+-------------------------
+
+``compile_commands.json`` file provides compile commands for all source files
+in the project.  This file is usually generated by the build system, or tools
+integrated with the build system.  Clangd will look for this file in the parent
+directories of the files you edit.
+
+:raw-html:`<details><summary markdown="span">CMake-based projects</summary>`
+
+If your project builds with CMake, it can generate ``compile_commands.json``.
+You should enable it with:
+
+::
+
+  $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1
+
+``compile_commands.json`` will be written to your build directory.  You should
+symlink it (or copy it) to the root of your source tree, if they are different.
+
+::
+
+  $ ln -s ~/myproject/compile_commands.json ~/myproject-build/
+
+:raw-html:`</details>`
+
+:raw-html:`<details><summary markdown="span">Other build systems, using Bear</summary>`
+
+`Bear <https://github.com/rizsotto/Bear>`__ is a tool that generates a
+``compile_commands.json`` file by recording a complete build.
+
+For a ``make``-based build, you can run ``make clean; bear make`` to generate the
+file (and run a clean build!)
+
+:raw-html:`</details>`
+
+Other tools can also generate this file. See `the compile_commands.json
+specification <https://clang.llvm.org/docs/JSONCompilationDatabase.html>`__.
+
+``compile_flags.txt``
+---------------------
+
+If all files in a project use the same build flags, you can put those flags,
+one flag per line, in ``compile_flags.txt`` in your source root.
+
+Clangd will assume the compile command is ``clang $FLAGS some_file.cc``.
+
+Creating this file by hand is a reasonable place to start if your project is
+quite simple.
+
+Project-wide Index
+==================
+
+By default clangd only has a view on symbols coming from files you are
+currently editing. You can extend this view to whole project by providing a
+project-wide index to clangd.  There are two ways to do this.
+
+- Pass an experimental `-background-index` command line argument.  With
+  this feature enabled, clangd incrementally builds an index of projects
+  that you work on and uses the just-built index automatically.
+
+- Generate an index file using `clangd-indexer
+  <https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/indexer/IndexerMain.cpp>`__
+  Then you can pass generated index file to clangd using
+  `-index-file=/path/to/index_file`.  *Note that clangd-indexer isn't
+  included alongside clangd in the Debian clang-tools package. You will
+  likely have to build it from source to use this option.*
diff --git a/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif b/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif
new file mode 100644
index 0000000..499f5c1
--- /dev/null
+++ b/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif
Binary files differ
diff --git a/docs/clangd/OutlineInVSCode.png b/docs/clangd/OutlineInVSCode.png
new file mode 100644
index 0000000..570a80d
--- /dev/null
+++ b/docs/clangd/OutlineInVSCode.png
Binary files differ
diff --git a/docs/clangd/SignatureHelpInVSCode.gif b/docs/clangd/SignatureHelpInVSCode.gif
new file mode 100644
index 0000000..e5700f2
--- /dev/null
+++ b/docs/clangd/SignatureHelpInVSCode.gif
Binary files differ
diff --git a/docs/clangd/index.rst b/docs/clangd/index.rst
new file mode 100644
index 0000000..4693906
--- /dev/null
+++ b/docs/clangd/index.rst
@@ -0,0 +1,27 @@
+======
+clangd
+======
+
+.. toctree::
+   :maxdepth: 1
+
+   Installation
+   Features
+
+What is clangd?
+===============
+
+clangd understands your C++ code and adds smart features to your editor: code
+completion, compile errors, go-to-definition and more.
+
+clangd is a language server that implements the `Language Server Protocol
+<https://github.com/Microsoft/language-server-protocol>`__; it can work with
+many editors through a plugin.  Here's Visual Studio Code with the clangd
+plugin, demonstrating code completion:
+
+.. image:: CodeCompletionInVSCode.png
+   :align: center
+   :alt: Code completion in VSCode
+
+clangd is based on the `Clang <https://clang.llvm.org>`__ C++ compiler, and is
+part of the `LLVM <https://llvm.org>`__ project.
diff --git a/docs/conf.py b/docs/conf.py
index 1b07e8e..16e8105 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -49,9 +49,9 @@
 # built documents.
 #
 # The short version.
-version = '8'
+version = '9'
 # The full version, including alpha/beta/rc tags.
-release = '8'
+release = '9'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -121,7 +121,7 @@
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = []
+html_static_path = ['_static']
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in
index 8809588..fd77fc4 100644
--- a/docs/doxygen.cfg.in
+++ b/docs/doxygen.cfg.in
@@ -752,7 +752,7 @@
                           @abs_srcdir@/../clang-reorder-fields \
                           @abs_srcdir@/../clang-tidy \
                           @abs_srcdir@/../clangd \
-                          @abs_srcdir@/../include-fixer \
+                          @abs_srcdir@/../clang-include-fixer \
                           @abs_srcdir@/../modularize \
                           @abs_srcdir@/../pp-trace \
                           @abs_srcdir@/../tool-template \
diff --git a/docs/index.rst b/docs/index.rst
index 8e6beb3..0fe9895 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,14 +1,9 @@
-.. Extra Clang Tools documentation master file, created by
-   sphinx-quickstart on Wed Feb 13 10:00:18 2013.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
 .. title:: Welcome to Extra Clang Tools's documentation!
 
 Introduction
 ============
 Welcome to the clang-tools-extra project which contains extra tools built using
-Clang's tooling API's.
+Clang's tooling APIs.
 
 .. toctree::
    :maxdepth: 1
@@ -21,11 +16,12 @@
    :maxdepth: 2
 
    clang-tidy/index
-   include-fixer
+   clang-include-fixer
    modularize
    pp-trace
    clang-rename
-   clangd
+   clangd/index
+   clangd/DeveloperDocumentation
    clang-doc
 
 
diff --git a/docs/modularize.rst b/docs/modularize.rst
index 6fe49b4..406ab9c 100644
--- a/docs/modularize.rst
+++ b/docs/modularize.rst
@@ -42,9 +42,9 @@
 Before continuing, take a look at :doc:`ModularizeUsage` to see how to invoke
 modularize.
 
-.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html
-.. _Building LLVM with CMake: http://llvm.org/docs/CMake.html
-.. _Clang Tools Documentation: http://clang.llvm.org/docs/ClangTools.html
+.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
+.. _Building LLVM with CMake: https://llvm.org/docs/CMake.html
+.. _Clang Tools Documentation: https://clang.llvm.org/docs/ClangTools.html
 
 What Modularize Checks
 ======================
@@ -262,4 +262,4 @@
 prepended to the name. For example, if the header name is ``header.h``,
 because ``header`` is a keyword, the module name will be ``_header``.
 For a list of the module map keywords, please see:
-`Lexical structure <http://clang.llvm.org/docs/Modules.html#lexical-structure>`_
+`Lexical structure <https://clang.llvm.org/docs/Modules.html#lexical-structure>`_
diff --git a/docs/pp-trace.rst b/docs/pp-trace.rst
index b8768ed..ed01ae9 100644
--- a/docs/pp-trace.rst
+++ b/docs/pp-trace.rst
@@ -11,7 +11,7 @@
 activity. It's also used as a test of Clang's PPCallbacks interface.
 It runs a given source file through the Clang preprocessor, displaying
 selected information from callback functions overridden in a
-`PPCallbacks <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html>`_
+`PPCallbacks <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html>`_
 derivation. The output is in a high-level YAML format, described in
 :ref:`OutputFormat`.
 
@@ -23,7 +23,7 @@
 Command Line Format
 -------------------
 
-``pp-trace [<pp-trace-options>] <source-file> [<front-end-options>]``
+``pp-trace [<pp-trace-options>] <source-file> [-- <front-end-options>]``
 
 ``<pp-trace-options>`` is a place-holder for options
 specific to pp-trace, which are described below in
@@ -32,7 +32,7 @@
 ``<source-file>`` specifies the source file to run through the preprocessor.
 
 ``<front-end-options>`` is a place-holder for regular
-`Clang Compiler Options <http://clang.llvm.org/docs/UsersManual.html#command-line-options>`_,
+`Clang Compiler Options <https://clang.llvm.org/docs/UsersManual.html#command-line-options>`_,
 which must follow the <source-file>.
 
 .. _CommandLineOptions:
@@ -40,12 +40,12 @@
 Command Line Options
 --------------------
 
-.. option:: -ignore <callback-name-list>
+.. option:: -callbacks <comma-separated-globs>
 
-  This option specifies a comma-separated list of names of callbacks
-  that shouldn't be traced. It can be used to eliminate unwanted
-  trace output. The callback names are the name of the actual
-  callback function names in the PPCallbacks class:
+  This option specifies a comma-separated list of globs describing the list of
+  callbacks that should be traced. Globs are processed in order of appearance.
+  Positive globs add matched callbacks to the set, netative globs (those with
+  the '-' prefix) remove callacks from the set.
 
   * FileChanged
   * FileSkipped
@@ -88,7 +88,7 @@
 pp-trace Output Format
 ======================
 
-The pp-trace output is formatted as YAML. See http://yaml.org/ for general
+The pp-trace output is formatted as YAML. See https://yaml.org/ for general
 YAML information. It's arranged as a sequence of information about the
 callback call, including the callback name and argument information, for
 example:::
@@ -150,8 +150,8 @@
 value, only some key member or members are shown to represent the value,
 instead of trying to display all members of the structure.
 
-`FileChanged <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a7cc8cfaf34114fc65e92af621cd6464e>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`FileChanged <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a7cc8cfaf34114fc65e92af621cd6464e>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 FileChanged is called when the preprocessor enters or exits a file, both the
 top level file being compiled, as well as any #include directives. It will
@@ -177,8 +177,8 @@
     FileType: C_User
     PrevFID: (invalid)
 
-`FileSkipped <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ab5b338a0670188eb05fa7685bbfb5128>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`FileSkipped <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ab5b338a0670188eb05fa7685bbfb5128>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 FileSkipped is called when a source file is skipped as the result of header
 guard optimization.
@@ -200,8 +200,8 @@
     FilenameTok: "filename.h"
     FileType: C_User
 
-`FileNotFound <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3045151545f987256bfa8d978916ef00>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`FileNotFound <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3045151545f987256bfa8d978916ef00>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 FileNotFound is called when an inclusion directive results in a file-not-found error.
 
@@ -220,8 +220,8 @@
     FileName: "/path/filename.h"
     RecoveryPath:
 
-`InclusionDirective <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a557d9738c329793513a6f57d6b60de52>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`InclusionDirective <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a557d9738c329793513a6f57d6b60de52>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 InclusionDirective is called when an inclusion directive of any kind (#include</code>, #import</code>, etc.) has been processed, regardless of whether the inclusion will actually result in an inclusion.
 
@@ -253,8 +253,8 @@
     RelativePath: "Input/Level1B.h"
     Imported: (null)
 
-`moduleImport <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#af32dcf1b8b7c179c7fcd3e24e89830fe>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`moduleImport <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#af32dcf1b8b7c179c7fcd3e24e89830fe>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 moduleImport is called when there was an explicit module-import syntax.
 
@@ -275,8 +275,8 @@
     Path: [{Name: Level1B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:9"}, {Name: Level2B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:17"}]
     Imported: Level2B
 
-`EndOfMainFile <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a63e170d069e99bc1c9c7ea0f3bed8bcc>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`EndOfMainFile <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a63e170d069e99bc1c9c7ea0f3bed8bcc>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 EndOfMainFile is called when the end of the main file is reached.
 
@@ -292,8 +292,8 @@
 
   - Callback: EndOfMainFile
 
-`Ident <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3683f1d1fa513e9b6193d446a5cc2b66>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Ident <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3683f1d1fa513e9b6193d446a5cc2b66>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ident is called when a #ident or #sccs directive is read.
 
@@ -312,8 +312,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-ident.cpp:3:1"
     str: "$Id$"
 
-`PragmaDirective <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0a2d7a72c62184b3cbde31fb62c6f2f7>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaDirective <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0a2d7a72c62184b3cbde31fb62c6f2f7>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDirective is called when start reading any pragma directive.
 
@@ -332,8 +332,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
     Introducer: PIK_HashPragma
 
-`PragmaComment <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ace0d940fc2c12ab76441466aab58dc37>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaComment <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ace0d940fc2c12ab76441466aab58dc37>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaComment is called when a #pragma comment directive is read.
 
@@ -354,8 +354,8 @@
     Kind: library
     Str: kernel32.lib
 
-`PragmaDetectMismatch <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ab11158c9149fb8ad8af1903f4a6cd65d>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaDetectMismatch <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ab11158c9149fb8ad8af1903f4a6cd65d>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDetectMismatch is called when a #pragma detect_mismatch directive is read.
 
@@ -376,8 +376,8 @@
     Name: name
     Value: value
 
-`PragmaDebug <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a57cdccb6dcc07e926513ac3d5b121466>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaDebug <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a57cdccb6dcc07e926513ac3d5b121466>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDebug is called when a #pragma clang __debug directive is read.
 
@@ -396,8 +396,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
     DebugType: warning
 
-`PragmaMessage <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#abb42935d9a9fd8e2c4f51cfdc4ea2ae1>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaMessage <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#abb42935d9a9fd8e2c4f51cfdc4ea2ae1>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaMessage is called when a #pragma message directive is read.
 
@@ -420,8 +420,8 @@
     Kind: PMK_Message
     Str: The message text.
 
-`PragmaDiagnosticPush <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0f3ff19762baa38fe6c5c58022d32979>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaDiagnosticPush <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0f3ff19762baa38fe6c5c58022d32979>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDiagnosticPush is called when a #pragma gcc dianostic push directive is read.
 
@@ -440,7 +440,7 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
     Namespace: "GCC"
 
-`PragmaDiagnosticPop <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ac94d789873122221fba8d76f6c5ea45e>`_ Callback
+`PragmaDiagnosticPop <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ac94d789873122221fba8d76f6c5ea45e>`_ Callback
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDiagnosticPop is called when a #pragma gcc dianostic pop directive is read.
@@ -460,8 +460,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
     Namespace: "GCC"
 
-`PragmaDiagnostic <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#afe7938f38a83cb7b4b25a13edfdd7bdd>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaDiagnostic <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#afe7938f38a83cb7b4b25a13edfdd7bdd>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaDiagnostic is called when a #pragma gcc dianostic directive is read.
 
@@ -484,8 +484,8 @@
     mapping: MAP_WARNING
     Str: WarningName
 
-`PragmaOpenCLExtension <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a92a20a21fadbab4e2c788f4e27fe07e7>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaOpenCLExtension <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a92a20a21fadbab4e2c788f4e27fe07e7>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaOpenCLExtension is called when OpenCL extension is either disabled or enabled with a pragma.
 
@@ -508,8 +508,8 @@
     StateLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:18"
     State: 1
 
-`PragmaWarning <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#aa17169d25fa1cf0a6992fc944d1d8730>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaWarning <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#aa17169d25fa1cf0a6992fc944d1d8730>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaWarning is called when a #pragma warning directive is read.
 
@@ -530,8 +530,8 @@
     WarningSpec: disable
     Ids: 1,2,3
 
-`PragmaWarningPush <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ae5626ef70502687a859f323a809ed0b6>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaWarningPush <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ae5626ef70502687a859f323a809ed0b6>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaWarningPush is called when a #pragma warning(push) directive is read.
 
@@ -550,8 +550,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
     Level: 1
 
-`PragmaWarningPop <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ac98d502af8811b8a6e7342d7cd2b3b95>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`PragmaWarningPop <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ac98d502af8811b8a6e7342d7cd2b3b95>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 PragmaWarningPop is called when a #pragma warning(pop) directive is read.
 
@@ -568,8 +568,8 @@
   - Callback: PragmaWarningPop
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
 
-`MacroExpands <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a9bc725209d3a071ea649144ab996d515>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`MacroExpands <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a9bc725209d3a071ea649144ab996d515>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 MacroExpands is called when ::HandleMacroExpandedIdentifier when a macro invocation is found.
 
@@ -592,8 +592,8 @@
     Range: [(nonfile), (nonfile)]
     Args: [a <plus> y, b]
 
-`MacroDefined <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a8448fc9f96f22ad1b93ff393cffc5a76>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`MacroDefined <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a8448fc9f96f22ad1b93ff393cffc5a76>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 MacroDefined is called when a macro definition is seen.
 
@@ -612,8 +612,8 @@
     MacroNameTok: X_IMPL
     MacroDirective: MD_Define
 
-`MacroUndefined <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#acb80fc6171a839db8e290945bf2c9d7a>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`MacroUndefined <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#acb80fc6171a839db8e290945bf2c9d7a>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 MacroUndefined is called when a macro #undef is seen.
 
@@ -632,8 +632,8 @@
     MacroNameTok: X_IMPL
     MacroDirective: MD_Define
 
-`Defined <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3cc2a644533d0e4088a13d2baf90db94>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Defined <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a3cc2a644533d0e4088a13d2baf90db94>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Defined is called when the 'defined' operator is seen.
 
@@ -654,8 +654,8 @@
     MacroDirective: (null)
     Range: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:5", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:19"]
 
-`SourceRangeSkipped <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#abdb4ebe11610f079ac33515965794b46>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`SourceRangeSkipped <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#abdb4ebe11610f079ac33515965794b46>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 SourceRangeSkipped is called when a source range is skipped.
 
@@ -672,8 +672,8 @@
   - Callback: SourceRangeSkipped
     Range: [":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2", ":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:2"]
 
-`If <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a645edcb0d6becbc6f256f02fd1287778>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`If <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a645edcb0d6becbc6f256f02fd1287778>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 If is called when an #if is seen.
 
@@ -694,8 +694,8 @@
     ConditionRange: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:4", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:1"]
     ConditionValue: false
 
-`Elif <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a180c9e106a28d60a6112e16b1bb8302a>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Elif <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a180c9e106a28d60a6112e16b1bb8302a>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Elif is called when an #elif is seen.
 
@@ -718,8 +718,8 @@
     ConditionValue: false
     IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
 
-`Ifdef <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0ce79575dda307784fd51a6dd4eec33d>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Ifdef <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a0ce79575dda307784fd51a6dd4eec33d>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ifdef is called when an #ifdef is seen.
 
@@ -740,8 +740,8 @@
     MacroNameTok: MACRO
     MacroDirective: MD_Define
 
-`Ifndef <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a767af69f1cdcc4cd880fa2ebf77ad3ad>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Ifndef <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#a767af69f1cdcc4cd880fa2ebf77ad3ad>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Ifndef is called when an #ifndef is seen.
 
@@ -762,8 +762,8 @@
     MacroNameTok: MACRO
     MacroDirective: MD_Define
 
-`Else <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ad57f91b6d9c3cbcca326a2bfb49e0314>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Else <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#ad57f91b6d9c3cbcca326a2bfb49e0314>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Else is called when an #else is seen.
 
@@ -782,8 +782,8 @@
     Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:2"
     IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
 
-`Endif <http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#afc62ca1401125f516d58b1629a2093ce>`_ Callback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+`Endif <https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html#afc62ca1401125f516d58b1629a2093ce>`_ Callback
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Endif is called when an #endif is seen.
 
@@ -819,7 +819,7 @@
    * If using CMake, you can also use the ``pp-trace`` target to build
      just the pp-trace tool and its dependencies.
 
-.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html
-.. _Building LLVM with CMake: http://llvm.org/docs/CMake.html
-.. _Clang Tools Documentation: http://clang.llvm.org/docs/ClangTools.html
+.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html
+.. _Building LLVM with CMake: https://llvm.org/docs/CMake.html
+.. _Clang Tools Documentation: https://clang.llvm.org/docs/ClangTools.html
 
diff --git a/modularize/CoverageChecker.cpp b/modularize/CoverageChecker.cpp
index 4e2a23c..8bcb1c7 100644
--- a/modularize/CoverageChecker.cpp
+++ b/modularize/CoverageChecker.cpp
@@ -1,9 +1,8 @@
 //===--- extra/module-map-checker/CoverageChecker.cpp -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/modularize/CoverageChecker.h b/modularize/CoverageChecker.h
index f6c8367..caafaeb 100644
--- a/modularize/CoverageChecker.h
+++ b/modularize/CoverageChecker.h
@@ -1,9 +1,8 @@
 //===-- CoverageChecker.h - Module map coverage checker -*- C++ -*-------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===--------------------------------------------------------------------===//
 ///
diff --git a/modularize/Modularize.cpp b/modularize/Modularize.cpp
index 83f2340..59fc5c3 100644
--- a/modularize/Modularize.cpp
+++ b/modularize/Modularize.cpp
@@ -1,9 +1,8 @@
 //===- extra/modularize/Modularize.cpp - Check modularized headers --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/modularize/Modularize.h b/modularize/Modularize.h
index a3f2ad3..d11a665 100644
--- a/modularize/Modularize.h
+++ b/modularize/Modularize.h
@@ -1,9 +1,8 @@
 //===--- Modularize.h - Common definitions for Modularize -*- C++ -*-----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===--------------------------------------------------------------------===//
 ///
diff --git a/modularize/ModularizeUtilities.cpp b/modularize/ModularizeUtilities.cpp
index 85768d5..c4e13ab 100644
--- a/modularize/ModularizeUtilities.cpp
+++ b/modularize/ModularizeUtilities.cpp
@@ -1,9 +1,8 @@
 //===--- extra/modularize/ModularizeUtilities.cpp -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/modularize/ModularizeUtilities.h b/modularize/ModularizeUtilities.h
index 4ad2b56..1c8c0b6 100644
--- a/modularize/ModularizeUtilities.h
+++ b/modularize/ModularizeUtilities.h
@@ -1,9 +1,8 @@
 //=====-- ModularizeUtilities.h - Utilities for modularize -*- C++ -*-======//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===--------------------------------------------------------------------===//
 ///
diff --git a/modularize/ModuleAssistant.cpp b/modularize/ModuleAssistant.cpp
index dacb4f9..c34308c 100644
--- a/modularize/ModuleAssistant.cpp
+++ b/modularize/ModuleAssistant.cpp
@@ -1,9 +1,8 @@
 //===--- ModuleAssistant.cpp - Module map generation manager --*- C++ -*---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/modularize/PreprocessorTracker.cpp b/modularize/PreprocessorTracker.cpp
index 6cb34c7..445c0c1 100644
--- a/modularize/PreprocessorTracker.cpp
+++ b/modularize/PreprocessorTracker.cpp
@@ -1,9 +1,8 @@
 //===--- PreprocessorTracker.cpp - Preprocessor tracking -*- C++ -*------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===--------------------------------------------------------------------===//
 //
diff --git a/modularize/PreprocessorTracker.h b/modularize/PreprocessorTracker.h
index a283d9f..8eec76c 100644
--- a/modularize/PreprocessorTracker.h
+++ b/modularize/PreprocessorTracker.h
@@ -1,9 +1,8 @@
 //===- PreprocessorTracker.h - Tracks preprocessor activities -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===--------------------------------------------------------------------===//
 ///
diff --git a/pp-trace/PPCallbacksTracker.cpp b/pp-trace/PPCallbacksTracker.cpp
index 2530dc2..ae4d584 100644
--- a/pp-trace/PPCallbacksTracker.cpp
+++ b/pp-trace/PPCallbacksTracker.cpp
@@ -1,9 +1,8 @@
 //===--- PPCallbacksTracker.cpp - Preprocessor tracker -*--*---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -18,16 +17,17 @@
 #include "clang/Lex/MacroArgs.h"
 #include "llvm/Support/raw_ostream.h"
 
-// Utility functions.
+namespace clang {
+namespace pp_trace {
 
 // Get a "file:line:column" source location string.
-static std::string getSourceLocationString(clang::Preprocessor &PP,
-                                           clang::SourceLocation Loc) {
+static std::string getSourceLocationString(Preprocessor &PP,
+                                           SourceLocation Loc) {
   if (Loc.isInvalid())
     return std::string("(none)");
 
   if (Loc.isFileID()) {
-    clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
+    PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
 
     if (PLoc.isInvalid()) {
       return std::string("(invalid)");
@@ -89,19 +89,20 @@
 
 // PPCallbacksTracker functions.
 
-PPCallbacksTracker::PPCallbacksTracker(llvm::SmallSet<std::string, 4> &Ignore,
+PPCallbacksTracker::PPCallbacksTracker(const FilterType &Filters,
                                        std::vector<CallbackCall> &CallbackCalls,
-                                       clang::Preprocessor &PP)
-    : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {}
+                                       Preprocessor &PP)
+    : CallbackCalls(CallbackCalls), Filters(Filters), PP(PP) {}
 
 PPCallbacksTracker::~PPCallbacksTracker() {}
 
 // Callback functions.
 
 // Callback invoked whenever a source file is entered or exited.
-void PPCallbacksTracker::FileChanged(
-    clang::SourceLocation Loc, clang::PPCallbacks::FileChangeReason Reason,
-    clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
+void PPCallbacksTracker::FileChanged(SourceLocation Loc,
+                                     PPCallbacks::FileChangeReason Reason,
+                                     SrcMgr::CharacteristicKind FileType,
+                                     FileID PrevFID) {
   beginCallback("FileChanged");
   appendArgument("Loc", Loc);
   appendArgument("Reason", Reason, FileChangeReasonStrings);
@@ -111,10 +112,9 @@
 
 // Callback invoked whenever a source file is skipped as the result
 // of header guard optimization.
-void
-PPCallbacksTracker::FileSkipped(const clang::FileEntry &SkippedFile,
-                                const clang::Token &FilenameTok,
-                                clang::SrcMgr::CharacteristicKind FileType) {
+void PPCallbacksTracker::FileSkipped(const FileEntry &SkippedFile,
+                                     const Token &FilenameTok,
+                                     SrcMgr::CharacteristicKind FileType) {
   beginCallback("FileSkipped");
   appendArgument("ParentFile", &SkippedFile);
   appendArgument("FilenameTok", FilenameTok);
@@ -135,11 +135,10 @@
 // any kind (#include, #import, etc.) has been processed, regardless
 // of whether the inclusion will actually result in an inclusion.
 void PPCallbacksTracker::InclusionDirective(
-    clang::SourceLocation HashLoc, const clang::Token &IncludeTok,
-    llvm::StringRef FileName, bool IsAngled,
-    clang::CharSourceRange FilenameRange, const clang::FileEntry *File,
+    SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName,
+    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
     llvm::StringRef SearchPath, llvm::StringRef RelativePath,
-    const clang::Module *Imported, clang::SrcMgr::CharacteristicKind FileType) {
+    const Module *Imported, SrcMgr::CharacteristicKind FileType) {
   beginCallback("InclusionDirective");
   appendArgument("IncludeTok", IncludeTok);
   appendFilePathArgument("FileName", FileName);
@@ -153,9 +152,9 @@
 
 // Callback invoked whenever there was an explicit module-import
 // syntax.
-void PPCallbacksTracker::moduleImport(clang::SourceLocation ImportLoc,
-                                      clang::ModuleIdPath Path,
-                                      const clang::Module *Imported) {
+void PPCallbacksTracker::moduleImport(SourceLocation ImportLoc,
+                                      ModuleIdPath Path,
+                                      const Module *Imported) {
   beginCallback("moduleImport");
   appendArgument("ImportLoc", ImportLoc);
   appendArgument("Path", Path);
@@ -167,24 +166,23 @@
 void PPCallbacksTracker::EndOfMainFile() { beginCallback("EndOfMainFile"); }
 
 // Callback invoked when a #ident or #sccs directive is read.
-void PPCallbacksTracker::Ident(clang::SourceLocation Loc, llvm::StringRef Str) {
+void PPCallbacksTracker::Ident(SourceLocation Loc, llvm::StringRef Str) {
   beginCallback("Ident");
   appendArgument("Loc", Loc);
   appendArgument("Str", Str);
 }
 
 // Callback invoked when start reading any pragma directive.
-void
-PPCallbacksTracker::PragmaDirective(clang::SourceLocation Loc,
-                                    clang::PragmaIntroducerKind Introducer) {
+void PPCallbacksTracker::PragmaDirective(SourceLocation Loc,
+                                         PragmaIntroducerKind Introducer) {
   beginCallback("PragmaDirective");
   appendArgument("Loc", Loc);
   appendArgument("Introducer", Introducer, PragmaIntroducerKindStrings);
 }
 
 // Callback invoked when a #pragma comment directive is read.
-void PPCallbacksTracker::PragmaComment(clang::SourceLocation Loc,
-                                       const clang::IdentifierInfo *Kind,
+void PPCallbacksTracker::PragmaComment(SourceLocation Loc,
+                                       const IdentifierInfo *Kind,
                                        llvm::StringRef Str) {
   beginCallback("PragmaComment");
   appendArgument("Loc", Loc);
@@ -194,7 +192,7 @@
 
 // Callback invoked when a #pragma detect_mismatch directive is
 // read.
-void PPCallbacksTracker::PragmaDetectMismatch(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaDetectMismatch(SourceLocation Loc,
                                               llvm::StringRef Name,
                                               llvm::StringRef Value) {
   beginCallback("PragmaDetectMismatch");
@@ -204,7 +202,7 @@
 }
 
 // Callback invoked when a #pragma clang __debug directive is read.
-void PPCallbacksTracker::PragmaDebug(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaDebug(SourceLocation Loc,
                                      llvm::StringRef DebugType) {
   beginCallback("PragmaDebug");
   appendArgument("Loc", Loc);
@@ -212,9 +210,10 @@
 }
 
 // Callback invoked when a #pragma message directive is read.
-void PPCallbacksTracker::PragmaMessage(
-    clang::SourceLocation Loc, llvm::StringRef Namespace,
-    clang::PPCallbacks::PragmaMessageKind Kind, llvm::StringRef Str) {
+void PPCallbacksTracker::PragmaMessage(SourceLocation Loc,
+                                       llvm::StringRef Namespace,
+                                       PPCallbacks::PragmaMessageKind Kind,
+                                       llvm::StringRef Str) {
   beginCallback("PragmaMessage");
   appendArgument("Loc", Loc);
   appendArgument("Namespace", Namespace);
@@ -224,7 +223,7 @@
 
 // Callback invoked when a #pragma gcc dianostic push directive
 // is read.
-void PPCallbacksTracker::PragmaDiagnosticPush(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaDiagnosticPush(SourceLocation Loc,
                                               llvm::StringRef Namespace) {
   beginCallback("PragmaDiagnosticPush");
   appendArgument("Loc", Loc);
@@ -233,7 +232,7 @@
 
 // Callback invoked when a #pragma gcc dianostic pop directive
 // is read.
-void PPCallbacksTracker::PragmaDiagnosticPop(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaDiagnosticPop(SourceLocation Loc,
                                              llvm::StringRef Namespace) {
   beginCallback("PragmaDiagnosticPop");
   appendArgument("Loc", Loc);
@@ -241,9 +240,9 @@
 }
 
 // Callback invoked when a #pragma gcc dianostic directive is read.
-void PPCallbacksTracker::PragmaDiagnostic(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaDiagnostic(SourceLocation Loc,
                                           llvm::StringRef Namespace,
-                                          clang::diag::Severity Mapping,
+                                          diag::Severity Mapping,
                                           llvm::StringRef Str) {
   beginCallback("PragmaDiagnostic");
   appendArgument("Loc", Loc);
@@ -254,9 +253,10 @@
 
 // Called when an OpenCL extension is either disabled or
 // enabled with a pragma.
-void PPCallbacksTracker::PragmaOpenCLExtension(
-    clang::SourceLocation NameLoc, const clang::IdentifierInfo *Name,
-    clang::SourceLocation StateLoc, unsigned State) {
+void PPCallbacksTracker::PragmaOpenCLExtension(SourceLocation NameLoc,
+                                               const IdentifierInfo *Name,
+                                               SourceLocation StateLoc,
+                                               unsigned State) {
   beginCallback("PragmaOpenCLExtension");
   appendArgument("NameLoc", NameLoc);
   appendArgument("Name", Name);
@@ -265,7 +265,7 @@
 }
 
 // Callback invoked when a #pragma warning directive is read.
-void PPCallbacksTracker::PragmaWarning(clang::SourceLocation Loc,
+void PPCallbacksTracker::PragmaWarning(SourceLocation Loc,
                                        llvm::StringRef WarningSpec,
                                        llvm::ArrayRef<int> Ids) {
   beginCallback("PragmaWarning");
@@ -285,26 +285,40 @@
 }
 
 // Callback invoked when a #pragma warning(push) directive is read.
-void PPCallbacksTracker::PragmaWarningPush(clang::SourceLocation Loc,
-                                           int Level) {
+void PPCallbacksTracker::PragmaWarningPush(SourceLocation Loc, int Level) {
   beginCallback("PragmaWarningPush");
   appendArgument("Loc", Loc);
   appendArgument("Level", Level);
 }
 
 // Callback invoked when a #pragma warning(pop) directive is read.
-void PPCallbacksTracker::PragmaWarningPop(clang::SourceLocation Loc) {
+void PPCallbacksTracker::PragmaWarningPop(SourceLocation Loc) {
   beginCallback("PragmaWarningPop");
   appendArgument("Loc", Loc);
 }
 
+// Callback invoked when a #pragma execution_character_set(push) directive
+// is read.
+void PPCallbacksTracker::PragmaExecCharsetPush(SourceLocation Loc,
+                                               StringRef Str) {
+  beginCallback("PragmaExecCharsetPush");
+  appendArgument("Loc", Loc);
+  appendArgument("Charset", Str);
+}
+
+// Callback invoked when a #pragma execution_character_set(pop) directive
+// is read.
+void PPCallbacksTracker::PragmaExecCharsetPop(SourceLocation Loc) {
+  beginCallback("PragmaExecCharsetPop");
+  appendArgument("Loc", Loc);
+}
+
 // Called by Preprocessor::HandleMacroExpandedIdentifier when a
 // macro invocation is found.
-void
-PPCallbacksTracker::MacroExpands(const clang::Token &MacroNameTok,
-                                 const clang::MacroDefinition &MacroDefinition,
-                                 clang::SourceRange Range,
-                                 const clang::MacroArgs *Args) {
+void PPCallbacksTracker::MacroExpands(const Token &MacroNameTok,
+                                      const MacroDefinition &MacroDefinition,
+                                      SourceRange Range,
+                                      const MacroArgs *Args) {
   beginCallback("MacroExpands");
   appendArgument("MacroNameTok", MacroNameTok);
   appendArgument("MacroDefinition", MacroDefinition);
@@ -313,28 +327,26 @@
 }
 
 // Hook called whenever a macro definition is seen.
-void
-PPCallbacksTracker::MacroDefined(const clang::Token &MacroNameTok,
-                                 const clang::MacroDirective *MacroDirective) {
+void PPCallbacksTracker::MacroDefined(const Token &MacroNameTok,
+                                      const MacroDirective *MacroDirective) {
   beginCallback("MacroDefined");
   appendArgument("MacroNameTok", MacroNameTok);
   appendArgument("MacroDirective", MacroDirective);
 }
 
 // Hook called whenever a macro #undef is seen.
-void PPCallbacksTracker::MacroUndefined(
-    const clang::Token &MacroNameTok,
-    const clang::MacroDefinition &MacroDefinition,
-    const clang::MacroDirective *Undef) {
+void PPCallbacksTracker::MacroUndefined(const Token &MacroNameTok,
+                                        const MacroDefinition &MacroDefinition,
+                                        const MacroDirective *Undef) {
   beginCallback("MacroUndefined");
   appendArgument("MacroNameTok", MacroNameTok);
   appendArgument("MacroDefinition", MacroDefinition);
 }
 
 // Hook called whenever the 'defined' operator is seen.
-void PPCallbacksTracker::Defined(const clang::Token &MacroNameTok,
-                                 const clang::MacroDefinition &MacroDefinition,
-                                 clang::SourceRange Range) {
+void PPCallbacksTracker::Defined(const Token &MacroNameTok,
+                                 const MacroDefinition &MacroDefinition,
+                                 SourceRange Range) {
   beginCallback("Defined");
   appendArgument("MacroNameTok", MacroNameTok);
   appendArgument("MacroDefinition", MacroDefinition);
@@ -342,15 +354,14 @@
 }
 
 // Hook called when a source range is skipped.
-void PPCallbacksTracker::SourceRangeSkipped(clang::SourceRange Range,
-                                            clang::SourceLocation EndifLoc) {
+void PPCallbacksTracker::SourceRangeSkipped(SourceRange Range,
+                                            SourceLocation EndifLoc) {
   beginCallback("SourceRangeSkipped");
-  appendArgument("Range", clang::SourceRange(Range.getBegin(), EndifLoc));
+  appendArgument("Range", SourceRange(Range.getBegin(), EndifLoc));
 }
 
 // Hook called whenever an #if is seen.
-void PPCallbacksTracker::If(clang::SourceLocation Loc,
-                            clang::SourceRange ConditionRange,
+void PPCallbacksTracker::If(SourceLocation Loc, SourceRange ConditionRange,
                             ConditionValueKind ConditionValue) {
   beginCallback("If");
   appendArgument("Loc", Loc);
@@ -359,10 +370,9 @@
 }
 
 // Hook called whenever an #elif is seen.
-void PPCallbacksTracker::Elif(clang::SourceLocation Loc,
-                              clang::SourceRange ConditionRange,
+void PPCallbacksTracker::Elif(SourceLocation Loc, SourceRange ConditionRange,
                               ConditionValueKind ConditionValue,
-                              clang::SourceLocation IfLoc) {
+                              SourceLocation IfLoc) {
   beginCallback("Elif");
   appendArgument("Loc", Loc);
   appendArgument("ConditionRange", ConditionRange);
@@ -371,9 +381,8 @@
 }
 
 // Hook called whenever an #ifdef is seen.
-void PPCallbacksTracker::Ifdef(clang::SourceLocation Loc,
-                               const clang::Token &MacroNameTok,
-                               const clang::MacroDefinition &MacroDefinition) {
+void PPCallbacksTracker::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+                               const MacroDefinition &MacroDefinition) {
   beginCallback("Ifdef");
   appendArgument("Loc", Loc);
   appendArgument("MacroNameTok", MacroNameTok);
@@ -381,9 +390,8 @@
 }
 
 // Hook called whenever an #ifndef is seen.
-void PPCallbacksTracker::Ifndef(clang::SourceLocation Loc,
-                                const clang::Token &MacroNameTok,
-                                const clang::MacroDefinition &MacroDefinition) {
+void PPCallbacksTracker::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+                                const MacroDefinition &MacroDefinition) {
   beginCallback("Ifndef");
   appendArgument("Loc", Loc);
   appendArgument("MacroNameTok", MacroNameTok);
@@ -391,16 +399,14 @@
 }
 
 // Hook called whenever an #else is seen.
-void PPCallbacksTracker::Else(clang::SourceLocation Loc,
-                              clang::SourceLocation IfLoc) {
+void PPCallbacksTracker::Else(SourceLocation Loc, SourceLocation IfLoc) {
   beginCallback("Else");
   appendArgument("Loc", Loc);
   appendArgument("IfLoc", IfLoc);
 }
 
 // Hook called whenever an #endif is seen.
-void PPCallbacksTracker::Endif(clang::SourceLocation Loc,
-                               clang::SourceLocation IfLoc) {
+void PPCallbacksTracker::Endif(SourceLocation Loc, SourceLocation IfLoc) {
   beginCallback("Endif");
   appendArgument("Loc", Loc);
   appendArgument("IfLoc", IfLoc);
@@ -410,7 +416,14 @@
 
 // Start a new callback.
 void PPCallbacksTracker::beginCallback(const char *Name) {
-  DisableTrace = Ignore.count(std::string(Name));
+  auto R = CallbackIsEnabled.try_emplace(Name, false);
+  if (R.second) {
+    llvm::StringRef N(Name);
+    for (const std::pair<llvm::GlobPattern, bool> &Filter : Filters)
+      if (Filter.first.match(N))
+        R.first->second = Filter.second;
+  }
+  DisableTrace = !R.first->second;
   if (DisableTrace)
     return;
   CallbackCalls.push_back(CallbackCall(Name));
@@ -433,7 +446,7 @@
 void PPCallbacksTracker::appendArgument(const char *Name, const char *Value) {
   if (DisableTrace)
     return;
-  CallbackCalls.back().Arguments.push_back(Argument(Name, Value));
+  CallbackCalls.back().Arguments.push_back(Argument{Name, Value});
 }
 
 // Append a string object argument to the top trace item.
@@ -449,8 +462,7 @@
 }
 
 // Append a token argument to the top trace item.
-void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::Token &Value) {
+void PPCallbacksTracker::appendArgument(const char *Name, const Token &Value) {
   appendArgument(Name, PP.getSpelling(Value));
 }
 
@@ -461,13 +473,12 @@
 }
 
 // Append a FileID argument to the top trace item.
-void PPCallbacksTracker::appendArgument(const char *Name, clang::FileID Value) {
+void PPCallbacksTracker::appendArgument(const char *Name, FileID Value) {
   if (Value.isInvalid()) {
     appendArgument(Name, "(invalid)");
     return;
   }
-  const clang::FileEntry *FileEntry =
-      PP.getSourceManager().getFileEntryForID(Value);
+  const FileEntry *FileEntry = PP.getSourceManager().getFileEntryForID(Value);
   if (!FileEntry) {
     appendArgument(Name, "(getFileEntryForID failed)");
     return;
@@ -477,7 +488,7 @@
 
 // Append a FileEntry argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::FileEntry *Value) {
+                                        const FileEntry *Value) {
   if (!Value) {
     appendArgument(Name, "(null)");
     return;
@@ -487,7 +498,7 @@
 
 // Append a SourceLocation argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        clang::SourceLocation Value) {
+                                        SourceLocation Value) {
   if (Value.isInvalid()) {
     appendArgument(Name, "(invalid)");
     return;
@@ -496,8 +507,7 @@
 }
 
 // Append a SourceRange argument to the top trace item.
-void PPCallbacksTracker::appendArgument(const char *Name,
-                                        clang::SourceRange Value) {
+void PPCallbacksTracker::appendArgument(const char *Name, SourceRange Value) {
   if (DisableTrace)
     return;
   if (Value.isInvalid()) {
@@ -513,7 +523,7 @@
 
 // Append a CharSourceRange argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        clang::CharSourceRange Value) {
+                                        CharSourceRange Value) {
   if (Value.isInvalid()) {
     appendArgument(Name, "(invalid)");
     return;
@@ -522,8 +532,7 @@
 }
 
 // Append a SourceLocation argument to the top trace item.
-void PPCallbacksTracker::appendArgument(const char *Name,
-                                        clang::ModuleIdPath Value) {
+void PPCallbacksTracker::appendArgument(const char *Name, ModuleIdPath Value) {
   if (DisableTrace)
     return;
   std::string Str;
@@ -542,7 +551,7 @@
 
 // Append an IdentifierInfo argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::IdentifierInfo *Value) {
+                                        const IdentifierInfo *Value) {
   if (!Value) {
     appendArgument(Name, "(null)");
     return;
@@ -552,7 +561,7 @@
 
 // Append a MacroDirective argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::MacroDirective *Value) {
+                                        const MacroDirective *Value) {
   if (!Value) {
     appendArgument(Name, "(null)");
     return;
@@ -562,7 +571,7 @@
 
 // Append a MacroDefinition argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::MacroDefinition &Value) {
+                                        const MacroDefinition &Value) {
   std::string Str;
   llvm::raw_string_ostream SS(Str);
   SS << "[";
@@ -581,7 +590,7 @@
 
 // Append a MacroArgs argument to the top trace item.
 void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::MacroArgs *Value) {
+                                        const MacroArgs *Value) {
   if (!Value) {
     appendArgument(Name, "(null)");
     return;
@@ -593,18 +602,17 @@
   // Each argument is is a series of contiguous Tokens, terminated by a eof.
   // Go through each argument printing tokens until we reach eof.
   for (unsigned I = 0; I < Value->getNumMacroArguments(); ++I) {
-    const clang::Token *Current = Value->getUnexpArgument(I);
+    const Token *Current = Value->getUnexpArgument(I);
     if (I)
       SS << ", ";
     bool First = true;
-    while (Current->isNot(clang::tok::eof)) {
+    while (Current->isNot(tok::eof)) {
       if (!First)
         SS << " ";
       // We need to be careful here because the arguments might not be legal in
       // YAML, so we use the token name for anything but identifiers and
       // numeric literals.
-      if (Current->isAnyIdentifier() ||
-          Current->is(clang::tok::numeric_constant)) {
+      if (Current->isAnyIdentifier() || Current->is(tok::numeric_constant)) {
         SS << PP.getSpelling(*Current);
       } else {
         SS << "<" << Current->getName() << ">";
@@ -618,8 +626,7 @@
 }
 
 // Append a Module argument to the top trace item.
-void PPCallbacksTracker::appendArgument(const char *Name,
-                                        const clang::Module *Value) {
+void PPCallbacksTracker::appendArgument(const char *Name, const Module *Value) {
   if (!Value) {
     appendArgument(Name, "(null)");
     return;
@@ -646,9 +653,11 @@
 }
 
 // Get the raw source string of the range.
-llvm::StringRef
-PPCallbacksTracker::getSourceString(clang::CharSourceRange Range) {
+llvm::StringRef PPCallbacksTracker::getSourceString(CharSourceRange Range) {
   const char *B = PP.getSourceManager().getCharacterData(Range.getBegin());
   const char *E = PP.getSourceManager().getCharacterData(Range.getEnd());
   return llvm::StringRef(B, E - B);
 }
+
+} // namespace pp_trace
+} // namespace clang
diff --git a/pp-trace/PPCallbacksTracker.h b/pp-trace/PPCallbacksTracker.h
index b46210e..1fb5c6f 100644
--- a/pp-trace/PPCallbacksTracker.h
+++ b/pp-trace/PPCallbacksTracker.h
@@ -1,9 +1,8 @@
 //===--- PPCallbacksTracker.h - Preprocessor tracking -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -27,18 +26,17 @@
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/GlobPattern.h"
 #include <string>
 #include <vector>
 
-/// \brief This class represents one callback function argument by name
-///   and value.
-class Argument {
-public:
-  Argument(llvm::StringRef Name, llvm::StringRef Value)
-      : Name(Name), Value(Value) {}
-  Argument() = default;
+namespace clang {
+namespace pp_trace {
 
+// This struct represents one callback function argument by name and value.
+struct Argument {
   std::string Name;
   std::string Value;
 };
@@ -54,6 +52,8 @@
   std::vector<Argument> Arguments;
 };
 
+using FilterType = std::vector<std::pair<llvm::GlobPattern, bool>>;
+
 /// \brief This class overrides the PPCallbacks class for tracking preprocessor
 ///   activity by means of its callback functions.
 ///
@@ -71,95 +71,81 @@
 /// overidden callback functions are defined.  The remaining functions are
 /// helpers for recording the trace data, to reduce the coupling between it
 /// and the recorded data structure.
-class PPCallbacksTracker : public clang::PPCallbacks {
+class PPCallbacksTracker : public PPCallbacks {
 public:
   /// \brief Note that all of the arguments are references, and owned
   /// by the caller.
-  /// \param Ignore - Set of names of callbacks to ignore.
+  /// \param Filters - List of (Glob,Enabled) pairs used to filter callbacks.
   /// \param CallbackCalls - Trace buffer.
   /// \param PP - The preprocessor.  Needed for getting some argument strings.
-  PPCallbacksTracker(llvm::SmallSet<std::string, 4> &Ignore,
+  PPCallbacksTracker(const FilterType &Filters,
                      std::vector<CallbackCall> &CallbackCalls,
-                     clang::Preprocessor &PP);
+                     Preprocessor &PP);
 
   ~PPCallbacksTracker() override;
 
   // Overidden callback functions.
 
-  void FileChanged(clang::SourceLocation Loc,
-                   clang::PPCallbacks::FileChangeReason Reason,
-                   clang::SrcMgr::CharacteristicKind FileType,
-                   clang::FileID PrevFID = clang::FileID()) override;
-  void FileSkipped(const clang::FileEntry &SkippedFile,
-                   const clang::Token &FilenameTok,
-                   clang::SrcMgr::CharacteristicKind FileType) override;
+  void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID = FileID()) override;
+  void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override;
   bool FileNotFound(llvm::StringRef FileName,
                     llvm::SmallVectorImpl<char> &RecoveryPath) override;
-  void InclusionDirective(clang::SourceLocation HashLoc,
-                          const clang::Token &IncludeTok,
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                           llvm::StringRef FileName, bool IsAngled,
-                          clang::CharSourceRange FilenameRange,
-                          const clang::FileEntry *File,
+                          CharSourceRange FilenameRange, const FileEntry *File,
                           llvm::StringRef SearchPath,
-                          llvm::StringRef RelativePath,
-                          const clang::Module *Imported,
-                          clang::SrcMgr::CharacteristicKind FileType) override;
-  void moduleImport(clang::SourceLocation ImportLoc, clang::ModuleIdPath Path,
-                    const clang::Module *Imported) override;
+                          llvm::StringRef RelativePath, const Module *Imported,
+                          SrcMgr::CharacteristicKind FileType) override;
+  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
+                    const Module *Imported) override;
   void EndOfMainFile() override;
-  void Ident(clang::SourceLocation Loc, llvm::StringRef str) override;
-  void PragmaDirective(clang::SourceLocation Loc,
-                       clang::PragmaIntroducerKind Introducer) override;
-  void PragmaComment(clang::SourceLocation Loc,
-                     const clang::IdentifierInfo *Kind,
+  void Ident(SourceLocation Loc, llvm::StringRef str) override;
+  void PragmaDirective(SourceLocation Loc,
+                       PragmaIntroducerKind Introducer) override;
+  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
                      llvm::StringRef Str) override;
-  void PragmaDetectMismatch(clang::SourceLocation Loc, llvm::StringRef Name,
+  void PragmaDetectMismatch(SourceLocation Loc, llvm::StringRef Name,
                             llvm::StringRef Value) override;
-  void PragmaDebug(clang::SourceLocation Loc,
-                   llvm::StringRef DebugType) override;
-  void PragmaMessage(clang::SourceLocation Loc, llvm::StringRef Namespace,
-                     clang::PPCallbacks::PragmaMessageKind Kind,
+  void PragmaDebug(SourceLocation Loc, llvm::StringRef DebugType) override;
+  void PragmaMessage(SourceLocation Loc, llvm::StringRef Namespace,
+                     PPCallbacks::PragmaMessageKind Kind,
                      llvm::StringRef Str) override;
-  void PragmaDiagnosticPush(clang::SourceLocation Loc,
+  void PragmaDiagnosticPush(SourceLocation Loc,
                             llvm::StringRef Namespace) override;
-  void PragmaDiagnosticPop(clang::SourceLocation Loc,
+  void PragmaDiagnosticPop(SourceLocation Loc,
                            llvm::StringRef Namespace) override;
-  void PragmaDiagnostic(clang::SourceLocation Loc, llvm::StringRef Namespace,
-                        clang::diag::Severity mapping,
-                        llvm::StringRef Str) override;
-  void PragmaOpenCLExtension(clang::SourceLocation NameLoc,
-                             const clang::IdentifierInfo *Name,
-                             clang::SourceLocation StateLoc,
-                             unsigned State) override;
-  void PragmaWarning(clang::SourceLocation Loc, llvm::StringRef WarningSpec,
+  void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
+                        diag::Severity mapping, llvm::StringRef Str) override;
+  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
+                             SourceLocation StateLoc, unsigned State) override;
+  void PragmaWarning(SourceLocation Loc, llvm::StringRef WarningSpec,
                      llvm::ArrayRef<int> Ids) override;
-  void PragmaWarningPush(clang::SourceLocation Loc, int Level) override;
-  void PragmaWarningPop(clang::SourceLocation Loc) override;
-  void MacroExpands(const clang::Token &MacroNameTok,
-                    const clang::MacroDefinition &MD, clang::SourceRange Range,
-                    const clang::MacroArgs *Args) override;
-  void MacroDefined(const clang::Token &MacroNameTok,
-                    const clang::MacroDirective *MD) override;
-  void MacroUndefined(const clang::Token &MacroNameTok,
-                      const clang::MacroDefinition &MD,
-                      const clang::MacroDirective *Undef) override;
-  void Defined(const clang::Token &MacroNameTok,
-               const clang::MacroDefinition &MD,
-               clang::SourceRange Range) override;
-  void SourceRangeSkipped(clang::SourceRange Range,
-                          clang::SourceLocation EndifLoc) override;
-  void If(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
+  void PragmaWarningPush(SourceLocation Loc, int Level) override;
+  void PragmaWarningPop(SourceLocation Loc) override;
+  void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override;
+  void PragmaExecCharsetPop(SourceLocation Loc) override;
+  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+                    SourceRange Range, const MacroArgs *Args) override;
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override;
+  void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
+                      const MacroDirective *Undef) override;
+  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
+               SourceRange Range) override;
+  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;
+  void If(SourceLocation Loc, SourceRange ConditionRange,
           ConditionValueKind ConditionValue) override;
-  void Elif(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
-            ConditionValueKind ConditionValue, clang::SourceLocation IfLoc) override;
-  void Ifdef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
-             const clang::MacroDefinition &MD) override;
-  void Ifndef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
-              const clang::MacroDefinition &MD) override;
-  void Else(clang::SourceLocation Loc,
-            clang::SourceLocation IfLoc) override;
-  void Endif(clang::SourceLocation Loc,
-             clang::SourceLocation IfLoc) override;
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDefinition &MD) override;
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDefinition &MD) override;
+  void Else(SourceLocation Loc, SourceLocation IfLoc) override;
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
 
   // Helper functions.
 
@@ -185,43 +171,43 @@
   void appendArgument(const char *Name, const std::string &Value);
 
   /// \brief Append a token argument to the top trace item.
-  void appendArgument(const char *Name, const clang::Token &Value);
+  void appendArgument(const char *Name, const Token &Value);
 
   /// \brief Append an enum argument to the top trace item.
   void appendArgument(const char *Name, int Value, const char *const Strings[]);
 
   /// \brief Append a FileID argument to the top trace item.
-  void appendArgument(const char *Name, clang::FileID Value);
+  void appendArgument(const char *Name, FileID Value);
 
   /// \brief Append a FileEntry argument to the top trace item.
-  void appendArgument(const char *Name, const clang::FileEntry *Value);
+  void appendArgument(const char *Name, const FileEntry *Value);
 
   /// \brief Append a SourceLocation argument to the top trace item.
-  void appendArgument(const char *Name, clang::SourceLocation Value);
+  void appendArgument(const char *Name, SourceLocation Value);
 
   /// \brief Append a SourceRange argument to the top trace item.
-  void appendArgument(const char *Name, clang::SourceRange Value);
+  void appendArgument(const char *Name, SourceRange Value);
 
   /// \brief Append a CharSourceRange argument to the top trace item.
-  void appendArgument(const char *Name, clang::CharSourceRange Value);
+  void appendArgument(const char *Name, CharSourceRange Value);
 
   /// \brief Append a ModuleIdPath argument to the top trace item.
-  void appendArgument(const char *Name, clang::ModuleIdPath Value);
+  void appendArgument(const char *Name, ModuleIdPath Value);
 
   /// \brief Append an IdentifierInfo argument to the top trace item.
-  void appendArgument(const char *Name, const clang::IdentifierInfo *Value);
+  void appendArgument(const char *Name, const IdentifierInfo *Value);
 
   /// \brief Append a MacroDirective argument to the top trace item.
-  void appendArgument(const char *Name, const clang::MacroDirective *Value);
+  void appendArgument(const char *Name, const MacroDirective *Value);
 
   /// \brief Append a MacroDefinition argument to the top trace item.
-  void appendArgument(const char *Name, const clang::MacroDefinition &Value);
+  void appendArgument(const char *Name, const MacroDefinition &Value);
 
   /// \brief Append a MacroArgs argument to the top trace item.
-  void appendArgument(const char *Name, const clang::MacroArgs *Value);
+  void appendArgument(const char *Name, const MacroArgs *Value);
 
   /// \brief Append a Module argument to the top trace item.
-  void appendArgument(const char *Name, const clang::Module *Value);
+  void appendArgument(const char *Name, const Module *Value);
 
   /// \brief Append a double-quoted argument to the top trace item.
   void appendQuotedArgument(const char *Name, const std::string &Value);
@@ -230,20 +216,26 @@
   void appendFilePathArgument(const char *Name, llvm::StringRef Value);
 
   /// \brief Get the raw source string of the range.
-  llvm::StringRef getSourceString(clang::CharSourceRange Range);
+  llvm::StringRef getSourceString(CharSourceRange Range);
 
   /// \brief Callback trace information.
   /// We use a reference so the trace will be preserved for the caller
   /// after this object is destructed.
   std::vector<CallbackCall> &CallbackCalls;
 
-  /// \brief Names of callbacks to ignore.
-  llvm::SmallSet<std::string, 4> &Ignore;
+  // List of (Glob,Enabled) pairs used to filter callbacks.
+  const FilterType &Filters;
+
+  // Whether a callback should be printed.
+  llvm::StringMap<bool> CallbackIsEnabled;
 
   /// \brief Inhibit trace while this is set.
   bool DisableTrace;
 
-  clang::Preprocessor &PP;
+  Preprocessor &PP;
 };
 
+} // namespace pp_trace
+} // namespace clang
+
 #endif // PPTRACE_PPCALLBACKSTRACKER_H
diff --git a/pp-trace/PPTrace.cpp b/pp-trace/PPTrace.cpp
index 08e0f51..5155a8b 100644
--- a/pp-trace/PPTrace.cpp
+++ b/pp-trace/PPTrace.cpp
@@ -1,9 +1,8 @@
 //===--- tools/pp-trace/PPTrace.cpp - Clang preprocessor tracer -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -18,44 +17,22 @@
 //
 // The pp-trace tool supports the following general command line format:
 //
-//    pp-trace [pp-trace options] (source file) [compiler options]
+//    pp-trace [options] file... [-- compiler options]
 //
 // Basically you put the pp-trace options first, then the source file or files,
-// and then any options you want to pass to the compiler.
-//
-// These are the pp-trace options:
-//
-//    -ignore (callback list)     Don't display output for a comma-separated
-//                                list of callbacks, i.e.:
-//                                  -ignore "FileChanged,InclusionDirective"
-//
-//    -output (file)              Output trace to the given file in a YAML
-//                                format, e.g.:
-//
-//                                  ---
-//                                  - Callback: Name
-//                                    Argument1: Value1
-//                                    Argument2: Value2
-//                                  (etc.)
-//                                  ...
-//
-// Future Directions:
-//
-// 1. Add option opposite to "-ignore" that specifys a comma-separated option
-// list of callbacs.  Perhaps "-only" or "-exclusive".
+// and then -- followed by any options you want to pass to the compiler.
 //
 //===----------------------------------------------------------------------===//
 
 #include "PPCallbacksTracker.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Execution.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -63,168 +40,126 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/GlobPattern.h"
+#include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ToolOutputFile.h"
-#include <algorithm>
-#include <fstream>
-#include <iterator>
+#include "llvm/Support/WithColor.h"
 #include <string>
 #include <vector>
 
-using namespace clang;
-using namespace clang::tooling;
 using namespace llvm;
 
-// Options:
+namespace clang {
+namespace pp_trace {
 
-// Collect the source files.
-static cl::list<std::string> SourcePaths(cl::Positional,
-                                         cl::desc("<source0> [... <sourceN>]"),
-                                         cl::OneOrMore);
+static cl::OptionCategory Cat("pp-trace options");
 
-// Option to specify a list or one or more callback names to ignore.
-static cl::opt<std::string> IgnoreCallbacks(
-    "ignore", cl::init(""),
-    cl::desc("Ignore callbacks, i.e. \"Callback1, Callback2...\"."));
+static cl::opt<std::string> Callbacks(
+    "callbacks", cl::init("*"),
+    cl::desc("Comma-separated list of globs describing the list of callbacks "
+             "to output. Globs are processed in order of appearance. Globs "
+             "with the '-' prefix remove callbacks from the set. e.g. "
+             "'*,-Macro*'."),
+    cl::cat(Cat));
 
-// Option to specify the trace output file name.
 static cl::opt<std::string> OutputFileName(
-    "output", cl::init(""),
-    cl::desc("Output trace to the given file name or '-' for stdout."));
+    "output", cl::init("-"),
+    cl::desc("Output trace to the given file name or '-' for stdout."),
+    cl::cat(Cat));
 
-// Collect all other arguments, which will be passed to the front end.
-static cl::list<std::string>
-    CC1Arguments(cl::ConsumeAfter,
-                 cl::desc("<arguments to be passed to front end>..."));
-
-// Frontend action stuff:
-
-namespace {
-// Consumer is responsible for setting up the callbacks.
-class PPTraceConsumer : public ASTConsumer {
-public:
-  PPTraceConsumer(SmallSet<std::string, 4> &Ignore,
-                  std::vector<CallbackCall> &CallbackCalls, Preprocessor &PP) {
-    // PP takes ownership.
-    PP.addPPCallbacks(llvm::make_unique<PPCallbacksTracker>(Ignore,
-                                                            CallbackCalls, PP));
-  }
-};
-
-class PPTraceAction : public SyntaxOnlyAction {
-public:
-  PPTraceAction(SmallSet<std::string, 4> &Ignore,
-                std::vector<CallbackCall> &CallbackCalls)
-      : Ignore(Ignore), CallbackCalls(CallbackCalls) {}
-
-protected:
-  std::unique_ptr<clang::ASTConsumer>
-  CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
-    return llvm::make_unique<PPTraceConsumer>(Ignore, CallbackCalls,
-                                              CI.getPreprocessor());
-  }
-
-private:
-  SmallSet<std::string, 4> &Ignore;
-  std::vector<CallbackCall> &CallbackCalls;
-};
-
-class PPTraceFrontendActionFactory : public FrontendActionFactory {
-public:
-  PPTraceFrontendActionFactory(SmallSet<std::string, 4> &Ignore,
-                               std::vector<CallbackCall> &CallbackCalls)
-      : Ignore(Ignore), CallbackCalls(CallbackCalls) {}
-
-  PPTraceAction *create() override {
-    return new PPTraceAction(Ignore, CallbackCalls);
-  }
-
-private:
-  SmallSet<std::string, 4> &Ignore;
-  std::vector<CallbackCall> &CallbackCalls;
-};
-} // namespace
-
-// Output the trace given its data structure and a stream.
-static int outputPPTrace(std::vector<CallbackCall> &CallbackCalls,
-                         llvm::raw_ostream &OS) {
-  // Mark start of document.
-  OS << "---\n";
-
-  for (std::vector<CallbackCall>::const_iterator I = CallbackCalls.begin(),
-                                                 E = CallbackCalls.end();
-       I != E; ++I) {
-    const CallbackCall &Callback = *I;
-    OS << "- Callback: " << Callback.Name << "\n";
-
-    for (auto AI = Callback.Arguments.begin(), AE = Callback.Arguments.end();
-         AI != AE; ++AI) {
-      const Argument &Arg = *AI;
-      OS << "  " << Arg.Name << ": " << Arg.Value << "\n";
-    }
-  }
-
-  // Mark end of document.
-  OS << "...\n";
-
-  return 0;
+LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) {
+  WithColor::error() << Message << '\n';
+  exit(1);
 }
 
-// Program entry point.
-int main(int Argc, const char **Argv) {
+namespace {
 
-  // Parse command line.
-  cl::ParseCommandLineOptions(Argc, Argv, "pp-trace.\n");
+class PPTraceAction : public ASTFrontendAction {
+public:
+  PPTraceAction(const FilterType &Filters, raw_ostream &OS)
+      : Filters(Filters), OS(OS) {}
 
-  // Parse the IgnoreCallbacks list into strings.
-  SmallVector<StringRef, 32> IgnoreCallbacksStrings;
-  StringRef(IgnoreCallbacks).split(IgnoreCallbacksStrings, ",",
-                                   /*MaxSplit=*/ -1, /*KeepEmpty=*/false);
-  SmallSet<std::string, 4> Ignore;
-  for (SmallVector<StringRef, 32>::iterator I = IgnoreCallbacksStrings.begin(),
-                                            E = IgnoreCallbacksStrings.end();
-       I != E; ++I)
-    Ignore.insert(*I);
+protected:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override {
+    Preprocessor &PP = CI.getPreprocessor();
+    PP.addPPCallbacks(
+        llvm::make_unique<PPCallbacksTracker>(Filters, CallbackCalls, PP));
+    return llvm::make_unique<ASTConsumer>();
+  }
 
-  // Create the compilation database.
-  SmallString<256> PathBuf;
-  sys::fs::current_path(PathBuf);
-  std::unique_ptr<CompilationDatabase> Compilations;
-  Compilations.reset(
-      new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));
+  void EndSourceFileAction() override {
+    OS << "---\n";
+    for (const CallbackCall &Callback : CallbackCalls) {
+      OS << "- Callback: " << Callback.Name << "\n";
+      for (const Argument &Arg : Callback.Arguments)
+        OS << "  " << Arg.Name << ": " << Arg.Value << "\n";
+    }
+    OS << "...\n";
 
-  // Store the callback trace information here.
+    CallbackCalls.clear();
+  }
+
+private:
+  const FilterType &Filters;
+  raw_ostream &OS;
   std::vector<CallbackCall> CallbackCalls;
+};
+
+class PPTraceFrontendActionFactory : public tooling::FrontendActionFactory {
+public:
+  PPTraceFrontendActionFactory(const FilterType &Filters, raw_ostream &OS)
+      : Filters(Filters), OS(OS) {}
+
+  PPTraceAction *create() override { return new PPTraceAction(Filters, OS); }
+
+private:
+  const FilterType &Filters;
+  raw_ostream &OS;
+};
+} // namespace
+} // namespace pp_trace
+} // namespace clang
+
+int main(int argc, const char **argv) {
+  using namespace clang::pp_trace;
+  InitLLVM X(argc, argv);
+  auto OptionsParser = clang::tooling::CommonOptionsParser::create(
+      argc, argv, Cat, llvm::cl::ZeroOrMore);
+  if (!OptionsParser)
+    error(toString(OptionsParser.takeError()));
+  // Parse the IgnoreCallbacks list into strings.
+  SmallVector<StringRef, 32> Patterns;
+  FilterType Filters;
+  StringRef(Callbacks).split(Patterns, ",",
+                             /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  for (StringRef Pattern : Patterns) {
+    Pattern = Pattern.trim();
+    bool Enabled = !Pattern.consume_front("-");
+    Expected<GlobPattern> Pat = GlobPattern::create(Pattern);
+    if (Pat)
+      Filters.emplace_back(std::move(*Pat), Enabled);
+    else
+      error(toString(Pat.takeError()));
+  }
 
   // Create the tool and run the compilation.
-  ClangTool Tool(*Compilations, SourcePaths);
-  PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls);
+  clang::tooling::ClangTool Tool(OptionsParser->getCompilations(),
+                                 OptionsParser->getSourcePathList());
+
+  std::error_code EC;
+  llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text);
+  if (EC)
+    error(EC.message());
+  PPTraceFrontendActionFactory Factory(Filters, Out.os());
   int HadErrors = Tool.run(&Factory);
 
   // If we had errors, exit early.
   if (HadErrors)
     return HadErrors;
 
-  // Do the output.
-  if (!OutputFileName.size()) {
-    HadErrors = outputPPTrace(CallbackCalls, llvm::outs());
-  } else {
-    // Set up output file.
-    std::error_code EC;
-    llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text);
-    if (EC) {
-      llvm::errs() << "pp-trace: error creating " << OutputFileName << ":"
-                   << EC.message() << "\n";
-      return 1;
-    }
+  Out.keep();
 
-    HadErrors = outputPPTrace(CallbackCalls, Out.os());
-
-    // Tell ToolOutputFile that we want to keep the file.
-    if (HadErrors == 0)
-      Out.keep();
-  }
-
-  return HadErrors;
+  return 0;
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index adeb036..a2cedea 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -15,18 +15,20 @@
 
 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
 
-llvm_canonicalize_cmake_booleans(
-  CLANG_ENABLE_STATIC_ANALYZER
-  CLANGD_BUILD_XPC_SUPPORT)
+llvm_canonicalize_cmake_booleans(CLANG_ENABLE_STATIC_ANALYZER)
 
 configure_lit_site_cfg(
-  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
-  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
+  MAIN_CONFIG
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
   )
 
 configure_lit_site_cfg(
-  ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
-  ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
+  ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
+  ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
+  MAIN_CONFIG
+  ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
   )
 
 option(CLANG_TOOLS_TEST_USE_VG "Run Clang tools' tests under Valgrind" OFF)
@@ -59,39 +61,23 @@
   # For the clang-tidy libclang integration test.
   c-index-test
   # clang-tidy tests require it.
-  clang-headers
+  clang-resource-headers
 
   clang-tidy
+  # Clang-tidy tests need clang for building modules.
+  clang
 )
 
-if(CLANGD_BUILD_XPC_SUPPORT)
-  list(APPEND CLANG_TOOLS_TEST_DEPS clangd-xpc-test-client)
-endif()
-
-set(CLANGD_TEST_DEPS
-  clangd
-  ClangdTests
-  # clangd-related tools which don't have tests, add them to the test to make
-  # sure we don't introduce new changes that break their compilations.
-  clangd-indexer
-  dexp
-  )
-
 # Add lit test dependencies.
 set(LLVM_UTILS_DEPS
   FileCheck count not
 )
 foreach(dep ${LLVM_UTILS_DEPS})
   if(TARGET ${dep})
-    list(APPEND CLANGD_TEST_DEPS ${dep})
+    list(APPEND CLANG_TOOLS_TEST_DEPS ${dep})
   endif()
 endforeach()
 
-foreach(clangd_dep ${CLANGD_TEST_DEPS})
-  list(APPEND CLANG_TOOLS_TEST_DEPS
-       ${clangd_dep})
-endforeach()
-
 add_lit_testsuite(check-clang-tools "Running the Clang extra tools' regression tests"
   ${CMAKE_CURRENT_BINARY_DIR}
   DEPENDS ${CLANG_TOOLS_TEST_DEPS}
@@ -99,15 +85,3 @@
   )
 
 set_target_properties(check-clang-tools PROPERTIES FOLDER "Clang extra tools' tests")
-
-# Setup an individual test for building and testing clangd-only stuff.
-# Note: all clangd tests have been covered in check-clang-tools, this is a
-# convenient target for clangd developers.
-# Exclude check-clangd from check-all.
-set(EXCLUDE_FROM_ALL ON)
-add_lit_testsuite(check-clangd "Running the Clangd regression tests"
-  ${CMAKE_CURRENT_BINARY_DIR}/Unit/clangd;${CMAKE_CURRENT_BINARY_DIR}/clangd
-  DEPENDS ${CLANGD_TEST_DEPS}
-)
-set_target_properties(check-clangd PROPERTIES FOLDER "Clangd tests")
-set(EXCLUDE_FROM_ALL OFF)
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg.py
similarity index 100%
rename from test/Unit/lit.cfg
rename to test/Unit/lit.cfg.py
diff --git a/test/Unit/lit.site.cfg.in b/test/Unit/lit.site.cfg.py.in
similarity index 95%
rename from test/Unit/lit.site.cfg.in
rename to test/Unit/lit.site.cfg.py.in
index 69a5cd5..dc7ee33 100644
--- a/test/Unit/lit.site.cfg.in
+++ b/test/Unit/lit.site.cfg.py.in
@@ -6,4 +6,4 @@
 config.shlibdir = "@SHLIBDIR@"
 config.target_triple = "@TARGET_TRIPLE@"
 
-lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/Unit/lit.cfg")
+lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/Unit/lit.cfg.py")
diff --git a/test/clang-apply-replacements/Inputs/basic/file1.yaml b/test/clang-apply-replacements/Inputs/basic/file1.yaml
index 3a5375e..0703f62 100644
--- a/test/clang-apply-replacements/Inputs/basic/file1.yaml
+++ b/test/clang-apply-replacements/Inputs/basic/file1.yaml
@@ -2,24 +2,25 @@
 MainSourceFile:     source1.cpp
 Diagnostics:
   - DiagnosticName: test-basic
-    Message: Fix
-    FilePath: $(path)/basic.h
-    FileOffset: 242
-    Replacements:
-      - FilePath:        $(path)/basic.h
-        Offset:          242
-        Length:          26
-        ReplacementText: 'auto & elem : ints'
-      - FilePath:        $(path)/basic.h
-        Offset:          276
-        Length:          22
-        ReplacementText: ''
-      - FilePath:        $(path)/basic.h
-        Offset:          298
-        Length:          1
-        ReplacementText: elem
-      - FilePath:        $(path)/../basic/basic.h
-        Offset:          148
-        Length:          0
-        ReplacementText: 'override '
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/basic.h
+      FileOffset: 242
+      Replacements:
+        - FilePath:        $(path)/basic.h
+          Offset:          242
+          Length:          26
+          ReplacementText: 'auto & elem : ints'
+        - FilePath:        $(path)/basic.h
+          Offset:          276
+          Length:          22
+          ReplacementText: ''
+        - FilePath:        $(path)/basic.h
+          Offset:          298
+          Length:          1
+          ReplacementText: elem
+        - FilePath:        $(path)/../basic/basic.h
+          Offset:          148
+          Length:          0
+          ReplacementText: 'override '
 ...
diff --git a/test/clang-apply-replacements/Inputs/basic/file2.yaml b/test/clang-apply-replacements/Inputs/basic/file2.yaml
index 8f6f65a..de99d86 100644
--- a/test/clang-apply-replacements/Inputs/basic/file2.yaml
+++ b/test/clang-apply-replacements/Inputs/basic/file2.yaml
@@ -2,12 +2,13 @@
 MainSourceFile:     source2.cpp
 Diagnostics:
   - DiagnosticName: test-basic
-    Message: Fix
-    FilePath: $(path)/basic.h
-    FileOffset: 148
-    Replacements:
-      - FilePath:        $(path)/../basic/basic.h
-        Offset:          298
-        Length:          1
-        ReplacementText: elem
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/basic.h
+      FileOffset: 148
+      Replacements:
+        - FilePath:        $(path)/../basic/basic.h
+          Offset:          298
+          Length:          1
+          ReplacementText: elem
 ...
diff --git a/test/clang-apply-replacements/Inputs/conflict/file1.yaml b/test/clang-apply-replacements/Inputs/conflict/file1.yaml
index 8505273..8dccc56 100644
--- a/test/clang-apply-replacements/Inputs/conflict/file1.yaml
+++ b/test/clang-apply-replacements/Inputs/conflict/file1.yaml
@@ -2,20 +2,21 @@
 MainSourceFile: source1.cpp
 Diagnostics:
   - DiagnosticName: test-conflict
-    Message: Fix
-    FilePath: $(path)/common.h
-    FileOffset: 106
-    Replacements:
-      - FilePath:        $(path)/common.h
-        Offset:          106
-        Length:          26
-        ReplacementText: 'auto & i : ints'
-      - FilePath:        $(path)/common.h
-        Offset:          140
-        Length:          7
-        ReplacementText: i
-      - FilePath:        $(path)/common.h
-        Offset:          160
-        Length:          12
-        ReplacementText: ''
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/common.h
+      FileOffset: 106
+      Replacements:
+        - FilePath:        $(path)/common.h
+          Offset:          106
+          Length:          26
+          ReplacementText: 'auto & i : ints'
+        - FilePath:        $(path)/common.h
+          Offset:          140
+          Length:          7
+          ReplacementText: i
+        - FilePath:        $(path)/common.h
+          Offset:          160
+          Length:          12
+          ReplacementText: ''
 ...
diff --git a/test/clang-apply-replacements/Inputs/conflict/file2.yaml b/test/clang-apply-replacements/Inputs/conflict/file2.yaml
index 32b35ac..d733966 100644
--- a/test/clang-apply-replacements/Inputs/conflict/file2.yaml
+++ b/test/clang-apply-replacements/Inputs/conflict/file2.yaml
@@ -2,20 +2,21 @@
 MainSourceFile: source2.cpp
 Diagnostics:
   - DiagnosticName:  test-conflict
-    Message: Fix
-    FilePath: $(path)/common.h
-    FileOffset: 106
-    Replacements:
-      - FilePath:        $(path)/common.h
-        Offset:          106
-        Length:          26
-        ReplacementText: 'int & elem : ints'
-      - FilePath:        $(path)/common.h
-        Offset:          140
-        Length:          7
-        ReplacementText: elem
-      - FilePath:        $(path)/common.h
-        Offset:          169
-        Length:          1
-        ReplacementText: nullptr
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/common.h
+      FileOffset: 106
+      Replacements:
+        - FilePath:        $(path)/common.h
+          Offset:          106
+          Length:          26
+          ReplacementText: 'int & elem : ints'
+        - FilePath:        $(path)/common.h
+          Offset:          140
+          Length:          7
+          ReplacementText: elem
+        - FilePath:        $(path)/common.h
+          Offset:          169
+          Length:          1
+          ReplacementText: nullptr
 ...
diff --git a/test/clang-apply-replacements/Inputs/conflict/file3.yaml b/test/clang-apply-replacements/Inputs/conflict/file3.yaml
index 88543e0..fee1108 100644
--- a/test/clang-apply-replacements/Inputs/conflict/file3.yaml
+++ b/test/clang-apply-replacements/Inputs/conflict/file3.yaml
@@ -2,12 +2,13 @@
 MainSourceFile: source1.cpp
 Diagnostics:
   - DiagnosticName:  test-conflict
-    Message: Fix
-    FilePath: $(path)/common.h
-    FileOffset: 169
-    Replacements:
-      - FilePath:        $(path)/common.h
-        Offset:          169
-        Length:          0
-        ReplacementText: "(int*)"
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/common.h
+      FileOffset: 169
+      Replacements:
+        - FilePath:        $(path)/common.h
+          Offset:          169
+          Length:          0
+          ReplacementText: "(int*)"
 ...
diff --git a/test/clang-apply-replacements/Inputs/crlf/file1.yaml b/test/clang-apply-replacements/Inputs/crlf/file1.yaml
index 06b058e..2c3d56e 100644
--- a/test/clang-apply-replacements/Inputs/crlf/file1.yaml
+++ b/test/clang-apply-replacements/Inputs/crlf/file1.yaml
@@ -2,12 +2,13 @@
 MainSourceFile:      source1.cpp
 Diagnostics:
   - DiagnosticName:  test-crlf
-    Message: Fix
-    FilePath: $(path)/crlf.cpp
-    FileOffset: 79
-    Replacements:
-      - FilePath:        $(path)/crlf.cpp
-        Offset:          79
-        Length:          1
-        ReplacementText: nullptr
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/crlf.cpp
+      FileOffset: 79
+      Replacements:
+        - FilePath:        $(path)/crlf.cpp
+          Offset:          79
+          Length:          1
+          ReplacementText: nullptr
 ...
diff --git a/test/clang-apply-replacements/Inputs/format/no.yaml b/test/clang-apply-replacements/Inputs/format/no.yaml
index 3118cc6..48aafd9 100644
--- a/test/clang-apply-replacements/Inputs/format/no.yaml
+++ b/test/clang-apply-replacements/Inputs/format/no.yaml
@@ -2,12 +2,13 @@
 MainSourceFile:  no.cpp
 Diagnostics:
   - DiagnosticName:  test-no
-    Message: Fix
-    FilePath: $(path)/no.cpp
-    FileOffset: 94
-    Replacements:
-      - FilePath:        $(path)/no.cpp
-        Offset:          94
-        Length:          3
-        ReplacementText: 'auto '
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/no.cpp
+      FileOffset: 94
+      Replacements:
+        - FilePath:        $(path)/no.cpp
+          Offset:          94
+          Length:          3
+          ReplacementText: 'auto '
 ...
diff --git a/test/clang-apply-replacements/Inputs/format/yes.yaml b/test/clang-apply-replacements/Inputs/format/yes.yaml
index 6ded4db..337004d 100644
--- a/test/clang-apply-replacements/Inputs/format/yes.yaml
+++ b/test/clang-apply-replacements/Inputs/format/yes.yaml
@@ -4,24 +4,25 @@
 MainSourceFile:  yes.cpp
 Diagnostics:
   - DiagnosticName:  test-yes
-    Message: Fix
-    FilePath: $(path)/yes.cpp
-    FileOffset: 494
-    Replacements:
-      - FilePath:        $(path)/yes.cpp
-        Offset:          494
-        Length:          1
-        ReplacementText: nullptr
-      - FilePath:        $(path)/yes.cpp
-        Offset:          410
-        Length:          1
-        ReplacementText: nullptr
-      - FilePath:        $(path)/yes.cpp
-        Offset:          454
-        Length:          1
-        ReplacementText: nullptr
-      - FilePath:        $(path)/yes.cpp
-        Offset:          108
-        Length:          38
-        ReplacementText: 'auto '
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/yes.cpp
+      FileOffset: 494
+      Replacements:
+        - FilePath:        $(path)/yes.cpp
+          Offset:          494
+          Length:          1
+          ReplacementText: nullptr
+        - FilePath:        $(path)/yes.cpp
+          Offset:          410
+          Length:          1
+          ReplacementText: nullptr
+        - FilePath:        $(path)/yes.cpp
+          Offset:          454
+          Length:          1
+          ReplacementText: nullptr
+        - FilePath:        $(path)/yes.cpp
+          Offset:          108
+          Length:          38
+          ReplacementText: 'auto '
 ...
diff --git a/test/clang-apply-replacements/Inputs/identical/file1.yaml b/test/clang-apply-replacements/Inputs/identical/file1.yaml
index cf273c4..9e3de7b 100644
--- a/test/clang-apply-replacements/Inputs/identical/file1.yaml
+++ b/test/clang-apply-replacements/Inputs/identical/file1.yaml
@@ -2,13 +2,14 @@
 MainSourceFile:     identical.cpp
 Diagnostics:
   - DiagnosticName: test-identical-insertion
-    Message: Fix
-    FilePath: $(path)/identical.cpp
-    FileOffset: 12
-    Replacements:
-      - FilePath:        $(path)/identical.cpp
-        Offset:          12
-        Length:          0
-        ReplacementText: '0'
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/identical.cpp
+      FileOffset: 12
+      Replacements:
+        - FilePath:        $(path)/identical.cpp
+          Offset:          12
+          Length:          0
+          ReplacementText: '0'
 ...
 
diff --git a/test/clang-apply-replacements/Inputs/identical/file2.yaml b/test/clang-apply-replacements/Inputs/identical/file2.yaml
index cf273c4..9e3de7b 100644
--- a/test/clang-apply-replacements/Inputs/identical/file2.yaml
+++ b/test/clang-apply-replacements/Inputs/identical/file2.yaml
@@ -2,13 +2,14 @@
 MainSourceFile:     identical.cpp
 Diagnostics:
   - DiagnosticName: test-identical-insertion
-    Message: Fix
-    FilePath: $(path)/identical.cpp
-    FileOffset: 12
-    Replacements:
-      - FilePath:        $(path)/identical.cpp
-        Offset:          12
-        Length:          0
-        ReplacementText: '0'
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/identical.cpp
+      FileOffset: 12
+      Replacements:
+        - FilePath:        $(path)/identical.cpp
+          Offset:          12
+          Length:          0
+          ReplacementText: '0'
 ...
 
diff --git a/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml b/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml
index a823438..939839d 100644
--- a/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml
+++ b/test/clang-apply-replacements/Inputs/order-dependent/file1.yaml
@@ -2,12 +2,13 @@
 MainSourceFile:     order-dependent.cpp
 Diagnostics:
   - DiagnosticName: test-order-dependent-insertion
-    Message: Fix
-    FilePath: $(path)/order-dependent.cpp
-    FileOffset: 12
-    Replacements:
-      - FilePath:        $(path)/order-dependent.cpp
-        Offset:          12
-        Length:          0
-        ReplacementText: '0'
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/order-dependent.cpp
+      FileOffset: 12
+      Replacements:
+        - FilePath:        $(path)/order-dependent.cpp
+          Offset:          12
+          Length:          0
+          ReplacementText: '0'
 ...
diff --git a/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml b/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml
index 634d3ca..1219c3b 100644
--- a/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml
+++ b/test/clang-apply-replacements/Inputs/order-dependent/file2.yaml
@@ -2,12 +2,13 @@
 MainSourceFile:     order-dependent.cpp
 Diagnostics:
   - DiagnosticName: test-order-dependent-insertion
-    Message: Fix
-    FilePath: $(path)/order-dependent.cpp
-    FileOffset: 12
-    Replacements:
-      - FilePath:        $(path)/order-dependent.cpp
-        Offset:          12
-        Length:          0
-        ReplacementText: '1'
+    DiagnosticMessage:
+      Message: Fix
+      FilePath: $(path)/order-dependent.cpp
+      FileOffset: 12
+      Replacements:
+        - FilePath:        $(path)/order-dependent.cpp
+          Offset:          12
+          Length:          0
+          ReplacementText: '1'
 ...
diff --git a/test/change-namespace/Inputs/fake-std.h b/test/clang-change-namespace/Inputs/fake-std.h
similarity index 100%
rename from test/change-namespace/Inputs/fake-std.h
rename to test/clang-change-namespace/Inputs/fake-std.h
diff --git a/test/change-namespace/lambda-function.cpp b/test/clang-change-namespace/lambda-function.cpp
similarity index 100%
rename from test/change-namespace/lambda-function.cpp
rename to test/clang-change-namespace/lambda-function.cpp
diff --git a/test/change-namespace/macro.cpp b/test/clang-change-namespace/macro.cpp
similarity index 100%
rename from test/change-namespace/macro.cpp
rename to test/clang-change-namespace/macro.cpp
diff --git a/test/change-namespace/simple-move.cpp b/test/clang-change-namespace/simple-move.cpp
similarity index 100%
rename from test/change-namespace/simple-move.cpp
rename to test/clang-change-namespace/simple-move.cpp
diff --git a/test/change-namespace/white-list.cpp b/test/clang-change-namespace/white-list.cpp
similarity index 100%
rename from test/change-namespace/white-list.cpp
rename to test/clang-change-namespace/white-list.cpp
diff --git a/test/include-fixer/Inputs/database_template.json b/test/clang-include-fixer/Inputs/database_template.json
similarity index 100%
rename from test/include-fixer/Inputs/database_template.json
rename to test/clang-include-fixer/Inputs/database_template.json
diff --git a/test/include-fixer/Inputs/fake_yaml_db.yaml b/test/clang-include-fixer/Inputs/fake_yaml_db.yaml
similarity index 96%
rename from test/include-fixer/Inputs/fake_yaml_db.yaml
rename to test/clang-include-fixer/Inputs/fake_yaml_db.yaml
index b599005..134b375 100644
--- a/test/include-fixer/Inputs/fake_yaml_db.yaml
+++ b/test/clang-include-fixer/Inputs/fake_yaml_db.yaml
@@ -65,7 +65,7 @@
 Contexts:
   - ContextType:    Namespace
     ContextName:    c
-FilePath:        test/include-fixer/baz.h
+FilePath:        test/clang-include-fixer/baz.h
 Type:            Class
 Seen:            1
 Used:            0
diff --git a/test/include-fixer/Inputs/merge/a.yaml b/test/clang-include-fixer/Inputs/merge/a.yaml
similarity index 100%
rename from test/include-fixer/Inputs/merge/a.yaml
rename to test/clang-include-fixer/Inputs/merge/a.yaml
diff --git a/test/include-fixer/Inputs/merge/b.yaml b/test/clang-include-fixer/Inputs/merge/b.yaml
similarity index 100%
rename from test/include-fixer/Inputs/merge/b.yaml
rename to test/clang-include-fixer/Inputs/merge/b.yaml
diff --git a/test/include-fixer/commandline_options.cpp b/test/clang-include-fixer/commandline_options.cpp
similarity index 100%
rename from test/include-fixer/commandline_options.cpp
rename to test/clang-include-fixer/commandline_options.cpp
diff --git a/test/include-fixer/exit_on_fatal.cpp b/test/clang-include-fixer/exit_on_fatal.cpp
similarity index 100%
rename from test/include-fixer/exit_on_fatal.cpp
rename to test/clang-include-fixer/exit_on_fatal.cpp
diff --git a/test/include-fixer/fixeddb.cpp b/test/clang-include-fixer/fixeddb.cpp
similarity index 100%
rename from test/include-fixer/fixeddb.cpp
rename to test/clang-include-fixer/fixeddb.cpp
diff --git a/test/clang-include-fixer/include_path.cpp b/test/clang-include-fixer/include_path.cpp
new file mode 100644
index 0000000..9185b7a
--- /dev/null
+++ b/test/clang-include-fixer/include_path.cpp
@@ -0,0 +1,19 @@
+// RUN: mkdir -p %T/clang-include-fixer/include
+// RUN: mkdir -p %T/clang-include-fixer/symbols
+// RUN: mkdir -p %T/clang-include-fixer/build
+// RUN: mkdir -p %T/clang-include-fixer/src
+// RUN: sed 's|test_dir|%/T/clang-include-fixer|g' %S/Inputs/database_template.json > %T/clang-include-fixer/build/compile_commands.json
+// RUN: echo -e '#include "bar.h"\nb::a::bar f;' > %T/clang-include-fixer/src/bar.cpp
+// RUN: echo 'namespace b { namespace a { class bar {}; } }' > %T/clang-include-fixer/include/bar.h
+// RUN: cd %T/clang-include-fixer/build
+// RUN: find-all-symbols -output-dir=%T/clang-include-fixer/symbols -p=. %T/clang-include-fixer/src/bar.cpp
+// RUN: find-all-symbols -merge-dir=%T/clang-include-fixer/symbols %T/clang-include-fixer/build/find_all_symbols.yaml
+// RUN: FileCheck -input-file=%T/clang-include-fixer/build/find_all_symbols.yaml -check-prefix=CHECK-YAML %s
+//
+// RUN: echo 'b::a::bar f;' > %T/clang-include-fixer/src/bar.cpp
+// RUN: clang-include-fixer -db=yaml -input=%T/clang-include-fixer/build/find_all_symbols.yaml -minimize-paths=true -p=. %T/clang-include-fixer/src/bar.cpp
+// RUN: FileCheck -input-file=%T/clang-include-fixer/src/bar.cpp %s
+
+// CHECK-YAML: ..{{[/\\]}}include{{[/\\]}}bar.h
+// CHECK: #include "bar.h"
+// CHECK: b::a::bar f;
diff --git a/test/include-fixer/merge.test b/test/clang-include-fixer/merge.test
similarity index 100%
rename from test/include-fixer/merge.test
rename to test/clang-include-fixer/merge.test
diff --git a/test/clang-include-fixer/multiple_fixes.cpp b/test/clang-include-fixer/multiple_fixes.cpp
new file mode 100644
index 0000000..791417a
--- /dev/null
+++ b/test/clang-include-fixer/multiple_fixes.cpp
@@ -0,0 +1,13 @@
+// REQUIRES: shell
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: mkdir -p %T/clang-include-fixer/multiple-fixes
+// RUN: echo 'foo f;' > %T/clang-include-fixer/multiple-fixes/foo.cpp
+// RUN: echo 'bar b;' > %T/clang-include-fixer/multiple-fixes/bar.cpp
+// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h";bar= "bar.h"' %T/clang-include-fixer/multiple-fixes/*.cpp --
+// RUN: FileCheck -input-file=%T/clang-include-fixer/multiple-fixes/bar.cpp %s -check-prefix=CHECK-BAR
+// RUN: FileCheck -input-file=%T/clang-include-fixer/multiple-fixes/foo.cpp %s -check-prefix=CHECK-FOO
+//
+// CHECK-FOO: #include "foo.h"
+// CHECK-FOO: foo f;
+// CHECK-BAR: #include "bar.h"
+// CHECK-BAR: bar b;
diff --git a/test/include-fixer/prefix_variable.cpp b/test/clang-include-fixer/prefix_variable.cpp
similarity index 100%
rename from test/include-fixer/prefix_variable.cpp
rename to test/clang-include-fixer/prefix_variable.cpp
diff --git a/test/include-fixer/query_symbol.cpp b/test/clang-include-fixer/query_symbol.cpp
similarity index 100%
rename from test/include-fixer/query_symbol.cpp
rename to test/clang-include-fixer/query_symbol.cpp
diff --git a/test/include-fixer/ranking.cpp b/test/clang-include-fixer/ranking.cpp
similarity index 88%
rename from test/include-fixer/ranking.cpp
rename to test/clang-include-fixer/ranking.cpp
index 2dabe16..ee54d4c 100644
--- a/test/include-fixer/ranking.cpp
+++ b/test/clang-include-fixer/ranking.cpp
@@ -2,7 +2,7 @@
 // RUN: clang-include-fixer -query-symbol bar -db=yaml -input=%S/Inputs/fake_yaml_db.yaml -output-headers %s -- | FileCheck %s
 
 // CHECK:     "HeaderInfos": [
-// CHECK-NEXT:  {"Header": "\"test/include-fixer/baz.h\"",
+// CHECK-NEXT:  {"Header": "\"test/clang-include-fixer/baz.h\"",
 // CHECK-NEXT:   "QualifiedName": "c::bar"},
 // CHECK-NEXT:  {"Header": "\"../include/bar.h\"",
 // CHECK-NEXT:   "QualifiedName": "b::a::bar"},
diff --git a/test/include-fixer/yaml_fuzzy.cpp b/test/clang-include-fixer/yaml_fuzzy.cpp
similarity index 74%
rename from test/include-fixer/yaml_fuzzy.cpp
rename to test/clang-include-fixer/yaml_fuzzy.cpp
index 705542d..9a3daac 100644
--- a/test/include-fixer/yaml_fuzzy.cpp
+++ b/test/clang-include-fixer/yaml_fuzzy.cpp
@@ -2,7 +2,7 @@
 // RUN: clang-include-fixer -db=fuzzyYaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp --
 // RUN: FileCheck %s -input-file=%t.cpp
 
-// include-fixer will add the include, but doesn't complete the symbol.
+// clang-include-fixer will add the include, but doesn't complete the symbol.
 // CHECK: #include "foobar.h"
 // CHECK: fba f;
 
diff --git a/test/include-fixer/yamldb.cpp b/test/clang-include-fixer/yamldb.cpp
similarity index 100%
rename from test/include-fixer/yamldb.cpp
rename to test/clang-include-fixer/yamldb.cpp
diff --git a/test/include-fixer/yamldb_autodetect.cpp b/test/clang-include-fixer/yamldb_autodetect.cpp
similarity index 100%
rename from test/include-fixer/yamldb_autodetect.cpp
rename to test/clang-include-fixer/yamldb_autodetect.cpp
diff --git a/test/clang-tidy/Inputs/Headers/stdio.h b/test/clang-tidy/Inputs/Headers/stdio.h
new file mode 100644
index 0000000..eebe9fd
--- /dev/null
+++ b/test/clang-tidy/Inputs/Headers/stdio.h
@@ -0,0 +1,18 @@
+//===--- stdio.h - Stub header for tests ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+// A header intended to contain C standard input and output library
+// declarations.
+
+int printf(const char *, ...);
+
+#endif // _STDIO_H_
+
diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h
index 9d136a5..5454f97 100644
--- a/test/clang-tidy/Inputs/absl/time/time.h
+++ b/test/clang-tidy/Inputs/absl/time/time.h
@@ -14,11 +14,14 @@
   Duration &operator/=(float r);
   Duration &operator/=(double r);
   template <typename T> Duration &operator/=(T r);
+
+  Duration &operator+(Duration d);
 };
 
 template <typename T> Duration operator*(Duration lhs, T rhs);
 template <typename T> Duration operator*(T lhs, Duration rhs);
 template <typename T> Duration operator/(Duration lhs, T rhs);
+int64_t operator/(Duration lhs, Duration rhs);
 
 class Time{};
 
@@ -55,6 +58,21 @@
 int64_t ToInt64Microseconds(Duration d);
 int64_t ToInt64Nanoseconds(Duration d);
 
+int64_t ToUnixHours(Time t);
+int64_t ToUnixMinutes(Time t);
+int64_t ToUnixSeconds(Time t);
+int64_t ToUnixMillis(Time t);
+int64_t ToUnixMicros(Time t);
+int64_t ToUnixNanos(Time t);
+Time FromUnixHours(int64_t);
+Time FromUnixMinutes(int64_t);
+Time FromUnixSeconds(int64_t);
+Time FromUnixMillis(int64_t);
+Time FromUnixMicros(int64_t);
+Time FromUnixNanos(int64_t);
+
+Time Now();
+
 // Relational Operators
 constexpr bool operator<(Duration lhs, Duration rhs);
 constexpr bool operator>(Duration lhs, Duration rhs);
@@ -69,4 +87,6 @@
 inline Time operator-(Time lhs, Duration rhs);
 inline Duration operator-(Time lhs, Time rhs);
 
+double FDivDuration(Duration num, Duration den);
+
 }  // namespace absl
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h
new file mode 100644
index 0000000..6651b4f
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/a.h
@@ -0,0 +1 @@
+#define a
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h
new file mode 100644
index 0000000..446eda1
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/b.h
@@ -0,0 +1,2 @@
+#include "a.h"
+#define b
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h
new file mode 100644
index 0000000..0d4c60d
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/c.h
@@ -0,0 +1,2 @@
+#include "b.h"
+#define c
diff --git a/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap
new file mode 100644
index 0000000..d04240a
--- /dev/null
+++ b/test/clang-tidy/Inputs/expand-modular-headers-ppcallbacks/module.modulemap
@@ -0,0 +1,3 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * use a }
+module c { header "c.h" export * use b }
diff --git a/test/clang-tidy/abseil-duration-addition.cpp b/test/clang-tidy/abseil-duration-addition.cpp
new file mode 100644
index 0000000..33cfc58
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Time t;
+  int i;
+
+  i = absl::ToUnixHours(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+  i = absl::ToUnixMinutes(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+  i = absl::ToUnixSeconds(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+  i = absl::ToUnixMillis(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+  i = absl::ToUnixMicros(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+  i = absl::ToUnixNanos(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+  i = 3 + absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+  i = 3 + absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+  i = 3 + absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+  i = 3 + absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+  i = 3 + absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+  // Parens
+  i = 3 + (absl::ToUnixHours(t));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+
+  // Float folding
+  i = absl::ToUnixSeconds(t) + 5.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+  // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+  i = absl::ToUnixSeconds(THIRTY) + 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+  // Some other contexts
+  if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+  // These should not match
+  i = 5 + 6;
+  i = absl::ToUnixSeconds(t) - 1.0;
+  i = absl::ToUnixSeconds(t) * 1.0;
+  i = absl::ToUnixSeconds(t) / 1.0;
+  i += absl::ToInt64Microseconds(absl::Seconds(1));
+
+#define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5
+  i = PLUS_FIVE(t);
+#undef PLUS_FIVE
+}
+
+// Within a templated function
+template<typename T>
+void foo(absl::Time t) {
+  int i = absl::ToUnixNanos(t) + T{};
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{}))
+}
+
+void g() {
+  absl::Time t;
+  foo<int>(t);
+  foo<double>(t);
+}
diff --git a/test/clang-tidy/abseil-duration-conversion-cast.cpp b/test/clang-tidy/abseil-duration-conversion-cast.cpp
new file mode 100644
index 0000000..260aa32
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-conversion-cast.cpp
@@ -0,0 +1,95 @@
+// RUN: %check_clang_tidy %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Duration d1;
+  double x;
+  int i;
+
+  i = static_cast<int>(absl::ToDoubleHours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Hours(d1);
+  x = static_cast<float>(absl::ToInt64Hours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleHours(d1);
+  i = static_cast<int>(absl::ToDoubleMinutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Minutes(d1);
+  x = static_cast<float>(absl::ToInt64Minutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMinutes(d1);
+  i = static_cast<int>(absl::ToDoubleSeconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Seconds(d1);
+  x = static_cast<float>(absl::ToInt64Seconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleSeconds(d1);
+  i = static_cast<int>(absl::ToDoubleMilliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Milliseconds(d1);
+  x = static_cast<float>(absl::ToInt64Milliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMilliseconds(d1);
+  i = static_cast<int>(absl::ToDoubleMicroseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Microseconds(d1);
+  x = static_cast<float>(absl::ToInt64Microseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+  i = static_cast<int>(absl::ToDoubleNanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Nanoseconds(d1);
+  x = static_cast<float>(absl::ToInt64Nanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleNanoseconds(d1);
+
+  // Functional-style casts
+  i = int(absl::ToDoubleHours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Hours(d1);
+  x = float(absl::ToInt64Microseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+  // C-style casts
+  i = (int) absl::ToDoubleHours(d1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Hours(d1);
+  x = (float) absl::ToInt64Microseconds(d1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+  // Type aliasing
+  typedef int FancyInt;
+  typedef float FancyFloat;
+
+  FancyInt j = static_cast<FancyInt>(absl::ToDoubleHours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToInt64Hours(d1);
+  FancyFloat k = static_cast<FancyFloat>(absl::ToInt64Microseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: absl::ToDoubleMicroseconds(d1);
+
+  // Macro handling
+  // We want to transform things in macro arguments
+#define EXTERNAL(x) (x) + 5
+  i = EXTERNAL(static_cast<int>(absl::ToDoubleSeconds(d1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast]
+  // CHECK-FIXES: EXTERNAL(absl::ToInt64Seconds(d1));
+#undef EXTERNAL
+
+  // We don't want to transform this which get split across macro boundaries
+#define SPLIT(x) static_cast<int>((x)) + 5
+  i = SPLIT(absl::ToDoubleSeconds(d1));
+#undef SPLIT
+
+  // We also don't want to transform things inside of a macro definition
+#define INTERNAL(x) static_cast<int>(absl::ToDoubleSeconds((x))) + 5
+  i = INTERNAL(d1);
+#undef INTERNAL
+
+  // These shouldn't be converted
+  i = static_cast<int>(absl::ToInt64Seconds(d1));
+  i = static_cast<float>(absl::ToDoubleSeconds(d1));
+}
diff --git a/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
new file mode 100644
index 0000000..d32837f
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s abseil-duration-unnecessary-conversion %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Duration d1, d2;
+
+  // Floating point
+  d2 = absl::Hours(absl::ToDoubleHours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Minutes(absl::ToDoubleMinutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Seconds(absl::ToDoubleSeconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+
+  // Integer point
+  d2 = absl::Hours(absl::ToInt64Hours(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Minutes(absl::ToInt64Minutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Seconds(absl::ToInt64Seconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Microseconds(absl::ToInt64Microseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+
+  d2 = absl::Hours(d1 / absl::Hours(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Minutes(d1 / absl::Minutes(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Seconds(d1 / absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Milliseconds(d1 / absl::Milliseconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Microseconds(d1 / absl::Microseconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Nanoseconds(d1 / absl::Nanoseconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+
+  d2 = absl::Hours(absl::FDivDuration(d1, absl::Hours(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Minutes(absl::FDivDuration(d1, absl::Minutes(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Microseconds(absl::FDivDuration(d1, absl::Microseconds(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+  d2 = absl::Nanoseconds(absl::FDivDuration(d1, absl::Nanoseconds(1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d2 = d1
+
+  // As macro argument
+#define PLUS_FIVE_S(x) x + absl::Seconds(5)
+  d2 = PLUS_FIVE_S(absl::Seconds(absl::ToInt64Seconds(d1)));
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: PLUS_FIVE_S(d1)
+#undef PLUS_FIVE_S
+
+  // Split by macro: should not change
+#define TOSECONDS(x) absl::Seconds(x)
+  d2 = TOSECONDS(absl::ToInt64Seconds(d1));
+#undef TOSECONDS
+
+  // Don't change something inside a macro definition
+#define VALUE(x) absl::Hours(absl::ToInt64Hours(x));
+  d2 = VALUE(d1);
+#undef VALUE
+
+  // These should not match
+  d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1));
+  d2 = absl::Seconds(4);
+  int i = absl::ToInt64Milliseconds(d1);
+  d2 = absl::Hours(d1 / absl::Minutes(1));
+  d2 = absl::Seconds(d1 / absl::Seconds(30));
+  d2 = absl::Hours(absl::FDivDuration(d1, absl::Minutes(1)));
+  d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(20)));
+}
diff --git a/test/clang-tidy/abseil-time-comparison.cpp b/test/clang-tidy/abseil-time-comparison.cpp
new file mode 100644
index 0000000..ab03020
--- /dev/null
+++ b/test/clang-tidy/abseil-time-comparison.cpp
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy %s abseil-time-comparison %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  double x;
+  absl::Duration d1, d2;
+  bool b;
+  absl::Time t1, t2;
+
+  // Check against the RHS
+  b = x > absl::ToUnixSeconds(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) > t1;
+  b = x >= absl::ToUnixSeconds(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) >= t1;
+  b = x == absl::ToUnixSeconds(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) == t1;
+  b = x <= absl::ToUnixSeconds(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) <= t1;
+  b = x < absl::ToUnixSeconds(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) < t1;
+  b = x == absl::ToUnixSeconds(t1 - d2);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixSeconds(x) == t1 - d2;
+  b = absl::ToUnixSeconds(t1) > absl::ToUnixSeconds(t2);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 > t2;
+
+  // Check against the LHS
+  b = absl::ToUnixSeconds(t1) < x;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 < absl::FromUnixSeconds(x);
+  b = absl::ToUnixSeconds(t1) <= x;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 <= absl::FromUnixSeconds(x);
+  b = absl::ToUnixSeconds(t1) == x;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 == absl::FromUnixSeconds(x);
+  b = absl::ToUnixSeconds(t1) >= x;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 >= absl::FromUnixSeconds(x);
+  b = absl::ToUnixSeconds(t1) > x;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 > absl::FromUnixSeconds(x);
+
+  // Comparison against zero
+  b = absl::ToUnixSeconds(t1) < 0.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 < absl::UnixEpoch();
+  b = absl::ToUnixSeconds(t1) < 0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: t1 < absl::UnixEpoch();
+
+  // Scales other than Seconds
+  b = x > absl::ToUnixMicros(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixMicros(x) > t1;
+  b = x >= absl::ToUnixMillis(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixMillis(x) >= t1;
+  b = x == absl::ToUnixNanos(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixNanos(x) == t1;
+  b = x <= absl::ToUnixMinutes(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixMinutes(x) <= t1;
+  b = x < absl::ToUnixHours(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixHours(x) < t1;
+
+  // A long expression
+  bool some_condition;
+  int very_very_very_very_long_variable_name;
+  absl::Time SomeTime;
+  if (some_condition && very_very_very_very_long_variable_name
+     < absl::ToUnixSeconds(SomeTime)) {
+  // CHECK-MESSAGES: [[@LINE-2]]:25: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: if (some_condition && absl::FromUnixSeconds(very_very_very_very_long_variable_name) < SomeTime) {
+    return;
+  }
+
+  // A complex expression
+  int y;
+  b = (y + 5) * 10 > absl::ToUnixMillis(t1);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: absl::FromUnixMillis((y + 5) * 10) > t1;
+
+  // We should still transform the expression inside this macro invocation
+#define VALUE_IF(v, e) v ? (e) : 0
+  int a = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1));
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+#undef VALUE_IF
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0)
+  int a2 = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1));
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the time domain [abseil-time-comparison]
+  // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e, type) (v ? VALUE_IF_2(absl::To##type##Seconds(e)) : 0)
+  int a3 = VALUE_IF(1, t1, Unix);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+#define VALUE_IF_2(e) (e)
+#define VALUE_IF(v, e, type) (v ? (5 > VALUE_IF_2(absl::To##type##Seconds(e))) : 0)
+  int a4 = VALUE_IF(1, t1, Unix);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
+  // These should not match
+  b = 6 < 4;
+
+#define TODOUBLE(x) absl::ToUnixSeconds(x)
+  b = 5.0 > TODOUBLE(t1);
+#undef TODOUBLE
+#define THIRTY 30.0
+  b = THIRTY > absl::ToUnixSeconds(t1);
+#undef THIRTY
+}
diff --git a/test/clang-tidy/abseil-time-subtraction.cpp b/test/clang-tidy/abseil-time-subtraction.cpp
new file mode 100644
index 0000000..6f5d4b4
--- /dev/null
+++ b/test/clang-tidy/abseil-time-subtraction.cpp
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s abseil-time-subtraction %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void g(absl::Duration d);
+
+void f() {
+  absl::Time t;
+  int x, y;
+  absl::Duration d;
+
+  d = absl::Hours(absl::ToUnixHours(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixHours(x));
+  d = absl::Minutes(absl::ToUnixMinutes(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixMinutes(x));
+  d = absl::Seconds(absl::ToUnixSeconds(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x));
+  d = absl::Milliseconds(absl::ToUnixMillis(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixMillis(x));
+  d = absl::Microseconds(absl::ToUnixMicros(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixMicros(x));
+  d = absl::Nanoseconds(absl::ToUnixNanos(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixNanos(x));
+
+  y = x - absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Hours(absl::FromUnixHours(x) - t);
+  y = x - absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Minutes(absl::FromUnixMinutes(x) - t);
+  y = x - absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t);
+  y = x - absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Milliseconds(absl::FromUnixMillis(x) - t);
+  y = x - absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Microseconds(absl::FromUnixMicros(x) - t);
+  y = x - absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: y = absl::ToInt64Nanoseconds(absl::FromUnixNanos(x) - t);
+
+  // Check parenthesis placement
+  d = 5 * absl::Seconds(absl::ToUnixSeconds(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = 5 * (t - absl::FromUnixSeconds(x));
+  d = absl::Seconds(absl::ToUnixSeconds(t) - x) / 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)) / 5;
+
+  // No extra parens around arguments
+  g(absl::Seconds(absl::ToUnixSeconds(t) - x));
+  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: g(t - absl::FromUnixSeconds(x));
+  g(absl::Seconds(x - absl::ToUnixSeconds(t)));
+  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: g(absl::FromUnixSeconds(x) - t);
+
+  // More complex subexpressions
+  d = absl::Hours(absl::ToUnixHours(t) - 5 * x);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: d = (t - absl::FromUnixHours(5 * x));
+
+  // These should not trigger; they are likely bugs
+  d = absl::Milliseconds(absl::ToUnixSeconds(t) - x);
+  d = absl::Seconds(absl::ToUnixMicros(t) - x);
+
+  // Various macro scenarios
+#define SUB(z, t1) z - absl::ToUnixSeconds(t1)
+  y = SUB(x, t);
+#undef SUB
+
+#define MILLIS(t1) absl::ToUnixMillis(t1)
+  y = x - MILLIS(t);
+#undef MILLIS
+
+#define HOURS(z) absl::Hours(z)
+  d = HOURS(absl::ToUnixHours(t) - x);
+#undef HOURS
+
+  // This should match the expression inside the macro invocation.
+#define SECONDS(z) absl::Seconds(z)
+  d = SECONDS(x - absl::ToUnixSeconds(t));
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t))
+#undef SECONDS
+}
+
+template<typename T>
+void func(absl::Time t, T x) {
+  absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: absl::Duration d = t - absl::FromUnixSeconds(x);
+}
+
+void g() {
+  func(absl::Now(), 5);
+}
+
+absl::Duration parens_in_return() {
+  absl::Time t;
+  int x;
+
+  return absl::Seconds(absl::ToUnixSeconds(t) - x);
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: return t - absl::FromUnixSeconds(x);
+  return absl::Seconds(x - absl::ToUnixSeconds(t));
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
+  // CHECK-FIXES: return absl::FromUnixSeconds(x) - t;
+}
diff --git a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
index 7d8ad43..fed0f8b 100644
--- a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
+++ b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
@@ -430,3 +430,36 @@
   factoryTemplateAndMacro<ConvertibleTo<int>>();
   TemplateFactoryInMacro(ConvertibleTo<int>());
 }
+
+// This is a reduced test-case for PR39949 and manifested in this check.
+namespace std {
+template <typename _Tp>
+_Tp declval();
+
+template <typename _Functor, typename... _ArgTypes>
+struct __res {
+  template <typename... _Args>
+  static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
+
+  template <typename...>
+  static void _S_test(...);
+
+  typedef decltype(_S_test<_ArgTypes...>(0)) type;
+};
+
+template <typename>
+struct function;
+
+template <typename... _ArgTypes>
+struct function<void(_ArgTypes...)> {
+  template <typename _Functor,
+            typename = typename __res<_Functor, _ArgTypes...>::type>
+  function(_Functor) {}
+};
+} // namespace std
+
+typedef std::function<void(void)> F;
+
+F foo() {
+  return F([] {});
+}
diff --git a/test/clang-tidy/alternative-fixes.cpp b/test/clang-tidy/alternative-fixes.cpp
new file mode 100644
index 0000000..d5cee68
--- /dev/null
+++ b/test/clang-tidy/alternative-fixes.cpp
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s "llvm-namespace-comment,clang-diagnostic-*" %t
+void foo(int a) {
+  if (a = 1) {
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: using the result of an assignment as a condition without parentheses [clang-diagnostic-parentheses]
+  // CHECK-NOTES: [[@LINE-2]]:9: note: place parentheses around the assignment to silence this warning
+  // CHECK-NOTES: [[@LINE-3]]:9: note: use '==' to turn this assignment into an equality comparison
+  // CHECK-FIXES: if ((a = 1)) {
+  }
+}
diff --git a/test/clang-tidy/bugprone-argument-comment-literals.cpp b/test/clang-tidy/bugprone-argument-comment-literals.cpp
new file mode 100644
index 0000000..739c9a5
--- /dev/null
+++ b/test/clang-tidy/bugprone-argument-comment-literals.cpp
@@ -0,0 +1,124 @@
+// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \
+// RUN:   -config="{CheckOptions: [{key: CommentBoolLiterals, value: 1},{key: CommentIntegerLiterals, value: 1}, {key: CommentFloatLiterals, value: 1}, {key: CommentUserDefinedLiterals, value: 1}, {key: CommentStringLiterals, value: 1}, {key: CommentNullPtrs, value: 1}, {key: CommentCharacterLiterals, value: 1}]}" --
+
+struct A {
+  void foo(bool abc);
+  void foo(bool abc, bool cde);
+  void foo(const char *, bool abc);
+  void foo(int iabc);
+  void foo(float fabc);
+  void foo(double dabc);
+  void foo(const char *strabc);
+  void fooW(const wchar_t *wstrabc);
+  void fooPtr(A *ptrabc);
+  void foo(char chabc);
+};
+
+#define FOO 1
+
+void g(int a);
+void h(double b);
+void i(const char *c);
+
+double operator"" _km(long double);
+
+void test() {
+  A a;
+
+  a.foo(true);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/true);
+
+  a.foo(false);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/false);
+
+  a.foo(true, false);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-MESSAGES: [[@LINE-2]]:15: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/true, /*cde=*/false);
+
+  a.foo(false, true);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-MESSAGES: [[@LINE-2]]:16: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+  a.foo(/*abc=*/false, true);
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+  a.foo(false, /*cde=*/true);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true);
+
+  bool val1 = true;
+  bool val2 = false;
+  a.foo(val1, val2);
+
+  a.foo("", true);
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo("", /*abc=*/true);
+
+  a.foo(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'iabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*iabc=*/0);
+
+  a.foo(1.0f);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'fabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*fabc=*/1.0f);
+
+  a.foo(1.0);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*dabc=*/1.0);
+
+  int val3 = 10;
+  a.foo(val3);
+
+  float val4 = 10.0;
+  a.foo(val4);
+
+  double val5 = 10.0;
+  a.foo(val5);
+
+  a.foo("Hello World");
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'strabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*strabc=*/"Hello World");
+  //
+  a.fooW(L"Hello World");
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: argument comment missing for literal argument 'wstrabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.fooW(/*wstrabc=*/L"Hello World");
+
+  a.fooPtr(nullptr);
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: argument comment missing for literal argument 'ptrabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.fooPtr(/*ptrabc=*/nullptr);
+
+  a.foo(402.0_km);
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*dabc=*/402.0_km);
+
+  a.foo('A');
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'chabc' [bugprone-argument-comment]
+  // CHECK-FIXES: a.foo(/*chabc=*/'A');
+
+  g(FOO);
+  h(1.0f);
+  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument 'b' [bugprone-argument-comment]
+  // CHECK-FIXES: h(/*b=*/1.0f);
+  i(__FILE__);
+
+  // FIXME Would like the below to add argument comments.
+  g((1));
+  // FIXME But we should not add argument comments here.
+  g(_Generic(0, int : 0));
+}
+
+void f(bool _with_underscores_);
+void ignores_underscores() {
+  f(false);
+  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument '_with_underscores_' [bugprone-argument-comment]
+  // CHECK-FIXES: f(/*_with_underscores_=*/false);
+
+  f(true);
+  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument
+  // CHECK-FIXES: f(/*_with_underscores_=*/true);
+}
diff --git a/test/clang-tidy/bugprone-exception-escape-openmp.cpp b/test/clang-tidy/bugprone-exception-escape-openmp.cpp
new file mode 100644
index 0000000..101c339
--- /dev/null
+++ b/test/clang-tidy/bugprone-exception-escape-openmp.cpp
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s bugprone-exception-escape %t -- -extra-arg=-fopenmp=libomp -extra-arg=-fexceptions --
+
+int thrower() {
+  throw 42;
+}
+
+void ok_parallel() {
+#pragma omp parallel
+  thrower();
+}
+
+void bad_for_header_XFAIL(const int a) noexcept {
+#pragma omp for
+  for (int i = 0; i < thrower(); i++)
+    ;
+  // FIXME: this really should be caught by bugprone-exception-escape.
+  // https://bugs.llvm.org/show_bug.cgi?id=41102
+}
+
+void ok_forloop(const int a) {
+#pragma omp for
+  for (int i = 0; i < a; i++)
+    thrower();
+}
+
+void some_exception_just_so_that_check_clang_tidy_shuts_up() noexcept {
+  thrower();
+}
+// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: an exception may be thrown in function 'some_exception_just_so_that_check_clang_tidy_shuts_up' which should not throw exceptions
diff --git a/test/clang-tidy/bugprone-parent-virtual-call.cpp b/test/clang-tidy/bugprone-parent-virtual-call.cpp
old mode 100755
new mode 100644
diff --git a/test/clang-tidy/bugprone-sizeof-expression.cpp b/test/clang-tidy/bugprone-sizeof-expression.cpp
index 683ad08..57b73ea 100644
--- a/test/clang-tidy/bugprone-sizeof-expression.cpp
+++ b/test/clang-tidy/bugprone-sizeof-expression.cpp
@@ -231,6 +231,35 @@
   return sum;
 }
 
+int Test6() {
+  int sum = 0;
+
+  struct S A = AsStruct(), B = AsStruct();
+  struct S *P = &A, *Q = &B;
+  sum += sizeof(struct S) == P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) != P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += sizeof(S) < P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) <= P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(*P) >= P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += Q - P > 3 * sizeof(*P);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += sizeof(S) + (P - Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) - (P - Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += (P - Q) / sizeof(S);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += (P - Q) / sizeof(*Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+
+  return sum;
+}
+
 int ValidExpressions() {
   int A[] = {1, 2, 3, 4};
   static const char str[] = "hello";
diff --git a/test/clang-tidy/bugprone-string-constructor.cpp b/test/clang-tidy/bugprone-string-constructor.cpp
index 3ab4f42..9e11a32 100644
--- a/test/clang-tidy/bugprone-string-constructor.cpp
+++ b/test/clang-tidy/bugprone-string-constructor.cpp
@@ -65,3 +65,11 @@
   std::string s2("test", 3);
   std::string s3("test");
 }
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+  bool x;
+  std::string f() { return x ? "a" : "b"; }
+};
+}
diff --git a/test/clang-tidy/bugprone-string-integer-assignment.cpp b/test/clang-tidy/bugprone-string-integer-assignment.cpp
index c4e13fc..18fe5ef 100644
--- a/test/clang-tidy/bugprone-string-integer-assignment.cpp
+++ b/test/clang-tidy/bugprone-string-integer-assignment.cpp
@@ -7,18 +7,29 @@
   basic_string& operator=(basic_string);
   basic_string& operator+=(T);
   basic_string& operator+=(basic_string);
+  const T &operator[](int i) const;
+  T &operator[](int i);
 };
 
 typedef basic_string<char> string;
 typedef basic_string<wchar_t> wstring;
+
+int tolower(int i);
+int toupper(int i);
 }
 
+int tolower(int i);
+int toupper(int i);
+
 typedef int MyArcaneChar;
 
+constexpr char kCharConstant = 'a';
+
 int main() {
   std::string s;
   std::wstring ws;
   int x = 5;
+  const char c = 'c';
 
   s = 6;
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a character code when assigning {{.*}} [bugprone-string-integer-assignment]
@@ -47,7 +58,52 @@
 
   std::basic_string<MyArcaneChar> as;
   as = 6;
-// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
-// CHECK-FIXES: {{^}}  as = 6;{{$}}
+  as = static_cast<MyArcaneChar>(6);
+  as = 'a';
 
+  s += toupper(x);
+  s += tolower(x);
+  s += (std::tolower(x));
+
+  s += c & s[1];
+  s += c ^ s[1];
+  s += c | s[1];
+
+  s[x] += 1;
+  s += s[x];
+  as += as[x];
+
+  // Likely character expressions.
+  s += x & 0xff;
+  s += 0xff & x;
+  s += x % 26;
+  s += 26 % x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(26 % x);{{$}}
+  s += c | 0x80;
+  s += c | 0x8000;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(c | 0x8000);{{$}}
+  as += c | 0x8000;
+
+  s += 'a' + (x % 26);
+  s += kCharConstant + (x % 26);
+  s += 'a' + (s[x] & 0xf);
+  s += (x % 10) + 'b';
+
+  s += x > 255 ? c : x;
+  s += x > 255 ? 12 : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(x > 255 ? 12 : x);{{$}}
+}
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+  static constexpr T t = 0x8000;
+  std::string s;
+  void f(char c) { s += c | static_cast<int>(t); }
+};
+
+template S<int>;
 }
diff --git a/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp b/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp
new file mode 100644
index 0000000..d602a1d
--- /dev/null
+++ b/test/clang-tidy/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+
+// MagnitudeBitsUpperLimit = 16 (default value)
+
+unsigned long size() { return 294967296l; }
+
+void voidFilteredOutForLoop1() {
+  for (long i = 0; i < size(); ++i) {
+    // no warning
+  }
+}
+
+void voidCaughtForLoop1() {
+  for (int i = 0; i < size(); ++i) {
+    // no warning
+  }
+}
+
+void voidCaughtForLoop2() {
+  for (short i = 0; i < size(); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'unsigned long' [bugprone-too-small-loop-variable]
+  }
+}
diff --git a/test/clang-tidy/bugprone-too-small-loop-variable.cpp b/test/clang-tidy/bugprone-too-small-loop-variable.cpp
index f11dd49..5a63355 100644
--- a/test/clang-tidy/bugprone-too-small-loop-variable.cpp
+++ b/test/clang-tidy/bugprone-too-small-loop-variable.cpp
@@ -1,4 +1,8 @@
-// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit, \
+// RUN:               value: 1024}]}" \
+// RUN:   -- --target=x86_64-linux
 
 long size() { return 294967296l; }
 
diff --git a/test/clang-tidy/check_clang_tidy.py b/test/clang-tidy/check_clang_tidy.py
index 9768011..5d808f4 100755
--- a/test/clang-tidy/check_clang_tidy.py
+++ b/test/clang-tidy/check_clang_tidy.py
@@ -2,10 +2,9 @@
 #
 #===- check_clang_tidy.py - ClangTidy Test Helper ------------*- python -*--===#
 #
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 #
 #===------------------------------------------------------------------------===#
 
diff --git a/test/clang-tidy/clang-tidy-diff.cpp b/test/clang-tidy/clang-tidy-diff.cpp
index 146287b..2e18a43 100644
--- a/test/clang-tidy/clang-tidy-diff.cpp
+++ b/test/clang-tidy/clang-tidy-diff.cpp
@@ -23,5 +23,4 @@
 // CHECK-QUIET-NOT: warning:
 };
 // CHECK-SANITY-NOT: Suppressed
-// CHECK: Suppressed 1 warnings (1 due to line filter).
 // CHECK-QUIET-NOT: Suppressed
diff --git a/test/clang-tidy/clang-tidy-mac-libcxx.cpp b/test/clang-tidy/clang-tidy-mac-libcxx.cpp
index 153a5d6..d124a34 100644
--- a/test/clang-tidy/clang-tidy-mac-libcxx.cpp
+++ b/test/clang-tidy/clang-tidy-mac-libcxx.cpp
@@ -8,7 +8,7 @@
 // RUN: cp -r %S/Inputs/mock-libcxx %t/
 //
 // Pretend clang is installed beside the mock library that we provided.
-// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
+// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -std=c++11 -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
 // RUN: cp "%s" "%t/test.cpp"
 // RUN: clang-tidy -header-filter='.*' -system-headers -checks='-*,modernize-use-using'  "%t/test.cpp" | FileCheck %s
 // CHECK: mock_vector:{{[0-9]+}}:{{[0-9]+}}: warning: use 'using' instead of 'typedef'
diff --git a/test/clang-tidy/cppcoreguidelines-macro-usage.cpp b/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
index a4948f5..edce328 100644
--- a/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
+++ b/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t -- -header-filter=.* -system-headers --
 
 #ifndef INCLUDE_GUARD
 #define INCLUDE_GUARD
diff --git a/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp b/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp
new file mode 100644
index 0000000..d191922
--- /dev/null
+++ b/test/clang-tidy/expand-modular-headers-ppcallbacks.cpp
@@ -0,0 +1,35 @@
+// Sanity-check. Run without modules:
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp %S/Inputs/expand-modular-headers-ppcallbacks/* %t/
+// RUN: %check_clang_tidy %s readability-identifier-naming %t/without-modules -- \
+// RUN:   -config="CheckOptions: [{ \
+// RUN:      key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }]" \
+// RUN:   -header-filter=.* \
+// RUN:   -- -x c++ -std=c++11 -I%t/
+//
+// Run clang-tidy on a file with modular includes:
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp %S/Inputs/expand-modular-headers-ppcallbacks/* %t/
+// RUN: %check_clang_tidy %s readability-identifier-naming %t/with-modules -- \
+// RUN:   -config="CheckOptions: [{ \
+// RUN:      key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }]" \
+// RUN:   -header-filter=.* \
+// RUN:   -- -x c++ -std=c++11 -I%t/ \
+// RUN:   -fmodules -fimplicit-modules -fno-implicit-module-maps \
+// RUN:   -fmodule-map-file=%t/module.modulemap \
+// RUN:   -fmodules-cache-path=%t/module-cache/
+#include "c.h"
+
+// CHECK-MESSAGES: a.h:1:9: warning: invalid case style for macro definition 'a' [readability-identifier-naming]
+// CHECK-MESSAGES: a.h:1:9: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: b.h:2:9: warning: invalid case style for macro definition 'b'
+// CHECK-MESSAGES: b.h:2:9: note: FIX-IT applied suggested code changes
+// CHECK-MESSAGES: c.h:2:9: warning: invalid case style for macro definition 'c'
+// CHECK-MESSAGES: c.h:2:9: note: FIX-IT applied suggested code changes
+
+#define m
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: invalid case style for macro definition 'm'
+// CHECK-MESSAGES: :[[@LINE-2]]:9: note: FIX-IT applied suggested code changes
diff --git a/test/clang-tidy/export-diagnostics.cpp b/test/clang-tidy/export-diagnostics.cpp
index 5eda204..14a6a40 100644
--- a/test/clang-tidy/export-diagnostics.cpp
+++ b/test/clang-tidy/export-diagnostics.cpp
@@ -13,16 +13,19 @@
 // CHECK-YAML-NEXT: MainSourceFile:  '{{.*}}-input.cpp'
 // CHECK-YAML-NEXT: Diagnostics:
 // CHECK-YAML-NEXT:   - DiagnosticName:  clang-diagnostic-missing-prototypes
-// CHECK-YAML-NEXT:     Message:         'no previous prototype for function ''ff'''
-// CHECK-YAML-NEXT:     FileOffset:      30
-// CHECK-YAML-NEXT:     FilePath:        '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT:     DiagnosticMessage:
+// CHECK-YAML-NEXT:       Message:         'no previous prototype for function
+// ''ff'''
+// CHECK-YAML-NEXT:       FilePath:        '{{.*}}-input.cpp'
+// CHECK-YAML-NEXT:       FileOffset:      30
+// CHECK-YAML-NEXT:       Replacements:      []
 // CHECK-YAML-NEXT:     Notes:
 // CHECK-YAML-NEXT:       - Message:         'expanded from macro ''X'''
 // CHECK-YAML-NEXT:         FilePath:        '{{.*}}-input.cpp'
 // CHECK-YAML-NEXT:         FileOffset:      18
+// CHECK-YAML-NEXT:         Replacements:    []
 // CHECK-YAML-NEXT:       - Message:         expanded from here
 // CHECK-YAML-NEXT:         FilePath:        ''
 // CHECK-YAML-NEXT:         FileOffset:      0
-// CHECK-YAML-NEXT:     Replacements:    []
+// CHECK-YAML-NEXT:         Replacements:    []
 // CHECK-YAML-NEXT: ...
-
diff --git a/test/clang-tidy/google-objc-function-naming.m b/test/clang-tidy/google-objc-function-naming.m
index d0336d2..01433d9 100644
--- a/test/clang-tidy/google-objc-function-naming.m
+++ b/test/clang-tidy/google-objc-function-naming.m
@@ -1,4 +1,12 @@
-// RUN: %check_clang_tidy %s google-objc-function-naming %t
+// RUN: %check_clang_tidy %s google-objc-function-naming %t -- -- -isystem %S/Inputs/Headers
+
+#include <stdio.h>
+
+static void TestImplicitFunctionDeclaration(int a) {
+  // Call a builtin function so that the compiler generates an implicit
+  // function declaration.
+  printf("%d", a);
+}
 
 typedef _Bool bool;
 
diff --git a/test/clang-tidy/google-objc-global-variable-declaration.mm b/test/clang-tidy/google-objc-global-variable-declaration.mm
new file mode 100644
index 0000000..a6b0f6e
--- /dev/null
+++ b/test/clang-tidy/google-objc-global-variable-declaration.mm
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s google-objc-global-variable-declaration %t
+
+@class NSString;
+static NSString* const myConstString = @"hello";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'myConstString' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kMyConstString = @"hello";
+
+class MyTest {
+    static int not_objc_style;
+};
diff --git a/test/clang-tidy/google-runtime-int.m b/test/clang-tidy/google-runtime-int.m
new file mode 100644
index 0000000..dd1225c
--- /dev/null
+++ b/test/clang-tidy/google-runtime-int.m
@@ -0,0 +1,32 @@
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- | count 0
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- -x objective-c++ | count 0
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+
+@interface NSString
+@property(readonly) NSInteger integerValue;
+@property(readonly) long long longLongValue;
+@property(readonly) NSUInteger length;
+@end
+
+NSInteger Foo(NSString *s) {
+  return [s integerValue];
+}
+
+long long Bar(NSString *s) {
+  return [s longLongValue];
+}
+
+NSUInteger Baz(NSString *s) {
+  return [s length];
+}
+
+unsigned short NSSwapShort(unsigned short inv);
+
+long DoSomeMath(long a, short b) {
+  short c = NSSwapShort(b);
+  long a2 = a * 5L;
+  return a2 + c;
+}
+
diff --git a/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp b/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp
new file mode 100644
index 0000000..48652d5
--- /dev/null
+++ b/test/clang-tidy/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t
+
+struct X;
+struct Y;
+struct Z {
+  int foo();
+  X *bar();
+  X *cast(Y*);
+  bool baz(Y*);
+};
+
+template <class X, class Y>
+bool isa(Y *);
+template <class X, class Y>
+X *cast(Y *);
+template <class X, class Y>
+X *dyn_cast(Y *);
+template <class X, class Y>
+X *dyn_cast_or_null(Y *);
+
+bool foo(Y *y, Z *z) {
+  if (auto x = cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (auto x = dyn_cast<X>(y))
+
+  while (auto x = cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: cast<> in conditional
+  // CHECK-FIXES: while (auto x = dyn_cast<X>(y))
+
+  if (cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: cast<> in conditional
+  // CHECK-FIXES: if (isa<X>(y))
+
+  while (cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: cast<> in conditional
+  // CHECK-FIXES: while (isa<X>(y))
+
+  do {
+    break;
+  } while (cast<X>(y));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional
+  // CHECK-FIXES: while (isa<X>(y));
+
+  if (dyn_cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: return value from dyn_cast<> not used [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (isa<X>(y))
+
+  while (dyn_cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: return value from dyn_cast<> not used
+  // CHECK-FIXES: while (isa<X>(y))
+
+  do {
+    break;
+  } while (dyn_cast<X>(y));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used
+  // CHECK-FIXES: while (isa<X>(y));
+
+  if (y && isa<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (isa_and_nonnull<X>(y))
+
+  if (z->bar() && isa<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning:  isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && cast<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && dyn_cast<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && dyn_cast_or_null<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  bool b = z->bar() && cast<Y>(z->bar());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: bool b = isa_and_nonnull<Y>(z->bar());
+
+  // These don't trigger a warning.
+  if (auto x = cast<Z>(y)->foo())
+    return true;
+  if (auto x = z->cast(y))
+    return true;
+  while (auto x = cast<Z>(y)->foo())
+    break;
+  if (cast<Z>(y)->foo())
+    return true;
+  if (z->cast(y))
+    return true;
+  while (cast<Z>(y)->foo())
+    break;
+  if (y && cast<X>(z->bar()))
+    return true;
+  if (z && cast<Z>(y)->foo())
+    return true;
+  bool b2 = y && cast<X>(z);
+  if(z->cast(y))
+    return true;
+  if (z->baz(cast<Y>(z)))
+    return true;
+
+#define CAST(T, Obj) cast<T>(Obj)
+#define AUTO_VAR_CAST(X, Y, Z) auto X = cast<Y>(Z)
+#define ISA(T, Obj) isa<T>(Obj)
+#define ISA_OR_NULL(T, Obj) Obj &&isa<T>(Obj)
+
+  // Macros don't trigger warning.
+  if (auto x = CAST(X, y))
+    return true;
+  if (AUTO_VAR_CAST(x, X, z))
+    return true;
+  if (z->bar() && ISA(Y, z->bar()))
+    return true;
+  if (ISA_OR_NULL(Y, z->bar()))
+    return true;
+
+  return false;
+}
diff --git a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
index 3105271..2a93ff6 100644
--- a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
+++ b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
@@ -35,6 +35,23 @@
   int S1_v3;
 };
 
+// Only data and implicit or static methods, do not warn
+
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+
+struct S1Implicit {
+  C S1Implicit_v0;
+};
+
+struct S1ImplicitAndStatic {
+  C S1Implicit_v0;
+  static void s() {}
+};
+
 //----------------------------------------------------------------------------//
 
 // All functions are static, do not warn.
diff --git a/test/clang-tidy/modernize-avoid-bind.cpp b/test/clang-tidy/modernize-avoid-bind.cpp
index 1c78b9e..721801b 100644
--- a/test/clang-tidy/modernize-avoid-bind.cpp
+++ b/test/clang-tidy/modernize-avoid-bind.cpp
@@ -77,3 +77,47 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
   // CHECK-FIXES: auto clj = [] { return C::add(1, 1); };
 }
+
+// Let's fake a minimal std::function-like facility.
+namespace std {
+template <typename _Tp>
+_Tp declval();
+
+template <typename _Functor, typename... _ArgTypes>
+struct __res {
+  template <typename... _Args>
+  static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
+
+  template <typename...>
+  static void _S_test(...);
+
+  using type = decltype(_S_test<_ArgTypes...>(0));
+};
+
+template <typename>
+struct function;
+
+template <typename... _ArgTypes>
+struct function<void(_ArgTypes...)> {
+  template <typename _Functor,
+            typename = typename __res<_Functor, _ArgTypes...>::type>
+  function(_Functor) {}
+};
+} // namespace std
+
+struct Thing {};
+void UseThing(Thing *);
+
+struct Callback {
+  Callback();
+  Callback(std::function<void()>);
+  void Reset(std::function<void()>);
+};
+
+void test(Thing *t) {
+  Callback cb;
+  if (t)
+    cb.Reset(std::bind(UseThing, t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: cb.Reset([=] { return UseThing(t); });
+}
diff --git a/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp
new file mode 100644
index 0000000..6549422
--- /dev/null
+++ b/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[]) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+  int f4[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[]) {
+  int f5[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  auto not_main = [](int argc, char *argv[]) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+    int f6[] = {1, 2};
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+  };
+}
diff --git a/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
new file mode 100644
index 0000000..22a4016
--- /dev/null
+++ b/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[], char *argw[]) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+  // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: do not declare C-style arrays, use std::array<> instead
+  int f4[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[], char *argw[]) {
+  int f5[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  auto not_main = [](int argc, char *argv[], char *argw[]) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+    // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: do not declare C-style arrays, use std::array<> instead
+    int f6[] = {1, 2};
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+  };
+}
diff --git a/test/clang-tidy/modernize-redundant-void-arg.cpp b/test/clang-tidy/modernize-redundant-void-arg.cpp
index 44a726b..0fad5d5 100644
--- a/test/clang-tidy/modernize-redundant-void-arg.cpp
+++ b/test/clang-tidy/modernize-redundant-void-arg.cpp
@@ -489,6 +489,13 @@
   // CHECK-FIXES: []() BODY;
 }
 
+namespace qqq {
+void foo() BODY
+void bar(void) BODY;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition
+// CHECK-FIXES: void bar() BODY;
+}
+
 struct S_1 {
   void g_1(void) const {
     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
diff --git a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
index fdc0db1..b98055c 100644
--- a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
+++ b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp
@@ -166,6 +166,14 @@
   // CHECK-FIXES: Enum e = Foo;
 };
 
+struct PositiveValueEnum {
+  PositiveValueEnum() : e() {}
+  // CHECK-FIXES: PositiveValueEnum()  {}
+  Enum e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+  // CHECK-FIXES: Enum e{};
+};
+
 struct PositiveString {
   PositiveString() : s("foo") {}
   // CHECK-FIXES: PositiveString()  {}
diff --git a/test/clang-tidy/modernize-use-default-member-init.cpp b/test/clang-tidy/modernize-use-default-member-init.cpp
index 0ed65df..825bfa0 100644
--- a/test/clang-tidy/modernize-use-default-member-init.cpp
+++ b/test/clang-tidy/modernize-use-default-member-init.cpp
@@ -165,6 +165,14 @@
   // CHECK-FIXES: Enum e{Foo};
 };
 
+struct PositiveValueEnum {
+  PositiveValueEnum() : e() {}
+  // CHECK-FIXES: PositiveValueEnum()  {}
+  Enum e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e'
+  // CHECK-FIXES: Enum e{};
+};
+
 struct PositiveString {
   PositiveString() : s("foo") {}
   // CHECK-FIXES: PositiveString()  {}
@@ -382,6 +390,16 @@
   const char *e4 = "bar";
 };
 
+struct UnionExisting {
+  UnionExisting() : e(5.0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: member initializer for 'e' is redundant
+  // CHECK-FIXES: UnionExisting()  {}
+  union {
+    int i;
+    double e = 5.0;
+  };
+};
+
 template <typename T>
 struct NegativeTemplateExisting {
   NegativeTemplateExisting(int) : t(0) {}
diff --git a/test/clang-tidy/modernize-use-override-no-destructors.cpp b/test/clang-tidy/modernize-use-override-no-destructors.cpp
new file mode 100644
index 0000000..eaadb07
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-no-destructors.cpp
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-override.IgnoreDestructors, value: 1}]}" \
+// RUN: -- -std=c++11
+
+struct Base {
+  virtual ~Base();
+  virtual void f();
+};
+
+struct Simple : public Base {
+  virtual ~Simple();
+  // CHECK-MESSAGES-NOT: warning:
+  virtual void f();
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void f() override;
+};
diff --git a/test/clang-tidy/modernize-use-override-with-macro.cpp b/test/clang-tidy/modernize-use-override-with-macro.cpp
new file mode 100644
index 0000000..ad682f1
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-with-macro.cpp
@@ -0,0 +1,70 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'FINAL'}]}" \
+// RUN: -- -std=c++11
+
+#define ABSTRACT = 0
+
+#define OVERRIDE override
+#define FINAL final
+#define VIRTUAL virtual
+#define NOT_VIRTUAL
+#define NOT_OVERRIDE
+
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#define UNUSED __attribute__((unused))
+
+struct Base {
+  virtual ~Base() {}
+  virtual void a();
+  virtual void b();
+  virtual void c();
+  virtual void e() = 0;
+  virtual void f2() const = 0;
+  virtual void g() = 0;
+  virtual void j() const;
+  virtual void k() = 0;
+  virtual void l() const;
+};
+
+struct SimpleCases : public Base {
+public:
+  virtual ~SimpleCases();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'OVERRIDE' or (rarely) 'FINAL' instead of 'virtual' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  ~SimpleCases() OVERRIDE;
+
+  void a();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this function with 'OVERRIDE' or (rarely) 'FINAL' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  void a() OVERRIDE;
+
+  virtual void b();
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'OVERRIDE' or (rarely) 'FINAL' instead of 'virtual' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  void b() OVERRIDE;
+
+  virtual void c();
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void c() OVERRIDE;
+
+  virtual void e() = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void e() OVERRIDE = 0;
+
+  virtual void f2() const = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void f2() const OVERRIDE = 0;
+
+  virtual void g() ABSTRACT;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void g() OVERRIDE ABSTRACT;
+
+  virtual void j() const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
+  // CHECK-FIXES: {{^}}  void j() const OVERRIDE;
+
+  virtual void k() OVERRIDE;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  void k() OVERRIDE;
+
+  virtual void l() const OVERRIDE;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  void l() const OVERRIDE;
+};
diff --git a/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp
new file mode 100644
index 0000000..97b7105
--- /dev/null
+++ b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s modernize-use-override %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'CUSTOM_OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'CUSTOM_FINAL'}]}" \
+// RUN: -- -std=c++11
+
+// As if the macro was not defined.
+//#define CUSTOM_OVERRIDE override
+//#define CUSTOM_FINAL override
+
+struct Base {
+  virtual ~Base() {}
+  virtual void a();
+  virtual void b();
+};
+
+struct SimpleCases : public Base {
+public:
+  virtual ~SimpleCases();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  virtual ~SimpleCases();
+
+  void a();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this function with 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  void a();
+
+  virtual void b();
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override]
+  // CHECK-FIXES: {{^}}  virtual void b();
+};
diff --git a/test/clang-tidy/nolint.cpp b/test/clang-tidy/nolint.cpp
index 24c3722..a2d2c10 100644
--- a/test/clang-tidy/nolint.cpp
+++ b/test/clang-tidy/nolint.cpp
@@ -31,6 +31,7 @@
   int i;
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: unused variable 'i' [clang-diagnostic-unused-variable]
   int j; // NOLINT
+  int k; // NOLINT(clang-diagnostic-unused-variable)
 }
 
 #define MACRO(X) class X { X(int i); };
@@ -47,4 +48,4 @@
 #define DOUBLE_MACRO MACRO(H) // NOLINT
 DOUBLE_MACRO
 
-// CHECK-MESSAGES: Suppressed 12 warnings (12 NOLINT)
+// CHECK-MESSAGES: Suppressed 13 warnings (13 NOLINT)
diff --git a/test/clang-tidy/objc-property-declaration.m b/test/clang-tidy/objc-property-declaration.m
index 07a0620..b56bdcd 100644
--- a/test/clang-tidy/objc-property-declaration.m
+++ b/test/clang-tidy/objc-property-declaration.m
@@ -46,6 +46,7 @@
 @property(strong, nonatomic) NSString *URLStr;
 @property(assign, nonatomic) int abc_camelCase;
 @property(strong, nonatomic) NSString *abc_URL;
+@property(strong, nonatomic) NSString *opac2_sourceComponent;
 @end
 
 @interface Foo ()
diff --git a/test/clang-tidy/objc-super-self.m b/test/clang-tidy/objc-super-self.m
new file mode 100644
index 0000000..9653cd2
--- /dev/null
+++ b/test/clang-tidy/objc-super-self.m
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s objc-super-self %t
+
+@interface NSObject
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NSObjectDerivedClass : NSObject
+@end
+
+@implementation NSObjectDerivedClass
+
+- (instancetype)init {
+  return [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super init];
+}
+
+- (instancetype)initWithObject:(NSObject *)obj {
+  self = [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: self = [super init];
+  if (self) {
+    // ...
+  }
+  return self;
+}
+
+#define INITIALIZE() [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc a:(int)a {
+  return INITIALIZE();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return INITIALIZE();
+}
+
+#define INITIALIZER_IMPL() return [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc b:(int)b {
+  INITIALIZER_IMPL();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: INITIALIZER_IMPL();
+}
+
+#define INITIALIZER_METHOD self
+
+- (instancetype)initWithObject:(NSObject *)objc c:(int)c {
+  return [super INITIALIZER_METHOD];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super INITIALIZER_METHOD];
+}
+
+#define RECEIVER super
+
+- (instancetype)initWithObject:(NSObject *)objc d:(int)d {
+  return [RECEIVER self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [RECEIVER self];
+}
+
+- (instancetype)foo {
+  return [super self];
+}
+
+- (instancetype)bar {
+  return [self self];
+}
+
+@end
+
+@interface RootClass
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NotNSObjectDerivedClass : RootClass
+@end
+
+@implementation NotNSObjectDerivedClass
+
+- (instancetype)init {
+  return [super self];
+}
+
+@end
+
diff --git a/test/clang-tidy/openmp-exception-escape.cpp b/test/clang-tidy/openmp-exception-escape.cpp
new file mode 100644
index 0000000..7334583
--- /dev/null
+++ b/test/clang-tidy/openmp-exception-escape.cpp
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy %s openmp-exception-escape %t -- -extra-arg=-fopenmp=libomp -extra-arg=-fexceptions -config="{CheckOptions: [{key: openmp-exception-escape.IgnoredExceptions, value: 'ignored, ignored2'}]}" --
+
+int thrower() {
+  throw 42;
+}
+
+class ignored {};
+class ignored2 {};
+namespace std {
+class bad_alloc {};
+} // namespace std
+
+void parallel() {
+#pragma omp parallel
+  thrower();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+}
+
+void ignore() {
+#pragma omp parallel
+  throw ignored();
+}
+
+void ignore2() {
+#pragma omp parallel
+  throw ignored2();
+}
+
+void standalone_directive() {
+#pragma omp taskwait
+  throw ignored(); // not structured block
+}
+
+void ignore_alloc() {
+#pragma omp parallel
+  throw std::bad_alloc();
+}
+
+void parallel_caught() {
+#pragma omp parallel
+  {
+    try {
+      thrower();
+    } catch (...) {
+    }
+  }
+}
+
+void for_header(const int a) {
+  // Only the body of the loop counts.
+#pragma omp for
+  for (int i = 0; i < thrower(); i++)
+    ;
+}
+
+void forloop(const int a) {
+#pragma omp for
+  for (int i = 0; i < a; i++)
+    thrower();
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+}
+
+void parallel_forloop(const int a) {
+#pragma omp parallel
+  {
+#pragma omp for
+    for (int i = 0; i < a; i++)
+      thrower();
+    thrower();
+    // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+    // CHECK-MESSAGES: :[[@LINE-3]]:7: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+  }
+}
+
+void parallel_forloop_caught(const int a) {
+#pragma omp parallel
+  {
+#pragma omp for
+    for (int i = 0; i < a; i++) {
+      try {
+        thrower();
+      } catch (...) {
+      }
+    }
+    thrower();
+    // CHECK-MESSAGES: :[[@LINE-9]]:3: warning: an exception thrown inside of the OpenMP 'parallel' region is not caught in that same region
+  }
+}
+
+void parallel_caught_forloop(const int a) {
+#pragma omp parallel
+  {
+#pragma omp for
+    for (int i = 0; i < a; i++)
+      thrower();
+    try {
+      thrower();
+    } catch (...) {
+    }
+    // CHECK-MESSAGES: :[[@LINE-5]]:7: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+  }
+}
+
+void parallel_outercaught_forloop(const int a) {
+#pragma omp parallel
+  {
+    try {
+#pragma omp for
+      for (int i = 0; i < a; i++)
+        thrower();
+      thrower();
+    } catch (...) {
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: an exception thrown inside of the OpenMP 'for' region is not caught in that same region
+  }
+}
+
+void parallel_outercaught_forloop_caught(const int a) {
+#pragma omp parallel
+  {
+    try {
+#pragma omp for
+      for (int i = 0; i < a; i++) {
+        try {
+          thrower();
+        } catch (...) {
+        }
+      }
+    } catch (...) {
+    }
+  }
+}
diff --git a/test/clang-tidy/openmp-use-default-none.cpp b/test/clang-tidy/openmp-use-default-none.cpp
new file mode 100644
index 0000000..1a374bd
--- /dev/null
+++ b/test/clang-tidy/openmp-use-default-none.cpp
@@ -0,0 +1,160 @@
+// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -x c++ -fopenmp=libomp -fopenmp-version=40
+// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -x c   -fopenmp=libomp -fopenmp-version=40
+
+//----------------------------------------------------------------------------//
+// Null cases.
+//----------------------------------------------------------------------------//
+
+// 'for' directive can not have 'default' clause, no diagnostics.
+void n0(const int a) {
+#pragma omp for
+  for (int b = 0; b < a; b++)
+    ;
+}
+
+//----------------------------------------------------------------------------//
+// Single-directive positive cases.
+//----------------------------------------------------------------------------//
+
+// 'parallel' directive.
+
+// 'parallel' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p0_0() {
+#pragma omp parallel
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'parallel' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p0_1() {
+#pragma omp parallel default(none)
+  ;
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p0_2() {
+#pragma omp parallel default(shared)
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'parallel' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+  // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here
+}
+
+// 'task' directive.
+
+// 'task' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p1_0() {
+#pragma omp task
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'task' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'task' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p1_1() {
+#pragma omp task default(none)
+  ;
+}
+
+// 'task' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p1_2() {
+#pragma omp task default(shared)
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'task' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+  // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here
+}
+
+// 'teams' directive. (has to be inside of 'target' directive)
+
+// 'teams' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p2_0() {
+#pragma omp target
+#pragma omp teams
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'teams' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'teams' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p2_1() {
+#pragma omp target
+#pragma omp teams default(none)
+  ;
+}
+
+// 'teams' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p2_2() {
+#pragma omp target
+#pragma omp teams default(shared)
+  ;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: OpenMP directive 'teams' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+  // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here
+}
+
+// 'taskloop' directive.
+
+// 'taskloop' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p3_0(const int a) {
+#pragma omp taskloop
+  for (int b = 0; b < a; b++)
+    ;
+  // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'taskloop' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'taskloop' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p3_1(const int a) {
+#pragma omp taskloop default(none) shared(a)
+  for (int b = 0; b < a; b++)
+    ;
+}
+
+// 'taskloop' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p3_2(const int a) {
+#pragma omp taskloop default(shared)
+  for (int b = 0; b < a; b++)
+    ;
+  // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'taskloop' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+  // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here
+}
+
+//----------------------------------------------------------------------------//
+// Combined directives.
+// Let's not test every single possible permutation/combination of directives,
+// but just *one* combined directive. The rest will be the same.
+//----------------------------------------------------------------------------//
+
+// 'parallel' directive can have 'default' clause, but said clause is not
+// specified, diagnosed.
+void p4_0(const int a) {
+#pragma omp parallel for
+  for (int b = 0; b < a; b++)
+    ;
+  // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'parallel for' does not specify 'default' clause, consider specifying 'default(none)' clause
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// with 'none' kind, all good.
+void p4_1(const int a) {
+#pragma omp parallel for default(none) shared(a)
+  for (int b = 0; b < a; b++)
+    ;
+}
+
+// 'parallel' directive can have 'default' clause, and said clause specified,
+// but with 'shared' kind, which is not 'none', diagnose.
+void p4_2(const int a) {
+#pragma omp parallel for default(shared)
+  for (int b = 0; b < a; b++)
+    ;
+  // CHECK-NOTES: :[[@LINE-3]]:9: warning: OpenMP directive 'parallel for' specifies 'default(shared)' clause, consider using 'default(none)' clause instead
+  // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here
+}
diff --git a/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp
new file mode 100644
index 0000000..6e8a5c2
--- /dev/null
+++ b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s google-readability-avoid-underscore-in-googletest-name %t
+
+#define TEST(test_case_name, test_name) void test_case_name##test_name()
+#define TEST_F(test_case_name, test_name) void test_case_name##test_name()
+#define TEST_P(test_case_name, test_name) void test_case_name##test_name()
+#define TYPED_TEST(test_case_name, test_name) void test_case_name##test_name()
+#define TYPED_TEST_P(test_case_name, test_name) void test_case_name##test_name()
+#define FRIEND_TEST(test_case_name, test_name) void test_case_name##test_name()
+
+TEST(TestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST(TestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(TestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_TestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_Test_CaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_Test_CaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST(Illegal_TestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(TestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(TestCaseFixtureName, DISABLED_Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(TestCaseFixtureName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(Illegal_TestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_F(Illegal_TestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_F(Illegal_Test_CaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Test_CaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(ParameterizedTestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(ParameterizedTestCaseFixtureName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(ParameterizedTestCaseFixtureName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(Illegal_ParameterizedTestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TEST_P(Illegal_ParameterizedTestCaseFixtureName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:50: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TEST_P(Illegal_Parameterized_TestCaseFixtureName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Parameterized_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(TypedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(TypedTestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(TypedTestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(Illegal_TypedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST(Illegal_TypedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:39: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST(Illegal_Typed_TestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_Typed_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(TypeParameterizedTestCaseName, DISABLED_Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_Test_Name) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, Illegal_TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+// CHECK-MESSAGES: :[[@LINE-2]]:53: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+TYPED_TEST_P(Illegal_Type_ParameterizedTestCaseName, TestName) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_Type_ParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
+
+// Underscores are allowed to disable a test with the DISABLED_ prefix.
+// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore
+TEST(TestCaseName, TestName) {}
+TEST(TestCaseName, DISABLED_TestName) {}
+
+TEST_F(TestCaseFixtureName, TestName) {}
+TEST_F(TestCaseFixtureName, DISABLED_TestName) {}
+
+TEST_P(ParameterizedTestCaseFixtureName, TestName) {}
+TEST_P(ParameterizedTestCaseFixtureName, DISABLED_TestName) {}
+
+TYPED_TEST(TypedTestName, TestName) {}
+TYPED_TEST(TypedTestName, DISABLED_TestName) {}
+
+TYPED_TEST_P(TypeParameterizedTestName, TestName) {}
+TYPED_TEST_P(TypeParameterizedTestName, DISABLED_TestName) {}
+
+FRIEND_TEST(FriendTest, Is_NotChecked) {}
+FRIEND_TEST(Friend_Test, IsNotChecked) {}
+FRIEND_TEST(Friend_Test, Is_NotChecked) {}
diff --git a/test/clang-tidy/readability-else-after-return.cpp b/test/clang-tidy/readability-else-after-return.cpp
index 7e95092..b06c02c 100644
--- a/test/clang-tidy/readability-else-after-return.cpp
+++ b/test/clang-tidy/readability-else-after-return.cpp
@@ -105,3 +105,15 @@
     }
   }
 }
+
+extern int *g();
+extern void h(int **x);
+
+int *decl_in_condition() {
+  if (int *x = g()) {
+    return x;
+  } else {
+    h(&x);
+    return x;
+  }
+}
diff --git a/test/clang-tidy/readability-misleading-indentation.cpp b/test/clang-tidy/readability-misleading-indentation.cpp
index 59d5f40..4039949 100644
--- a/test/clang-tidy/readability-misleading-indentation.cpp
+++ b/test/clang-tidy/readability-misleading-indentation.cpp
@@ -8,7 +8,7 @@
     foo1();   \
     foo2();
 
-int main()
+void f()
 {
   bool cond1 = true;
   bool cond2 = true;
@@ -90,7 +90,7 @@
        else {
   }
   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: different indentation for 'if' and corresponding 'else' [readability-misleading-indentation]
-  
+
   if (cond1) {
     if (cond1) {
     }
@@ -109,3 +109,12 @@
 
   BLOCK
 }
+
+void g(bool x) {
+  if (x)
+    #pragma unroll
+    for (int k = 0; k < 1; ++k) {}
+
+  #pragma unroll
+  for (int k = 0; k < 1; ++k) {}
+}
diff --git a/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp b/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp
new file mode 100644
index 0000000..bd8990a
--- /dev/null
+++ b/test/clang-tidy/readability-redundant-smartptr-get-msvc.cpp
@@ -0,0 +1,94 @@
+// RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t
+
+#define NULL __null
+
+namespace std {
+
+// MSVC headers define operator templates instead of plain operators.
+
+template <typename T>
+struct unique_ptr {
+  template <typename T2 = T>
+  T2& operator*() const;
+  template <typename T2 = T>
+  T2* operator->() const;
+  T* get() const;
+  explicit operator bool() const noexcept;
+};
+
+template <typename T>
+struct shared_ptr {
+  template <typename T2 = T>
+  T2& operator*() const;
+  template <typename T2 = T>
+  T2* operator->() const;
+  T* get() const;
+  explicit operator bool() const noexcept;
+};
+
+}  // namespace std
+
+struct Bar {
+  void Do();
+  void ConstDo() const;
+};
+
+void Positive() {
+  std::unique_ptr<Bar>* up;
+  (*up->get()).Do();
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
+  // CHECK-MESSAGES: (*up->get()).Do();
+  // CHECK-FIXES: (**up).Do();
+
+  std::unique_ptr<int> uu;
+  std::shared_ptr<double> *ss;
+  bool bb = uu.get() == nullptr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
+  // CHECK-MESSAGES: uu.get() == nullptr;
+  // CHECK-FIXES: bool bb = uu == nullptr;
+
+  if (up->get());
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+  // CHECK-MESSAGES: if (up->get());
+  // CHECK-FIXES: if (*up);
+  if ((uu.get()));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+  // CHECK-MESSAGES: if ((uu.get()));
+  // CHECK-FIXES: if ((uu));
+  bb = !ss->get();
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant get() call
+  // CHECK-MESSAGES: bb = !ss->get();
+  // CHECK-FIXES: bb = !*ss;
+
+  bb = nullptr != ss->get();
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call
+  // CHECK-MESSAGES: nullptr != ss->get();
+  // CHECK-FIXES: bb = nullptr != *ss;
+
+  bb = std::unique_ptr<int>().get() == NULL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+  // CHECK-MESSAGES: bb = std::unique_ptr<int>().get() == NULL;
+  // CHECK-FIXES: bb = std::unique_ptr<int>() == NULL;
+  bb = ss->get() == NULL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
+  // CHECK-MESSAGES: bb = ss->get() == NULL;
+  // CHECK-FIXES: bb = *ss == NULL;
+
+  std::unique_ptr<int> x, y;
+  if (x.get() == nullptr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+  // CHECK-MESSAGES: if (x.get() == nullptr);
+  // CHECK-FIXES: if (x == nullptr);
+  if (nullptr == y.get());
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant get() call
+  // CHECK-MESSAGES: if (nullptr == y.get());
+  // CHECK-FIXES: if (nullptr == y);
+  if (x.get() == NULL);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
+  // CHECK-MESSAGES: if (x.get() == NULL);
+  // CHECK-FIXES: if (x == NULL);
+  if (NULL == x.get());
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant get() call
+  // CHECK-MESSAGES: if (NULL == x.get());
+  // CHECK-FIXES: if (NULL == x);
+}
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp
new file mode 100644
index 0000000..b2b858f
--- /dev/null
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target aarch64-linux-gnu -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void float16_normal_literals() {
+  // _Float16
+
+  static constexpr auto v14 = 1.f16;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16;
+  // CHECK-MESSAGES-NEXT: ^ ~
+  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+  // CHECK-FIXES: static constexpr auto v14 = 1.F16;
+  static_assert(is_same<decltype(v14), const _Float16>::value, "");
+  static_assert(v14 == 1.F16, "");
+
+  static constexpr auto v15 = 1.e0f16;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16;
+  // CHECK-MESSAGES-NEXT: ^ ~
+  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+  // CHECK-FIXES: static constexpr auto v15 = 1.e0F16;
+  static_assert(is_same<decltype(v15), const _Float16>::value, "");
+  static_assert(v15 == 1.F16, "");
+
+  static constexpr auto v16 = 1.F16; // OK.
+  static_assert(is_same<decltype(v16), const _Float16>::value, "");
+  static_assert(v16 == 1.F16, "");
+
+  static constexpr auto v17 = 1.e0F16; // OK.
+  static_assert(is_same<decltype(v17), const _Float16>::value, "");
+  static_assert(v17 == 1.F16, "");
+}
+
+void float16_hexadecimal_literals() {
+// _Float16
+
+  static constexpr auto v13 = 0xfp0f16;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16;
+  // CHECK-MESSAGES-NEXT: ^    ~
+  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
+  // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16;
+  static_assert(is_same<decltype(v13), const _Float16>::value, "");
+  static_assert(v13 == 0xfp0F16, "");
+
+  static constexpr auto v14 = 0xfp0F16; // OK.
+  static_assert(is_same<decltype(v14), const _Float16>::value, "");
+  static_assert(v14 == 0xfp0F16, "");
+
+}
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
index 4d41db7..50e75fa 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp
@@ -97,34 +97,6 @@
   static constexpr auto v13 = 1.e0Q; // OK.
   static_assert(is_same<decltype(v13), const __float128>::value, "");
   static_assert(v13 == 1., "");
-
-  // _Float16
-
-  static constexpr auto v14 = 1.f16;
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
-  // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16;
-  // CHECK-MESSAGES-NEXT: ^ ~
-  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
-  // CHECK-FIXES: static constexpr auto v14 = 1.F16;
-  static_assert(is_same<decltype(v14), const _Float16>::value, "");
-  static_assert(v14 == 1.F16, "");
-
-  static constexpr auto v15 = 1.e0f16;
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
-  // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16;
-  // CHECK-MESSAGES-NEXT: ^ ~
-  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
-  // CHECK-FIXES: static constexpr auto v15 = 1.e0F16;
-  static_assert(is_same<decltype(v15), const _Float16>::value, "");
-  static_assert(v15 == 1.F16, "");
-
-  static constexpr auto v16 = 1.F16; // OK.
-  static_assert(is_same<decltype(v16), const _Float16>::value, "");
-  static_assert(v16 == 1.F16, "");
-
-  static constexpr auto v17 = 1.e0F16; // OK.
-  static_assert(is_same<decltype(v17), const _Float16>::value, "");
-  static_assert(v17 == 1.F16, "");
 }
 
 void floating_point_complex_suffix() {
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
index 4cc9d6d..415c6d8 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp
@@ -93,21 +93,6 @@
   static constexpr auto v12 = 0xfp0Q; // OK.
   static_assert(is_same<decltype(v12), const __float128>::value, "");
   static_assert(v12 == 0xfp0, "");
-
-  // _Float16
-
-  static constexpr auto v13 = 0xfp0f16;
-  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
-  // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16;
-  // CHECK-MESSAGES-NEXT: ^    ~
-  // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
-  // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16;
-  static_assert(is_same<decltype(v13), const _Float16>::value, "");
-  static_assert(v13 == 0xfp0F16, "");
-
-  static constexpr auto v14 = 0xfp0F16; // OK.
-  static_assert(is_same<decltype(v14), const _Float16>::value, "");
-  static_assert(v14 == 0xfp0F16, "");
 }
 
 void floating_point_complex_suffix() {
diff --git a/test/clang-tidy/run-clang-tidy.cpp b/test/clang-tidy/run-clang-tidy.cpp
index 2207e43..31c4d68 100644
--- a/test/clang-tidy/run-clang-tidy.cpp
+++ b/test/clang-tidy/run-clang-tidy.cpp
@@ -1,3 +1,4 @@
+// RUN: %run_clang_tidy --help
 // RUN: rm -rf %t
 // RUN: mkdir %t
 // RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %/t/test.cpp\",\"file\":\"%/t/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
diff --git a/test/clang-tidy/static-analyzer-config.cpp b/test/clang-tidy/static-analyzer-config.cpp
index 9ca87cf..d07c0c3 100644
--- a/test/clang-tidy/static-analyzer-config.cpp
+++ b/test/clang-tidy/static-analyzer-config.cpp
@@ -1,5 +1,5 @@
 // REQUIRES: static-analyzer
-// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: true}]}' -- | FileCheck %s
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.DynamicMemoryModeling:Optimistic", value: true}]}' -- | FileCheck %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);
diff --git a/test/clangd/diagnostics.test b/test/clangd/diagnostics.test
deleted file mode 100644
index a191c08..0000000
--- a/test/clangd/diagnostics.test
+++ /dev/null
@@ -1,28 +0,0 @@
-# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
-{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
----
-{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
-#      CHECK:  "method": "textDocument/publishDiagnostics",
-# CHECK-NEXT:  "params": {
-# CHECK-NEXT:    "diagnostics": [
-# CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Return type of 'main' is not 'int'",
-# CHECK-NEXT:        "range": {
-# CHECK-NEXT:          "end": {
-# CHECK-NEXT:            "character": 4,
-# CHECK-NEXT:            "line": 0
-# CHECK-NEXT:          },
-# CHECK-NEXT:          "start": {
-# CHECK-NEXT:            "character": 0,
-# CHECK-NEXT:            "line": 0
-# CHECK-NEXT:          }
-# CHECK-NEXT:        },
-# CHECK-NEXT:        "severity": 2
-# CHECK-NEXT:      }
-# CHECK-NEXT:    ],
-# CHECK-NEXT:    "uri": "file://{{.*}}/foo.c"
-# CHECK-NEXT:  }
----
-{"jsonrpc":"2.0","id":5,"method":"shutdown"}
----
-{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/trace.test b/test/clangd/trace.test
deleted file mode 100644
index 83b040a..0000000
--- a/test/clangd/trace.test
+++ /dev/null
@@ -1,25 +0,0 @@
-# RUN: env CLANGD_TRACE=%t clangd -lit-test < %s && FileCheck %s < %t
-{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
----
-{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"c","version":1,"text":"void main() {}"}}}
-# These assertions are a bit loose, to avoid brittleness.
-# CHECK: {"displayTimeUnit":"ns","traceEvents":[
-# CHECK: {
-# CHECK:   "args": {
-# CHECK:     "File": "{{.*(/|\\)}}foo.c"
-# CHECK:   },
-# CHECK:   "name": "BuildPreamble",
-# CHECK:   "ph": "X",
-# CHECK: }
-# CHECK: {
-# CHECK:   "args": {
-# CHECK:     "File": "{{.*(/|\\)}}foo.c"
-# CHECK:   },
-# CHECK:   "name": "BuildAST",
-# CHECK:   "ph": "X",
-# CHECK: }
-# CHECK: },
----
-{"jsonrpc":"2.0","id":5,"method":"shutdown"}
----
-{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/include-fixer/include_path.cpp b/test/include-fixer/include_path.cpp
deleted file mode 100644
index 28b6ace..0000000
--- a/test/include-fixer/include_path.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: mkdir -p %T/include-fixer/include
-// RUN: mkdir -p %T/include-fixer/symbols
-// RUN: mkdir -p %T/include-fixer/build
-// RUN: mkdir -p %T/include-fixer/src
-// RUN: sed 's|test_dir|%/T/include-fixer|g' %S/Inputs/database_template.json > %T/include-fixer/build/compile_commands.json
-// RUN: echo -e '#include "bar.h"\nb::a::bar f;' > %T/include-fixer/src/bar.cpp
-// RUN: echo 'namespace b { namespace a { class bar {}; } }' > %T/include-fixer/include/bar.h
-// RUN: cd %T/include-fixer/build
-// RUN: find-all-symbols -output-dir=%T/include-fixer/symbols -p=. %T/include-fixer/src/bar.cpp
-// RUN: find-all-symbols -merge-dir=%T/include-fixer/symbols %T/include-fixer/build/find_all_symbols.yaml
-// RUN: FileCheck -input-file=%T/include-fixer/build/find_all_symbols.yaml -check-prefix=CHECK-YAML %s
-//
-// RUN: echo 'b::a::bar f;' > %T/include-fixer/src/bar.cpp
-// RUN: clang-include-fixer -db=yaml -input=%T/include-fixer/build/find_all_symbols.yaml -minimize-paths=true -p=. %T/include-fixer/src/bar.cpp
-// RUN: FileCheck -input-file=%T/include-fixer/src/bar.cpp %s
-
-// CHECK-YAML: ..{{[/\\]}}include{{[/\\]}}bar.h
-// CHECK: #include "bar.h"
-// CHECK: b::a::bar f;
diff --git a/test/include-fixer/multiple_fixes.cpp b/test/include-fixer/multiple_fixes.cpp
deleted file mode 100644
index 35a73b4..0000000
--- a/test/include-fixer/multiple_fixes.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: shell
-// RUN: sed -e 's#//.*$##' %s > %t.cpp
-// RUN: mkdir -p %T/include-fixer/multiple-fixes
-// RUN: echo 'foo f;' > %T/include-fixer/multiple-fixes/foo.cpp
-// RUN: echo 'bar b;' > %T/include-fixer/multiple-fixes/bar.cpp
-// RUN: clang-include-fixer -db=fixed -input='foo= "foo.h";bar= "bar.h"' %T/include-fixer/multiple-fixes/*.cpp --
-// RUN: FileCheck -input-file=%T/include-fixer/multiple-fixes/bar.cpp %s -check-prefix=CHECK-BAR
-// RUN: FileCheck -input-file=%T/include-fixer/multiple-fixes/foo.cpp %s -check-prefix=CHECK-FOO
-//
-// CHECK-FOO: #include "foo.h"
-// CHECK-FOO: foo f;
-// CHECK-BAR: #include "bar.h"
-// CHECK-BAR: bar b;
diff --git a/test/lit.cfg b/test/lit.cfg.py
similarity index 94%
rename from test/lit.cfg
rename to test/lit.cfg.py
index 7fe56f7..eaf0778 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg.py
@@ -99,11 +99,9 @@
 if lit_config.useValgrind:
     config.target_triple += '-vg'
 
+config.available_features.add('crash-recovery')
 # Set available features we allow tests to conditionalize on.
 #
-# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
-if platform.system() not in ['FreeBSD']:
-    config.available_features.add('crash-recovery')
 
 # Shell execution
 if execute_external:
@@ -117,10 +115,6 @@
 if platform.system() not in ['Windows']:
     config.available_features.add('ansi-escape-sequences')
 
-# XPC support for Clangd.
-if config.clangd_xpc_support:
-    config.available_features.add('clangd-xpc-support')
-
 if config.clang_staticanalyzer:
     config.available_features.add('static-analyzer')
 
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.py.in
similarity index 94%
rename from test/lit.site.cfg.in
rename to test/lit.site.cfg.py.in
index d71ca18..a970e7f 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.py.in
@@ -11,7 +11,6 @@
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.target_triple = "@TARGET_TRIPLE@"
 config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
-config.clangd_xpc_support = @CLANGD_BUILD_XPC_SUPPORT@
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
@@ -28,4 +27,4 @@
 lit.llvm.initialize(lit_config, config)
 
 # Let the main config do the real work.
-lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/lit.cfg")
+lit_config.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/lit.cfg.py")
diff --git a/test/modularize/ProblemsInconsistent.modularize b/test/modularize/ProblemsInconsistent.modularize
index 04d0b01..713bfe9 100644
--- a/test/modularize/ProblemsInconsistent.modularize
+++ b/test/modularize/ProblemsInconsistent.modularize
@@ -60,16 +60,6 @@
 # CHECK-NEXT:     {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
 # CHECK-NEXT:       {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
 # CHECK-NEXT: (no macro definition)
-# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:11:2
-# CHECK-NEXT: #if SYMBOL == 1
-# CHECK-NEXT: ^
-# CHECK-NEXT: error: Conditional expression instance 'SYMBOL == 1' has different values in this header, depending on how it was included.
-# CHECK-NEXT:   'SYMBOL == 1' expanded to: 'true' with respect to these inclusion paths:
-# CHECK-NEXT:     {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h
-# CHECK-NEXT:       {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
-# CHECK-NEXT:   'SYMBOL == 1' expanded to: 'false' with respect to these inclusion paths:
-# CHECK-NEXT:     {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h
-# CHECK-NEXT:       {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h
 # CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:2:2
 # CHECK-NEXT: #ifdef SYMBOL1
 # CHECK-NEXT: ^
diff --git a/test/pp-trace/pp-trace-conditional.cpp b/test/pp-trace/pp-trace-conditional.cpp
index ac5d3b3..0ad6c59 100644
--- a/test/pp-trace/pp-trace-conditional.cpp
+++ b/test/pp-trace/pp-trace-conditional.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged' %s -- -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
 
 #if 1
 #endif
@@ -79,14 +79,14 @@
 // CHECK-NEXT:   MacroDirective: MD_Define
 // CHECK:      - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Endif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:2"
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2"
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Endif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2"
@@ -95,7 +95,7 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Else
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:2"
@@ -107,7 +107,7 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:11:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Else
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:2"
@@ -119,11 +119,11 @@
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2"
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2"
 // CHECK-NEXT: - Callback: Endif
@@ -133,11 +133,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2"
 // CHECK-NEXT: - Callback: Endif
@@ -147,11 +147,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:26:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:7"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
 // CHECK-NEXT: - Callback: SourceRangeSkipped
@@ -161,11 +161,11 @@
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2"
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:7"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2"
 // CHECK-NEXT: - Callback: Endif
@@ -175,11 +175,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2"
 // CHECK-NEXT: - Callback: Endif
@@ -189,11 +189,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2"
 // CHECK-NEXT: - Callback: Endif
@@ -203,11 +203,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:7"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2"
 // CHECK-NEXT: - Callback: SourceRangeSkipped
@@ -222,11 +222,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:40:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:5"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:43:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:7"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
 // CHECK-NEXT: - Callback: Else
@@ -239,11 +239,11 @@
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2"
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:47:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2"
 // CHECK-NEXT: - Callback: Endif
@@ -253,11 +253,11 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:48:2"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:5"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Elif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:51:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:8"]
 // CHECK-NEXT:   ConditionValue: CVK_NotEvaluated
 // CHECK-NEXT:   IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2"
 // CHECK-NEXT: - Callback: Endif
diff --git a/test/pp-trace/pp-trace-filter.cpp b/test/pp-trace/pp-trace-filter.cpp
new file mode 100644
index 0000000..1cd2ce7
--- /dev/null
+++ b/test/pp-trace/pp-trace-filter.cpp
@@ -0,0 +1,17 @@
+// RUN: pp-trace -callbacks 'File*,Macro*,-MacroUndefined' %s -- | FileCheck %s
+// RUN: pp-trace -callbacks ' File* , Macro* , -MacroUndefined ' %s -- | FileCheck %s
+// RUN: not pp-trace -callbacks '[' %s -- 2>&1 | FileCheck --check-prefix=INVALID %s
+
+#define M 1
+int i = M;
+#undef M
+
+// CHECK:      ---
+// CHECK:      - Callback: FileChanged
+// CHECK:      - Callback: MacroDefined
+// CHECK:      - Callback: MacroExpands
+// CHECK-NOT:  - Callback: MacroUndefined
+// CHECK-NOT:  - Callback: EndOfMainFile
+// CHECK:      ...
+
+// INVALID: error: invalid glob pattern: [
diff --git a/test/pp-trace/pp-trace-ident.cpp b/test/pp-trace/pp-trace-ident.cpp
index 9981c39..cdd9fd3 100644
--- a/test/pp-trace/pp-trace-ident.cpp
+++ b/test/pp-trace/pp-trace-ident.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged,MacroDefined %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -- -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
 
 #ident "$Id$"
 
diff --git a/test/pp-trace/pp-trace-include.cpp b/test/pp-trace/pp-trace-include.cpp
index 7d925d8..ba6ad11 100644
--- a/test/pp-trace/pp-trace-include.cpp
+++ b/test/pp-trace/pp-trace-include.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+// RUN: pp-trace %s -- -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
 
 #include "Inputs/Level1A.h"
 #include "Inputs/Level1B.h"
diff --git a/test/pp-trace/pp-trace-macro.cpp b/test/pp-trace/pp-trace-macro.cpp
index e6ba761..47f9e1c 100644
--- a/test/pp-trace/pp-trace-macro.cpp
+++ b/test/pp-trace/pp-trace-macro.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged' %s -- -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s
 
 #define MACRO 1
 int i = MACRO;
@@ -44,7 +44,7 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:19"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:19"]
 // CHECK-NEXT:   ConditionValue: CVK_True
 // CHECK-NEXT: - Callback: Endif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:2"
@@ -58,7 +58,7 @@
 // CHECK-NEXT:   Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:19"]
 // CHECK-NEXT: - Callback: If
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:2"
-// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:1"]
+// CHECK-NEXT:   ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:19"]
 // CHECK-NEXT:   ConditionValue: CVK_False
 // CHECK-NEXT: - Callback: Endif
 // CHECK-NEXT:   Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:2"
diff --git a/test/pp-trace/pp-trace-modules.cpp b/test/pp-trace/pp-trace-modules.cpp
index 5e9e1de..32d6c48 100644
--- a/test/pp-trace/pp-trace-modules.cpp
+++ b/test/pp-trace/pp-trace-modules.cpp
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t
-// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -- -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s
 
 // CHECK: ---
 
diff --git a/test/pp-trace/pp-trace-pragma-general.cpp b/test/pp-trace/pp-trace-pragma-general.cpp
index 6caef0b..f01ebd1 100644
--- a/test/pp-trace/pp-trace-pragma-general.cpp
+++ b/test/pp-trace/pp-trace-pragma-general.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged,MacroDefined %s | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -- | FileCheck --strict-whitespace %s
 
 #pragma clang diagnostic push
 #pragma clang diagnostic pop
diff --git a/test/pp-trace/pp-trace-pragma-ms.cpp b/test/pp-trace/pp-trace-pragma-ms.cpp
index 33c9f7f..5df30ad 100644
--- a/test/pp-trace/pp-trace-pragma-ms.cpp
+++ b/test/pp-trace/pp-trace-pragma-ms.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged,MacroDefined %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -- -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s
 
 #pragma comment(compiler, "compiler comment")
 #pragma comment(exestr, "exestr comment")
diff --git a/test/pp-trace/pp-trace-pragma-opencl.cpp b/test/pp-trace/pp-trace-pragma-opencl.cpp
index cfd72c0..8ba26c3 100644
--- a/test/pp-trace/pp-trace-pragma-opencl.cpp
+++ b/test/pp-trace/pp-trace-pragma-opencl.cpp
@@ -1,4 +1,4 @@
-// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x cl | FileCheck --strict-whitespace %s
+// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -- -x cl | FileCheck --strict-whitespace %s
 
 #pragma OPENCL EXTENSION all : disable
 #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : disable
diff --git a/tool-template/ToolTemplate.cpp b/tool-template/ToolTemplate.cpp
index 66ec2e8..3220eb3 100644
--- a/tool-template/ToolTemplate.cpp
+++ b/tool-template/ToolTemplate.cpp
@@ -1,9 +1,8 @@
 //===---- tools/extra/ToolTemplate.cpp - Template for refactoring tool ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 9e01473..086a68e 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -5,20 +5,10 @@
   add_unittest(ExtraToolsUnitTests ${test_dirname} ${ARGN})
 endfunction()
 
-if(CLANG_BUILT_STANDALONE)
-  # LLVMTestingSupport library is needed for clangd tests.
-  if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
-      AND NOT TARGET LLVMTestingSupport)
-    add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
-      lib/Testing/Support)
-  endif()
-endif()
-
-add_subdirectory(change-namespace)
 add_subdirectory(clang-apply-replacements)
+add_subdirectory(clang-change-namespace)
 add_subdirectory(clang-doc)
+add_subdirectory(clang-include-fixer)
 add_subdirectory(clang-move)
 add_subdirectory(clang-query)
 add_subdirectory(clang-tidy)
-add_subdirectory(clangd)
-add_subdirectory(include-fixer)
diff --git a/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp b/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
index 85aaebf..0a2a677 100644
--- a/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
+++ b/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
@@ -1,10 +1,9 @@
 //===- clang-apply-replacements/ApplyReplacementsTest.cpp
 //----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +26,6 @@
   TUs.push_back({MainSourceFile,
                  {{DiagnosticName,
                    Message,
-                   Replacements,
                    {},
                    Diagnostic::Warning,
                    BuildDirectory}}});
diff --git a/unittests/change-namespace/CMakeLists.txt b/unittests/clang-change-namespace/CMakeLists.txt
similarity index 74%
rename from unittests/change-namespace/CMakeLists.txt
rename to unittests/clang-change-namespace/CMakeLists.txt
index dc5f59d..9c94972 100644
--- a/unittests/change-namespace/CMakeLists.txt
+++ b/unittests/clang-change-namespace/CMakeLists.txt
@@ -3,7 +3,7 @@
   )
 
 get_filename_component(CHANGE_NAMESPACE_SOURCE_DIR
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../change-namespace REALPATH)
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-change-namespace REALPATH)
 include_directories(
   ${CHANGE_NAMESPACE_SOURCE_DIR}
   )
@@ -11,11 +11,11 @@
 # We'd like clang/unittests/Tooling/RewriterTestContext.h in the test.
 include_directories(${CLANG_SOURCE_DIR})
 
-add_extra_unittest(ChangeNamespaceTests
+add_extra_unittest(ClangChangeNamespaceTests
   ChangeNamespaceTests.cpp
   )
 
-target_link_libraries(ChangeNamespaceTests
+target_link_libraries(ClangChangeNamespaceTests
   PRIVATE
   clangAST
   clangASTMatchers
diff --git a/unittests/change-namespace/ChangeNamespaceTests.cpp b/unittests/clang-change-namespace/ChangeNamespaceTests.cpp
similarity index 99%
rename from unittests/change-namespace/ChangeNamespaceTests.cpp
rename to unittests/clang-change-namespace/ChangeNamespaceTests.cpp
index 4008600..d66fede 100644
--- a/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ b/unittests/clang-change-namespace/ChangeNamespaceTests.cpp
@@ -1,9 +1,8 @@
 //===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/BitcodeTest.cpp b/unittests/clang-doc/BitcodeTest.cpp
index 26bdf9e..c89a649 100644
--- a/unittests/clang-doc/BitcodeTest.cpp
+++ b/unittests/clang-doc/BitcodeTest.cpp
@@ -1,9 +1,8 @@
 //===-- clang-doc/BitcodeTest.cpp -----------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/ClangDocTest.cpp b/unittests/clang-doc/ClangDocTest.cpp
index e763d35..99ea76b 100644
--- a/unittests/clang-doc/ClangDocTest.cpp
+++ b/unittests/clang-doc/ClangDocTest.cpp
@@ -1,9 +1,8 @@
 //===-- clang-doc/ClangDocTest.cpp ----------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/ClangDocTest.h b/unittests/clang-doc/ClangDocTest.h
index 1cc0619..d9f3a65 100644
--- a/unittests/clang-doc/ClangDocTest.h
+++ b/unittests/clang-doc/ClangDocTest.h
@@ -1,9 +1,8 @@
 //===-- clang-doc/ClangDocTest.h ------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/MDGeneratorTest.cpp b/unittests/clang-doc/MDGeneratorTest.cpp
index aa624ba..233ec6e 100644
--- a/unittests/clang-doc/MDGeneratorTest.cpp
+++ b/unittests/clang-doc/MDGeneratorTest.cpp
@@ -1,9 +1,8 @@
 //===-- clang-doc/MDGeneratorTest.cpp -------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/MergeTest.cpp b/unittests/clang-doc/MergeTest.cpp
index ab3afa8..7adc1f3 100644
--- a/unittests/clang-doc/MergeTest.cpp
+++ b/unittests/clang-doc/MergeTest.cpp
@@ -1,9 +1,8 @@
 //===-- clang-doc/MergeTest.cpp -------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/SerializeTest.cpp b/unittests/clang-doc/SerializeTest.cpp
index d5bf8f1..1c044f7 100644
--- a/unittests/clang-doc/SerializeTest.cpp
+++ b/unittests/clang-doc/SerializeTest.cpp
@@ -1,9 +1,8 @@
 //===-- clang-doc/SerializeTest.cpp ---------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-doc/YAMLGeneratorTest.cpp b/unittests/clang-doc/YAMLGeneratorTest.cpp
index a4ac5df..8a1ba46 100644
--- a/unittests/clang-doc/YAMLGeneratorTest.cpp
+++ b/unittests/clang-doc/YAMLGeneratorTest.cpp
@@ -1,10 +1,9 @@
 //===-- clang-doc/YAMLGeneratorTest.cpp
 //------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/include-fixer/CMakeLists.txt b/unittests/clang-include-fixer/CMakeLists.txt
similarity index 77%
rename from unittests/include-fixer/CMakeLists.txt
rename to unittests/clang-include-fixer/CMakeLists.txt
index c084a4d..997aa14 100644
--- a/unittests/include-fixer/CMakeLists.txt
+++ b/unittests/clang-include-fixer/CMakeLists.txt
@@ -3,7 +3,7 @@
   )
 
 get_filename_component(INCLUDE_FIXER_SOURCE_DIR
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../include-fixer REALPATH)
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-include-fixer REALPATH)
 include_directories(
   ${INCLUDE_FIXER_SOURCE_DIR}
   )
@@ -11,12 +11,12 @@
 # We'd like to clang/unittests/Tooling/RewriterTestContext.h in the test.
 include_directories(${CLANG_SOURCE_DIR})
 
-add_extra_unittest(IncludeFixerTests
+add_extra_unittest(ClangIncludeFixerTests
   IncludeFixerTest.cpp
   FuzzySymbolIndexTests.cpp
   )
 
-target_link_libraries(IncludeFixerTests
+target_link_libraries(ClangIncludeFixerTests
   PRIVATE
   clangBasic
   clangFormat
diff --git a/unittests/include-fixer/FuzzySymbolIndexTests.cpp b/unittests/clang-include-fixer/FuzzySymbolIndexTests.cpp
similarity index 90%
rename from unittests/include-fixer/FuzzySymbolIndexTests.cpp
rename to unittests/clang-include-fixer/FuzzySymbolIndexTests.cpp
index 17679c5..3886269 100644
--- a/unittests/include-fixer/FuzzySymbolIndexTests.cpp
+++ b/unittests/clang-include-fixer/FuzzySymbolIndexTests.cpp
@@ -1,9 +1,8 @@
 //===-- FuzzySymbolIndexTests.cpp - Fuzzy symbol index unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/include-fixer/IncludeFixerTest.cpp b/unittests/clang-include-fixer/IncludeFixerTest.cpp
similarity index 97%
rename from unittests/include-fixer/IncludeFixerTest.cpp
rename to unittests/clang-include-fixer/IncludeFixerTest.cpp
index 519c083..ab7ef79 100644
--- a/unittests/include-fixer/IncludeFixerTest.cpp
+++ b/unittests/clang-include-fixer/IncludeFixerTest.cpp
@@ -1,9 +1,8 @@
 //===-- IncludeFixerTest.cpp - Include fixer unit tests -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -179,7 +178,7 @@
   EXPECT_EQ("#define FOO(x) a::##x\nint x = FOO(b::foo);\n",
             runIncludeFixer("#define FOO(x) a::##x\nint x = FOO(b::foo);\n"));
 
-  // The empty namespace is cleaned up by clang-format after include-fixer
+  // The empty namespace is cleaned up by clang-format after clang-include-fixer
   // finishes.
   EXPECT_EQ("#include \"dir/otherdir/qux.h\"\n"
             "\nint a = a::b::foo(0);\n",
@@ -228,7 +227,7 @@
 }
 
 // FIXME: add test cases for inserting and sorting multiple headers when
-// include-fixer supports multiple headers insertion.
+// clang-include-fixer supports multiple headers insertion.
 TEST(IncludeFixer, InsertAndSortSingleHeader) {
   // Insert one header.
   std::string Code = "#include \"a.h\"\n"
diff --git a/unittests/include-fixer/find-all-symbols/CMakeLists.txt b/unittests/clang-include-fixer/find-all-symbols/CMakeLists.txt
similarity index 81%
rename from unittests/include-fixer/find-all-symbols/CMakeLists.txt
rename to unittests/clang-include-fixer/find-all-symbols/CMakeLists.txt
index 6a5472e..427aa8e 100644
--- a/unittests/include-fixer/find-all-symbols/CMakeLists.txt
+++ b/unittests/clang-include-fixer/find-all-symbols/CMakeLists.txt
@@ -3,7 +3,7 @@
   )
 
 get_filename_component(INCLUDE_FIXER_SOURCE_DIR
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../../include-fixer/find-all-symbols REALPATH)
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../../clang-include-fixer/find-all-symbols REALPATH)
 include_directories(
   ${INCLUDE_FIXER_SOURCE_DIR}
   )
diff --git a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp b/unittests/clang-include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
similarity index 98%
rename from unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
rename to unittests/clang-include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
index 1ad9e7f..179ad25 100644
--- a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
+++ b/unittests/clang-include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
@@ -1,9 +1,8 @@
 //===-- FindAllSymbolsTests.cpp - find all symbols unit tests ---*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-move/ClangMoveTests.cpp b/unittests/clang-move/ClangMoveTests.cpp
index 97c7ce0..721ffd9 100644
--- a/unittests/clang-move/ClangMoveTests.cpp
+++ b/unittests/clang-move/ClangMoveTests.cpp
@@ -1,13 +1,12 @@
-//===-- ClangMoveTest.cpp - clang-move unit tests -------------------------===//
+//===-- ClangMoveTests.cpp - clang-move unit tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "ClangMove.h"
+#include "Move.h"
 #include "unittests/Tooling/RewriterTestContext.h"
 #include "clang/Format/Format.h"
 #include "clang/Frontend/FrontendActions.h"
diff --git a/unittests/clang-query/QueryEngineTest.cpp b/unittests/clang-query/QueryEngineTest.cpp
index c1d67a1..6d728ce 100644
--- a/unittests/clang-query/QueryEngineTest.cpp
+++ b/unittests/clang-query/QueryEngineTest.cpp
@@ -1,9 +1,8 @@
-//===---- QueryTest.cpp - clang-query test --------------------------------===//
+//===-- QueryEngineTest.cpp - clang-query test ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-query/QueryParserTest.cpp b/unittests/clang-query/QueryParserTest.cpp
index d4c384c..01c6545 100644
--- a/unittests/clang-query/QueryParserTest.cpp
+++ b/unittests/clang-query/QueryParserTest.cpp
@@ -1,9 +1,8 @@
 //===---- QueryParserTest.cpp - clang-query test --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-tidy/CMakeLists.txt b/unittests/clang-tidy/CMakeLists.txt
index 648f0c5..614f84c 100644
--- a/unittests/clang-tidy/CMakeLists.txt
+++ b/unittests/clang-tidy/CMakeLists.txt
@@ -16,7 +16,8 @@
   ObjCModuleTest.cpp
   OverlappingReplacementsTest.cpp
   UsingInserterTest.cpp
-  ReadabilityModuleTest.cpp)
+  ReadabilityModuleTest.cpp
+  )
 
 target_link_libraries(ClangTidyTests
   PRIVATE
diff --git a/unittests/clang-tidy/ClangTidyTest.h b/unittests/clang-tidy/ClangTidyTest.h
index 32bb53c..560b0ff 100644
--- a/unittests/clang-tidy/ClangTidyTest.h
+++ b/unittests/clang-tidy/ClangTidyTest.h
@@ -1,9 +1,8 @@
 //===--- ClangTidyTest.h - clang-tidy ---------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,6 +14,8 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/Optional.h"
@@ -40,9 +41,10 @@
     Context.setCurrentFile(File);
     Context.setASTContext(&Compiler.getASTContext());
 
+    Preprocessor *PP = &Compiler.getPreprocessor();
     for (auto &Check : Checks) {
       Check->registerMatchers(&Finder);
-      Check->registerPPCallbacks(Compiler);
+      Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
     }
     return Finder.newASTConsumer();
   }
@@ -130,16 +132,17 @@
   tooling::Replacements Fixes;
   std::vector<ClangTidyError> Diags = DiagConsumer.take();
   for (const ClangTidyError &Error : Diags) {
-    for (const auto &FileAndFixes : Error.Fix) {
-      for (const auto &Fix : FileAndFixes.second) {
-        auto Err = Fixes.add(Fix);
-        // FIXME: better error handling. Keep the behavior for now.
-        if (Err) {
-          llvm::errs() << llvm::toString(std::move(Err)) << "\n";
-          return "";
+    if (const auto *ChosenFix = tooling::selectFirstFix(Error))
+      for (const auto &FileAndFixes : *ChosenFix) {
+        for (const auto &Fix : FileAndFixes.second) {
+          auto Err = Fixes.add(Fix);
+          // FIXME: better error handling. Keep the behavior for now.
+          if (Err) {
+            llvm::errs() << llvm::toString(std::move(Err)) << "\n";
+            return "";
+          }
         }
       }
-    }
   }
   if (Errors)
     *Errors = std::move(Diags);
diff --git a/unittests/clang-tidy/IncludeInserterTest.cpp b/unittests/clang-tidy/IncludeInserterTest.cpp
index 7a70f66..89b2567 100644
--- a/unittests/clang-tidy/IncludeInserterTest.cpp
+++ b/unittests/clang-tidy/IncludeInserterTest.cpp
@@ -1,9 +1,8 @@
 //===---- IncludeInserterTest.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -32,12 +31,11 @@
   IncludeInserterCheckBase(StringRef CheckName, ClangTidyContext *Context)
       : ClangTidyCheck(CheckName, Context) {}
 
-  void registerPPCallbacks(CompilerInstance &Compiler) override {
-    Inserter.reset(new utils::IncludeInserter(
-        Compiler.getSourceManager(),
-        Compiler.getLangOpts(),
-        utils::IncludeSorter::IS_Google));
-    Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override {
+    Inserter = llvm::make_unique<utils::IncludeInserter>(
+        SM, getLangOpts(), utils::IncludeSorter::IS_Google);
+    PP->addPPCallbacks(Inserter->CreatePPCallbacks());
   }
 
   void registerMatchers(ast_matchers::MatchFinder *Finder) override {
diff --git a/unittests/clang-tidy/NamespaceAliaserTest.cpp b/unittests/clang-tidy/NamespaceAliaserTest.cpp
index e4f8ebc..e4cd74e 100644
--- a/unittests/clang-tidy/NamespaceAliaserTest.cpp
+++ b/unittests/clang-tidy/NamespaceAliaserTest.cpp
@@ -1,10 +1,9 @@
 //===---- NamespaceAliaserTest.cpp - clang-tidy
 //----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-tidy/ObjCModuleTest.cpp b/unittests/clang-tidy/ObjCModuleTest.cpp
index 92ae8e1..826978b 100644
--- a/unittests/clang-tidy/ObjCModuleTest.cpp
+++ b/unittests/clang-tidy/ObjCModuleTest.cpp
@@ -1,9 +1,8 @@
 //===---- ObjCModuleTest.cpp - clang-tidy ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-tidy/OverlappingReplacementsTest.cpp b/unittests/clang-tidy/OverlappingReplacementsTest.cpp
index 87213b1..3aaf549 100644
--- a/unittests/clang-tidy/OverlappingReplacementsTest.cpp
+++ b/unittests/clang-tidy/OverlappingReplacementsTest.cpp
@@ -1,9 +1,8 @@
 //===---- OverlappingReplacementsTest.cpp - clang-tidy --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-tidy/UsingInserterTest.cpp b/unittests/clang-tidy/UsingInserterTest.cpp
index 16d2519..71c7159 100644
--- a/unittests/clang-tidy/UsingInserterTest.cpp
+++ b/unittests/clang-tidy/UsingInserterTest.cpp
@@ -1,9 +1,8 @@
 //===---- UsingInserterTest.cpp - clang-tidy ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clangd/Annotations.cpp b/unittests/clangd/Annotations.cpp
deleted file mode 100644
index 474ba05..0000000
--- a/unittests/clangd/Annotations.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===--- Annotations.cpp - Annotated source code for unit tests --*- C++-*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Annotations.h"
-#include "SourceCode.h"
-
-namespace clang {
-namespace clangd {
-
-// Crash if the assertion fails, printing the message and testcase.
-// More elegant error handling isn't needed for unit tests.
-static void require(bool Assertion, const char *Msg, llvm::StringRef Code) {
-  if (!Assertion) {
-    llvm::errs() << "Annotated testcase: " << Msg << "\n" << Code << "\n";
-    llvm_unreachable("Annotated testcase assertion failed!");
-  }
-}
-
-Annotations::Annotations(llvm::StringRef Text) {
-  auto Here = [this] { return offsetToPosition(Code, Code.size()); };
-  auto Require = [Text](bool Assertion, const char *Msg) {
-    require(Assertion, Msg, Text);
-  };
-  llvm::Optional<llvm::StringRef> Name;
-  llvm::SmallVector<std::pair<llvm::StringRef, Position>, 8> OpenRanges;
-
-  Code.reserve(Text.size());
-  while (!Text.empty()) {
-    if (Text.consume_front("^")) {
-      Points[Name.getValueOr("")].push_back(Here());
-      Name = None;
-      continue;
-    }
-    if (Text.consume_front("[[")) {
-      OpenRanges.emplace_back(Name.getValueOr(""), Here());
-      Name = None;
-      continue;
-    }
-    Require(!Name, "$name should be followed by ^ or [[");
-    if (Text.consume_front("]]")) {
-      Require(!OpenRanges.empty(), "unmatched ]]");
-      Ranges[OpenRanges.back().first].push_back(
-          {OpenRanges.back().second, Here()});
-      OpenRanges.pop_back();
-      continue;
-    }
-    if (Text.consume_front("$")) {
-      Name = Text.take_while(llvm::isAlnum);
-      Text = Text.drop_front(Name->size());
-      continue;
-    }
-    Code.push_back(Text.front());
-    Text = Text.drop_front();
-  }
-  Require(!Name, "unterminated $name");
-  Require(OpenRanges.empty(), "unmatched [[");
-}
-
-Position Annotations::point(llvm::StringRef Name) const {
-  auto I = Points.find(Name);
-  require(I != Points.end() && I->getValue().size() == 1,
-          "expected exactly one point", Code);
-  return I->getValue()[0];
-}
-std::vector<Position> Annotations::points(llvm::StringRef Name) const {
-  auto P = Points.lookup(Name);
-  return {P.begin(), P.end()};
-}
-Range Annotations::range(llvm::StringRef Name) const {
-  auto I = Ranges.find(Name);
-  require(I != Ranges.end() && I->getValue().size() == 1,
-          "expected exactly one range", Code);
-  return I->getValue()[0];
-}
-std::vector<Range> Annotations::ranges(llvm::StringRef Name) const {
-  auto R = Ranges.lookup(Name);
-  return {R.begin(), R.end()};
-}
-
-} // namespace clangd
-} // namespace clang
diff --git a/unittests/clangd/Annotations.h b/unittests/clangd/Annotations.h
deleted file mode 100644
index 4d787c2..0000000
--- a/unittests/clangd/Annotations.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Annotations lets you mark points and ranges inside source code, for tests:
-//
-//    Annotations Example(R"cpp(
-//       int complete() { x.pri^ }          // ^ indicates a point
-//       void err() { [["hello" == 42]]; }  // [[this is a range]]
-//       $definition^class Foo{};           // points can be named: "definition"
-//       $fail[[static_assert(false, "")]]  // ranges can be named too: "fail"
-//    )cpp");
-//
-//    StringRef Code = Example.code();              // annotations stripped.
-//    std::vector<Position> PP = Example.points();  // all unnamed points
-//    Position P = Example.point();                 // there must be exactly one
-//    Range R = Example.range("fail");              // find named ranges
-//
-// Points/ranges are coordinates into `code()` which is stripped of annotations.
-//
-// Ranges may be nested (and points can be inside ranges), but there's no way
-// to define general overlapping ranges.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
-#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
-
-#include "Protocol.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace clangd {
-
-class Annotations {
-public:
-  // Parses the annotations from Text. Crashes if it's malformed.
-  Annotations(llvm::StringRef Text);
-
-  // The input text with all annotations stripped.
-  // All points and ranges are relative to this stripped text.
-  llvm::StringRef code() const { return Code; }
-
-  // Returns the position of the point marked by ^ (or $name^) in the text.
-  // Crashes if there isn't exactly one.
-  Position point(llvm::StringRef Name = "") const;
-  // Returns the position of all points marked by ^ (or $name^) in the text.
-  std::vector<Position> points(llvm::StringRef Name = "") const;
-
-  // Returns the location of the range marked by [[ ]] (or $name[[ ]]).
-  // Crashes if there isn't exactly one.
-  Range range(llvm::StringRef Name = "") const;
-  // Returns the location of all ranges marked by [[ ]] (or $name[[ ]]).
-  std::vector<Range> ranges(llvm::StringRef Name = "") const;
-
-private:
-  std::string Code;
-  llvm::StringMap<llvm::SmallVector<Position, 1>> Points;
-  llvm::StringMap<llvm::SmallVector<Range, 1>> Ranges;
-};
-
-} // namespace clangd
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_ANNOTATIONS_H
diff --git a/unittests/clangd/ClangdUnitTests.cpp b/unittests/clangd/ClangdUnitTests.cpp
deleted file mode 100644
index d0b85fd..0000000
--- a/unittests/clangd/ClangdUnitTests.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-//===-- ClangdUnitTests.cpp - ClangdUnit tests ------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Annotations.h"
-#include "ClangdUnit.h"
-#include "SourceCode.h"
-#include "TestTU.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace clangd {
-namespace {
-
-using testing::ElementsAre;
-using testing::Field;
-using testing::IsEmpty;
-using testing::Pair;
-using testing::UnorderedElementsAre;
-
-testing::Matcher<const Diag &> WithFix(testing::Matcher<Fix> FixMatcher) {
-  return Field(&Diag::Fixes, ElementsAre(FixMatcher));
-}
-
-testing::Matcher<const Diag &> WithNote(testing::Matcher<Note> NoteMatcher) {
-  return Field(&Diag::Notes, ElementsAre(NoteMatcher));
-}
-
-MATCHER_P2(Diag, Range, Message,
-           "Diag at " + llvm::to_string(Range) + " = [" + Message + "]") {
-  return arg.Range == Range && arg.Message == Message;
-}
-
-MATCHER_P3(Fix, Range, Replacement, Message,
-           "Fix " + llvm::to_string(Range) + " => " +
-               testing::PrintToString(Replacement) + " = [" + Message + "]") {
-  return arg.Message == Message && arg.Edits.size() == 1 &&
-         arg.Edits[0].range == Range && arg.Edits[0].newText == Replacement;
-}
-
-MATCHER_P(EqualToLSPDiag, LSPDiag,
-          "LSP diagnostic " + llvm::to_string(LSPDiag)) {
-  return std::tie(arg.range, arg.severity, arg.message) ==
-         std::tie(LSPDiag.range, LSPDiag.severity, LSPDiag.message);
-}
-
-MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) {
-  if (arg.Message != Fix.Message)
-    return false;
-  if (arg.Edits.size() != Fix.Edits.size())
-    return false;
-  for (std::size_t I = 0; I < arg.Edits.size(); ++I) {
-    if (arg.Edits[I].range != Fix.Edits[I].range ||
-        arg.Edits[I].newText != Fix.Edits[I].newText)
-      return false;
-  }
-  return true;
-}
-
-// Helper function to make tests shorter.
-Position pos(int line, int character) {
-  Position Res;
-  Res.line = line;
-  Res.character = character;
-  return Res;
-}
-
-TEST(DiagnosticsTest, DiagnosticRanges) {
-  // Check we report correct ranges, including various edge-cases.
-  Annotations Test(R"cpp(
-    namespace test{};
-    void $decl[[foo]]();
-    int main() {
-      $typo[[go\
-o]]();
-      foo()$semicolon[[]]//with comments
-      $unk[[unknown]]();
-      double $type[[bar]] = "foo";
-      struct Foo { int x; }; Foo a;
-      a.$nomember[[y]];
-      test::$nomembernamespace[[test]];
-    }
-  )cpp");
-  EXPECT_THAT(
-      TestTU::withCode(Test.code()).build().getDiagnostics(),
-      ElementsAre(
-          // This range spans lines.
-          AllOf(Diag(Test.range("typo"),
-                     "use of undeclared identifier 'goo'; did you mean 'foo'?"),
-                WithFix(
-                    Fix(Test.range("typo"), "foo", "change 'go\\ o' to 'foo'")),
-                // This is a pretty normal range.
-                WithNote(Diag(Test.range("decl"), "'foo' declared here"))),
-          // This range is zero-width and insertion. Therefore make sure we are
-          // not expanding it into other tokens. Since we are not going to
-          // replace those.
-          AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"),
-                WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))),
-          // This range isn't provided by clang, we expand to the token.
-          Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"),
-          Diag(Test.range("type"),
-               "cannot initialize a variable of type 'double' with an lvalue "
-               "of type 'const char [4]'"),
-          Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"),
-          Diag(Test.range("nomembernamespace"),
-               "no member named 'test' in namespace 'test'")));
-}
-
-TEST(DiagnosticsTest, FlagsMatter) {
-  Annotations Test("[[void]] main() {}");
-  auto TU = TestTU::withCode(Test.code());
-  EXPECT_THAT(TU.build().getDiagnostics(),
-              ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"),
-                                WithFix(Fix(Test.range(), "int",
-                                            "change 'void' to 'int'")))));
-  // Same code built as C gets different diagnostics.
-  TU.Filename = "Plain.c";
-  EXPECT_THAT(
-      TU.build().getDiagnostics(),
-      ElementsAre(AllOf(
-          Diag(Test.range(), "return type of 'main' is not 'int'"),
-          WithFix(Fix(Test.range(), "int", "change return type to 'int'")))));
-}
-
-TEST(DiagnosticsTest, ClangTidy) {
-  Annotations Test(R"cpp(
-    #include $deprecated[["assert.h"]]
-
-    #define $macrodef[[SQUARE]](X) (X)*(X)
-    int main() {
-      return $doubled[[sizeof]](sizeof(int));
-      int y = 4;
-      return SQUARE($macroarg[[++]]y);
-    }
-  )cpp");
-  auto TU = TestTU::withCode(Test.code());
-  TU.HeaderFilename = "assert.h"; // Suppress "not found" error.
-  EXPECT_THAT(
-      TU.build().getDiagnostics(),
-      UnorderedElementsAre(
-          AllOf(Diag(Test.range("deprecated"),
-                     "inclusion of deprecated C++ header 'assert.h'; consider "
-                     "using 'cassert' instead [modernize-deprecated-headers]"),
-                WithFix(Fix(Test.range("deprecated"), "<cassert>",
-                            "change '\"assert.h\"' to '<cassert>'"))),
-          Diag(Test.range("doubled"),
-               "suspicious usage of 'sizeof(sizeof(...))' "
-               "[bugprone-sizeof-expression]"),
-          AllOf(
-              Diag(Test.range("macroarg"),
-                   "side effects in the 1st macro argument 'X' are repeated in "
-                   "macro expansion [bugprone-macro-repeated-side-effects]"),
-              WithNote(Diag(Test.range("macrodef"),
-                            "macro 'SQUARE' defined here "
-                            "[bugprone-macro-repeated-side-effects]"))),
-          Diag(Test.range("macroarg"),
-               "multiple unsequenced modifications to 'y'")));
-}
-
-TEST(DiagnosticsTest, Preprocessor) {
-  // This looks like a preamble, but there's an #else in the middle!
-  // Check that:
-  //  - the #else doesn't generate diagnostics (we had this bug)
-  //  - we get diagnostics from the taken branch
-  //  - we get no diagnostics from the not taken branch
-  Annotations Test(R"cpp(
-    #ifndef FOO
-    #define FOO
-      int a = [[b]];
-    #else
-      int x = y;
-    #endif
-    )cpp");
-  EXPECT_THAT(
-      TestTU::withCode(Test.code()).build().getDiagnostics(),
-      ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'")));
-}
-
-TEST(DiagnosticsTest, InsideMacros) {
-  Annotations Test(R"cpp(
-    #define TEN 10
-    #define RET(x) return x + 10
-
-    int* foo() {
-      RET($foo[[0]]);
-    }
-    int* bar() {
-      return $bar[[TEN]];
-    }
-    )cpp");
-  EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(),
-              ElementsAre(Diag(Test.range("foo"),
-                               "cannot initialize return object of type "
-                               "'int *' with an rvalue of type 'int'"),
-                          Diag(Test.range("bar"),
-                               "cannot initialize return object of type "
-                               "'int *' with an rvalue of type 'int'")));
-}
-
-TEST(DiagnosticsTest, ToLSP) {
-  clangd::Diag D;
-  D.Message = "something terrible happened";
-  D.Range = {pos(1, 2), pos(3, 4)};
-  D.InsideMainFile = true;
-  D.Severity = DiagnosticsEngine::Error;
-  D.File = "foo/bar/main.cpp";
-
-  clangd::Note NoteInMain;
-  NoteInMain.Message = "declared somewhere in the main file";
-  NoteInMain.Range = {pos(5, 6), pos(7, 8)};
-  NoteInMain.Severity = DiagnosticsEngine::Remark;
-  NoteInMain.File = "../foo/bar/main.cpp";
-  NoteInMain.InsideMainFile = true;
-  D.Notes.push_back(NoteInMain);
-
-  clangd::Note NoteInHeader;
-  NoteInHeader.Message = "declared somewhere in the header file";
-  NoteInHeader.Range = {pos(9, 10), pos(11, 12)};
-  NoteInHeader.Severity = DiagnosticsEngine::Note;
-  NoteInHeader.File = "../foo/baz/header.h";
-  NoteInHeader.InsideMainFile = false;
-  D.Notes.push_back(NoteInHeader);
-
-  clangd::Fix F;
-  F.Message = "do something";
-  D.Fixes.push_back(F);
-
-  auto MatchingLSP = [](const DiagBase &D, StringRef Message) {
-    clangd::Diagnostic Res;
-    Res.range = D.Range;
-    Res.severity = getSeverity(D.Severity);
-    Res.message = Message;
-    return Res;
-  };
-
-  // Diagnostics should turn into these:
-  clangd::Diagnostic MainLSP = MatchingLSP(D, R"(Something terrible happened
-
-main.cpp:6:7: remark: declared somewhere in the main file
-
-../foo/baz/header.h:10:11:
-note: declared somewhere in the header file)");
-
-  clangd::Diagnostic NoteInMainLSP =
-      MatchingLSP(NoteInMain, R"(Declared somewhere in the main file
-
-main.cpp:2:3: error: something terrible happened)");
-
-  // Transform dianostics and check the results.
-  std::vector<std::pair<clangd::Diagnostic, std::vector<clangd::Fix>>> LSPDiags;
-  toLSPDiags(D,
-#ifdef _WIN32
-             URIForFile::canonicalize("c:\\path\\to\\foo\\bar\\main.cpp",
-                                      /*TUPath=*/""),
-#else
-      URIForFile::canonicalize("/path/to/foo/bar/main.cpp", /*TUPath=*/""),
-#endif
-             ClangdDiagnosticOptions(),
-             [&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix> Fixes) {
-               LSPDiags.push_back(
-                   {std::move(LSPDiag),
-                    std::vector<clangd::Fix>(Fixes.begin(), Fixes.end())});
-             });
-
-  EXPECT_THAT(
-      LSPDiags,
-      ElementsAre(Pair(EqualToLSPDiag(MainLSP), ElementsAre(EqualToFix(F))),
-                  Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty())));
-}
-
-TEST(ClangdUnitTest, GetBeginningOfIdentifier) {
-  std::string Preamble = R"cpp(
-struct Bar { int func(); };
-#define MACRO(X) void f() { X; }
-Bar* bar;
-  )cpp";
-  // First ^ is the expected beginning, last is the search position.
-  for (std::string Text : std::vector<std::string>{
-           "int ^f^oo();", // inside identifier
-           "int ^foo();",  // beginning of identifier
-           "int ^foo^();", // end of identifier
-           "int foo(^);",  // non-identifier
-           "^int foo();",  // beginning of file (can't back up)
-           "int ^f0^0();", // after a digit (lexing at N-1 is wrong)
-           "int ^λλ^λ();", // UTF-8 handled properly when backing up
-
-           // identifier in macro arg
-           "MACRO(bar->^func())",  // beginning of identifier
-           "MACRO(bar->^fun^c())", // inside identifier
-           "MACRO(bar->^func^())", // end of identifier
-           "MACRO(^bar->func())",  // begin identifier
-           "MACRO(^bar^->func())", // end identifier
-           "^MACRO(bar->func())",  // beginning of macro name
-           "^MAC^RO(bar->func())", // inside macro name
-           "^MACRO^(bar->func())", // end of macro name
-       }) {
-    std::string WithPreamble = Preamble + Text;
-    Annotations TestCase(WithPreamble);
-    auto AST = TestTU::withCode(TestCase.code()).build();
-    const auto &SourceMgr = AST.getASTContext().getSourceManager();
-    SourceLocation Actual = getBeginningOfIdentifier(
-        AST, TestCase.points().back(), SourceMgr.getMainFileID());
-    Position ActualPos = offsetToPosition(
-        TestCase.code(),
-        SourceMgr.getFileOffset(SourceMgr.getSpellingLoc(Actual)));
-    EXPECT_EQ(TestCase.points().front(), ActualPos) << Text;
-  }
-}
-
-MATCHER_P(DeclNamed, Name, "") {
-  if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
-    if (ND->getName() == Name)
-      return true;
-  if (auto *Stream = result_listener->stream()) {
-    llvm::raw_os_ostream OS(*Stream);
-    arg->dump(OS);
-  }
-  return false;
-}
-
-TEST(ClangdUnitTest, TopLevelDecls) {
-  TestTU TU;
-  TU.HeaderCode = R"(
-    int header1();
-    int header2;
-  )";
-  TU.Code = "int main();";
-  auto AST = TU.build();
-  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
-}
-
-} // namespace
-} // namespace clangd
-} // namespace clang
diff --git a/unittests/clangd/SourceCodeTests.cpp b/unittests/clangd/SourceCodeTests.cpp
deleted file mode 100644
index b170c13..0000000
--- a/unittests/clangd/SourceCodeTests.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//===-- SourceCodeTests.cpp  ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#include "SourceCode.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/raw_os_ostream.h"
-#include "llvm/Testing/Support/Error.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace clangd {
-namespace {
-
-MATCHER_P2(Pos, Line, Col, "") {
-  return arg.line == Line && arg.character == Col;
-}
-
-// The = → 🡆 below are ASCII (1 byte), BMP (3 bytes), and astral (4 bytes).
-const char File[] = R"(0:0 = 0
-1:0 → 8
-2:0 🡆 18)";
-
-/// A helper to make tests easier to read.
-Position position(int line, int character) {
-  Position Pos;
-  Pos.line = line;
-  Pos.character = character;
-  return Pos;
-}
-
-Range range(const std::pair<int, int> p1, const std::pair<int, int> p2) {
-  Range range;
-  range.start = position(p1.first, p1.second);
-  range.end = position(p2.first, p2.second);
-  return range;
-}
-
-TEST(SourceCodeTests, lspLength) {
-  EXPECT_EQ(lspLength(""), 0UL);
-  EXPECT_EQ(lspLength("ascii"), 5UL);
-  // BMP
-  EXPECT_EQ(lspLength("↓"), 1UL);
-  EXPECT_EQ(lspLength("¥"), 1UL);
-  // astral
-  EXPECT_EQ(lspLength("😂"), 2UL);
-}
-
-TEST(SourceCodeTests, PositionToOffset) {
-  // line out of bounds
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
-  // first line
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
-                       llvm::Failed()); // out of range
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
-                       llvm::HasValue(0)); // first character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
-                       llvm::HasValue(3)); // middle character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
-                       llvm::HasValue(6)); // last character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
-                       llvm::HasValue(7)); // the newline itself
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
-                       llvm::HasValue(7));
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
-                       llvm::HasValue(7)); // out of range
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
-                       llvm::Failed()); // out of range
-  // middle line
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
-                       llvm::Failed()); // out of range
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
-                       llvm::HasValue(8)); // first character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
-                       llvm::HasValue(11)); // middle character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
-                       llvm::HasValue(11));
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
-                       llvm::HasValue(16)); // last character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
-                       llvm::HasValue(17)); // the newline itself
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
-                       llvm::HasValue(17)); // out of range
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
-                       llvm::Failed()); // out of range
-  // last line
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
-                       llvm::Failed()); // out of range
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
-                       llvm::HasValue(18)); // first character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
-                       llvm::HasValue(21)); // middle character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
-                       llvm::Failed()); // middle of surrogate pair
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
-                       llvm::HasValue(26)); // middle of surrogate pair
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
-                       llvm::HasValue(26)); // end of surrogate pair
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
-                       llvm::HasValue(28)); // last character
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
-                       llvm::HasValue(29)); // EOF
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
-                       llvm::Failed()); // out of range
-  // line out of bounds
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
-}
-
-TEST(SourceCodeTests, OffsetToPosition) {
-  EXPECT_THAT(offsetToPosition(File, 0), Pos(0, 0)) << "start of file";
-  EXPECT_THAT(offsetToPosition(File, 3), Pos(0, 3)) << "in first line";
-  EXPECT_THAT(offsetToPosition(File, 6), Pos(0, 6)) << "end of first line";
-  EXPECT_THAT(offsetToPosition(File, 7), Pos(0, 7)) << "first newline";
-  EXPECT_THAT(offsetToPosition(File, 8), Pos(1, 0)) << "start of second line";
-  EXPECT_THAT(offsetToPosition(File, 12), Pos(1, 4)) << "before BMP char";
-  EXPECT_THAT(offsetToPosition(File, 13), Pos(1, 5)) << "in BMP char";
-  EXPECT_THAT(offsetToPosition(File, 15), Pos(1, 5)) << "after BMP char";
-  EXPECT_THAT(offsetToPosition(File, 16), Pos(1, 6)) << "end of second line";
-  EXPECT_THAT(offsetToPosition(File, 17), Pos(1, 7)) << "second newline";
-  EXPECT_THAT(offsetToPosition(File, 18), Pos(2, 0)) << "start of last line";
-  EXPECT_THAT(offsetToPosition(File, 21), Pos(2, 3)) << "in last line";
-  EXPECT_THAT(offsetToPosition(File, 22), Pos(2, 4)) << "before astral char";
-  EXPECT_THAT(offsetToPosition(File, 24), Pos(2, 6)) << "in astral char";
-  EXPECT_THAT(offsetToPosition(File, 26), Pos(2, 6)) << "after astral char";
-  EXPECT_THAT(offsetToPosition(File, 28), Pos(2, 8)) << "end of last line";
-  EXPECT_THAT(offsetToPosition(File, 29), Pos(2, 9)) << "EOF";
-  EXPECT_THAT(offsetToPosition(File, 30), Pos(2, 9)) << "out of bounds";
-}
-
-TEST(SourceCodeTests, IsRangeConsecutive) {
-  EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
-  EXPECT_FALSE(
-      IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
-  EXPECT_FALSE(
-      IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
-}
-
-} // namespace
-} // namespace clangd
-} // namespace clang
diff --git a/unittests/clangd/TestIndex.cpp b/unittests/clangd/TestIndex.cpp
deleted file mode 100644
index 714d3a6..0000000
--- a/unittests/clangd/TestIndex.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-//===-- IndexHelpers.cpp ----------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TestIndex.h"
-
-namespace clang {
-namespace clangd {
-
-Symbol symbol(llvm::StringRef QName) {
-  Symbol Sym;
-  Sym.ID = SymbolID(QName.str());
-  size_t Pos = QName.rfind("::");
-  if (Pos == llvm::StringRef::npos) {
-    Sym.Name = QName;
-    Sym.Scope = "";
-  } else {
-    Sym.Name = QName.substr(Pos + 2);
-    Sym.Scope = QName.substr(0, Pos + 2);
-  }
-  return Sym;
-}
-
-SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames) {
-  SymbolSlab::Builder Slab;
-  for (llvm::StringRef QName : QualifiedNames)
-    Slab.insert(symbol(QName));
-  return std::move(Slab).build();
-}
-
-SymbolSlab generateNumSymbols(int Begin, int End) {
-  std::vector<std::string> Names;
-  for (int i = Begin; i <= End; i++)
-    Names.push_back(std::to_string(i));
-  return generateSymbols(Names);
-}
-
-std::string getQualifiedName(const Symbol &Sym) {
-  return (Sym.Scope + Sym.Name).str();
-}
-
-std::vector<std::string> match(const SymbolIndex &I,
-                               const FuzzyFindRequest &Req, bool *Incomplete) {
-  std::vector<std::string> Matches;
-  bool IsIncomplete = I.fuzzyFind(Req, [&](const Symbol &Sym) {
-    Matches.push_back(clang::clangd::getQualifiedName(Sym));
-  });
-  if (Incomplete)
-    *Incomplete = IsIncomplete;
-  return Matches;
-}
-
-// Returns qualified names of symbols with any of IDs in the index.
-std::vector<std::string> lookup(const SymbolIndex &I,
-                                llvm::ArrayRef<SymbolID> IDs) {
-  LookupRequest Req;
-  Req.IDs.insert(IDs.begin(), IDs.end());
-  std::vector<std::string> Results;
-  I.lookup(Req, [&](const Symbol &Sym) {
-    Results.push_back(getQualifiedName(Sym));
-  });
-  return Results;
-}
-
-} // namespace clangd
-} // namespace clang
diff --git a/unittests/include/common/VirtualFileHelper.h b/unittests/include/common/VirtualFileHelper.h
index 5fa4d53..03eddb8 100644
--- a/unittests/include/common/VirtualFileHelper.h
+++ b/unittests/include/common/VirtualFileHelper.h
@@ -1,9 +1,8 @@
 //===--- VirtualFileHelper.h ------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///