Merge 80b6bd26 for LLVM update to 353983

Change-Id: I725a25e633fed57b4065f7c34243b468a5ab125c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c3137ad..37e3e87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,8 @@
+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)
diff --git a/LICENSE.TXT b/LICENSE.TXT
index b886535..24806ab 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,10 +1,245 @@
 ==============================================================================
-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
 
-Copyright (c) 2007-2018 University of Illinois at Urbana-Champaign.
+Copyright (c) 2007-2019 University of Illinois at Urbana-Champaign.
 All rights reserved.
 
 Developed by:
@@ -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/change-namespace/ChangeNamespace.cpp b/change-namespace/ChangeNamespace.cpp
index 7a71031..eb73263 100644
--- a/change-namespace/ChangeNamespace.cpp
+++ b/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/change-namespace/ChangeNamespace.h
index cfe3cbc..293d5ce 100644
--- a/change-namespace/ChangeNamespace.h
+++ b/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/ClangChangeNamespace.cpp b/change-namespace/tool/ClangChangeNamespace.cpp
index 180e8c3..0d51502 100644
--- a/change-namespace/tool/ClangChangeNamespace.cpp
+++ b/change-namespace/tool/ClangChangeNamespace.cpp
@@ -1,9 +1,8 @@
 //===-- ClangIncludeFixer.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-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..7a656a6 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
 //
 //===----------------------------------------------------------------------===//
 ///
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/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..e57a261 100644
--- a/clang-doc/Generators.cpp
+++ b/clang-doc/Generators.cpp
@@ -1,9 +1,8 @@
 //===---- Generator.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..897fed5 100644
--- a/clang-doc/Serialize.cpp
+++ b/clang-doc/Serialize.cpp
@@ -1,9 +1,8 @@
 //===-- Serializer.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..ceb4215 100644
--- a/clang-doc/YAMLGenerator.cpp
+++ b/clang-doc/YAMLGenerator.cpp
@@ -1,9 +1,8 @@
 //===--  ClangDocYAML.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/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/clang-move/ClangMove.cpp b/clang-move/ClangMove.cpp
index ec9db73..9fd3e96 100644
--- a/clang-move/ClangMove.cpp
+++ b/clang-move/ClangMove.cpp
@@ -1,9 +1,8 @@
 //===-- ClangMove.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
 //
 //===----------------------------------------------------------------------===//
 
@@ -76,10 +75,7 @@
     return "";
   llvm::SmallString<128> InitialDirectory(CurrentDir);
   llvm::SmallString<128> AbsolutePath(Path);
-  if (std::error_code EC =
-          llvm::sys::fs::make_absolute(InitialDirectory, AbsolutePath))
-    llvm::errs() << "Warning: could not make absolute file: '" << EC.message()
-                 << '\n';
+  llvm::sys::fs::make_absolute(InitialDirectory, AbsolutePath);
   return CleanPath(std::move(AbsolutePath));
 }
 
diff --git a/clang-move/ClangMove.h b/clang-move/ClangMove.h
index 9417218..8dfccf7 100644
--- a/clang-move/ClangMove.h
+++ b/clang-move/ClangMove.h
@@ -1,9 +1,8 @@
 //===-- ClangMove.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/HelperDeclRefGraph.cpp b/clang-move/HelperDeclRefGraph.cpp
index 28200e0..93a0f87 100644
--- a/clang-move/HelperDeclRefGraph.cpp
+++ b/clang-move/HelperDeclRefGraph.cpp
@@ -1,9 +1,8 @@
 //===-- UsedHelperDeclFinder.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
 //
 //===----------------------------------------------------------------------===//
 
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/tool/ClangMoveMain.cpp b/clang-move/tool/ClangMoveMain.cpp
index f50e973..a73dd6e 100644
--- a/clang-move/tool/ClangMoveMain.cpp
+++ b/clang-move/tool/ClangMoveMain.cpp
@@ -1,9 +1,8 @@
 //===-- ClangMoveMain.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
 //
 //===----------------------------------------------------------------------===//
 
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 7c12e3b..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,29 +26,22 @@
 // is found before End, return StringRef().  Begin is adjusted to exclude the
 // lexed region.
 StringRef QueryParser::lexWord() {
-  while (true) {
-    if (Begin == End)
-      return StringRef(Begin, 0);
+  Line = Line.ltrim();
 
-    if (!isWhitespace(*Begin))
-      break;
+  if (Line.empty())
+    // Even though the Line is empty, it contains a pointer and
+    // a (zero) length. The pointer is used in the LexOrCompleteWord
+    // code completion.
+    return Line;
 
-    ++Begin;
-  }
-
-  if (*Begin == '#') {
-    End = Begin;
+  if (Line.front() == '#') {
+    Line = {};
     return StringRef();
   }
 
-  const char *WordBegin = Begin;
-
-  while (true) {
-    ++Begin;
-
-    if (Begin == End || isWhitespace(*Begin))
-      return StringRef(WordBegin, Begin - WordBegin);
-  }
+  StringRef Word = Line.take_until(isWhitespace);
+  Line = Line.drop_front(Word.size());
+  return Word;
 }
 
 // This is the StringSwitch-alike used by lexOrCompleteWord below. See that
@@ -133,10 +125,9 @@
 }
 
 QueryRef QueryParser::endQuery(QueryRef Q) {
-  const char *Extra = Begin;
+  const StringRef Extra = Line;
   if (!lexWord().empty())
-    return new InvalidQuery("unexpected extra input: '" +
-                            StringRef(Extra, End - Extra) + "'");
+    return new InvalidQuery("unexpected extra input: '" + Extra + "'");
   return Q;
 }
 
@@ -174,8 +165,7 @@
 
 QueryRef QueryParser::completeMatcherExpression() {
   std::vector<MatcherCompletion> Comps = Parser::completeExpression(
-      StringRef(Begin, End - Begin), CompletionPos - Begin, nullptr,
-      &QS.NamedValues);
+      Line, CompletionPos - Line.begin(), nullptr, &QS.NamedValues);
   for (auto I = Comps.begin(), E = Comps.end(); I != E; ++I) {
     Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));
   }
@@ -222,8 +212,8 @@
 
     Diagnostics Diag;
     ast_matchers::dynamic::VariantValue Value;
-    if (!Parser::parseExpression(StringRef(Begin, End - Begin), nullptr,
-                                 &QS.NamedValues, &Value, &Diag)) {
+    if (!Parser::parseExpression(Line, nullptr, &QS.NamedValues, &Value,
+                                 &Diag)) {
       return makeInvalidQueryFromDiagnostics(Diag);
     }
 
@@ -235,7 +225,7 @@
       return completeMatcherExpression();
 
     Diagnostics Diag;
-    auto MatcherSource = StringRef(Begin, End - Begin).trim();
+    auto MatcherSource = Line.trim();
     Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(
         MatcherSource, nullptr, &QS.NamedValues, &Diag);
     if (!Matcher) {
diff --git a/clang-query/QueryParser.h b/clang-query/QueryParser.h
index 6730f99..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -37,7 +36,7 @@
 
 private:
   QueryParser(StringRef Line, const QuerySession &QS)
-      : Begin(Line.begin()), End(Line.end()), CompletionPos(nullptr), QS(QS) {}
+      : Line(Line), CompletionPos(nullptr), QS(QS) {}
 
   StringRef lexWord();
 
@@ -55,8 +54,7 @@
   /// \c InvalidQuery if a parse error occurs.
   QueryRef doParse();
 
-  const char *Begin;
-  const char *End;
+  StringRef Line;
 
   const char *CompletionPos;
   std::vector<llvm::LineEditor::Completion> Completions;
diff --git a/clang-query/QuerySession.h b/clang-query/QuerySession.h
index 62ecb54..0f3bc1a 100644
--- a/clang-query/QuerySession.h
+++ b/clang-query/QuerySession.h
@@ -1,16 +1,14 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H
 
-#include "Query.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringMap.h"
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/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/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp
index 0feda60..6534fd4 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
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -529,24 +528,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);
 
diff --git a/clang-tidy/ClangTidy.h b/clang-tidy/ClangTidy.h
index dc11200..2985732 100644
--- a/clang-tidy/ClangTidy.h
+++ b/clang-tidy/ClangTidy.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index 6e2385b..637addf 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
 //
 //===----------------------------------------------------------------------===//
 ///
@@ -319,7 +318,7 @@
   return true;
 }
 
-static bool LineIsMarkedWithNOLINT(SourceManager &SM, SourceLocation Loc,
+static bool LineIsMarkedWithNOLINT(const SourceManager &SM, SourceLocation Loc,
                                    unsigned DiagID,
                                    const ClangTidyContext &Context) {
   bool Invalid;
@@ -365,8 +364,8 @@
   return false;
 }
 
-static bool LineIsMarkedWithNOLINTinMacro(SourceManager &SM, SourceLocation Loc,
-                                          unsigned DiagID,
+static bool LineIsMarkedWithNOLINTinMacro(const SourceManager &SM,
+                                          SourceLocation Loc, unsigned DiagID,
                                           const ClangTidyContext &Context) {
   while (true) {
     if (LineIsMarkedWithNOLINT(SM, Loc, DiagID, Context))
diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tidy/ClangTidyDiagnosticConsumer.h
index a868203..63dbd52 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/ClangTidyForceLinker.h b/clang-tidy/ClangTidyForceLinker.h
index 2e8e8a8..966aeb2 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
 //
 //===----------------------------------------------------------------------===//
 
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/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..1489b48 100644
--- a/clang-tidy/abseil/AbseilTidyModule.cpp
+++ b/clang-tidy/abseil/AbseilTidyModule.cpp
@@ -1,20 +1,22 @@
 //===------- 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"
@@ -30,8 +32,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 +46,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>(
diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt
index bf9d9e8..578dd57 100644
--- a/clang-tidy/abseil/CMakeLists.txt
+++ b/clang-tidy/abseil/CMakeLists.txt
@@ -2,12 +2,15 @@
 
 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
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 ae368ed..337f2ca 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -35,11 +34,7 @@
 void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Binop = Result.Nodes.getNodeAs<BinaryOperator>("binop");
 
-  // Don't try to replace things inside of macro definitions.
-  if (Binop->getExprLoc().isMacroID())
-    return;
-
-  llvm::Optional<DurationScale> Scale = getScaleForInverse(
+  llvm::Optional<DurationScale> Scale = getScaleForDurationInverse(
       Result.Nodes.getNodeAs<FunctionDecl>("function_decl")->getName());
   if (!Scale)
     return;
@@ -48,19 +43,19 @@
   // 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.
-  llvm::Optional<std::string> LhsReplacement =
-      rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS());
-  llvm::Optional<std::string> RhsReplacement =
-      rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS());
-
-  if (!(LhsReplacement && RhsReplacement))
+  if (!isNotInMacro(Result, Binop->getLHS()) ||
+      !isNotInMacro(Result, Binop->getRHS()))
     return;
+  std::string LhsReplacement =
+      rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS());
+  std::string RhsReplacement =
+      rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS());
 
   diag(Binop->getBeginLoc(), "perform comparison in the duration domain")
       << FixItHint::CreateReplacement(Binop->getSourceRange(),
-                                      (llvm::Twine(*LhsReplacement) + " " +
+                                      (llvm::Twine(LhsReplacement) + " " +
                                        Binop->getOpcodeStr() + " " +
-                                       *RhsReplacement)
+                                       RhsReplacement)
                                           .str());
 }
 
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..f0ae82c
--- /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 (!isNotInMacro(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 078f88c..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -123,6 +122,10 @@
           hasArgument(
               0,
               ignoringImpCasts(anyOf(
+                  cxxFunctionalCastExpr(
+                      hasDestinationType(
+                          anyOf(isInteger(), realFloatingPointType())),
+                      hasSourceExpression(initListExpr())),
                   integerLiteral(equals(0)), floatLiteral(equals(0.0)),
                   binaryOperator(hasOperatorName("*"),
                                  hasEitherOperand(ignoringImpCasts(
@@ -206,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());
     }
@@ -219,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 7a48813..c3e4078 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -37,9 +36,8 @@
   return llvm::None;
 }
 
-/// Given a `Scale` return the inverse functions for it.
-static const std::pair<llvm::StringRef, llvm::StringRef> &
-getInverseForScale(DurationScale Scale) {
+const std::pair<llvm::StringRef, llvm::StringRef> &
+getDurationInverseForScale(DurationScale Scale) {
   static const llvm::IndexedMap<std::pair<llvm::StringRef, llvm::StringRef>,
                                 DurationScale2IndexFunctor>
       InverseMap = []() {
@@ -73,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(
@@ -87,7 +85,7 @@
 }
 
 /// 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";
@@ -105,14 +103,49 @@
   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) {
-  return selectFirst<const clang::Expr>(
-             "val",
-             match(expr(ignoringImpCasts(anyOf(integerLiteral(equals(0)),
-                                               floatLiteral(equals(0.0)))))
-                       .bind("val"),
-                   Node, *Result.Context)) != nullptr;
+  auto ZeroMatcher =
+      anyOf(integerLiteral(equals(0)), floatLiteral(equals(0.0)));
+
+  // Check to see if we're using a zero directly.
+  if (selectFirst<const clang::Expr>(
+          "val", match(expr(ignoringImpCasts(ZeroMatcher)).bind("val"), Node,
+                       *Result.Context)) != nullptr)
+    return true;
+
+  // Now check to see if we're using a functional cast with a scalar
+  // initializer expression, e.g. `int{0}`.
+  if (selectFirst<const clang::Expr>(
+          "val", match(cxxFunctionalCastExpr(
+                           hasDestinationType(
+                               anyOf(isInteger(), realFloatingPointType())),
+                           hasSourceExpression(initListExpr(
+                               hasInit(0, ignoringParenImpCasts(ZeroMatcher)))))
+                           .bind("val"),
+                       Node, *Result.Context)) != nullptr)
+    return true;
+
+  return false;
 }
 
 llvm::Optional<std::string>
@@ -161,7 +194,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},
@@ -183,14 +216,27 @@
   return ScaleIter->second;
 }
 
-llvm::Optional<std::string> rewriteExprFromNumberToDuration(
+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) {
   const Expr &RootNode = *Node->IgnoreParenImpCasts();
 
-  if (RootNode.getBeginLoc().isMacroID())
-    return llvm::None;
-
   // First check to see if we can undo a complimentary function call.
   if (llvm::Optional<std::string> MaybeRewrite =
           rewriteInverseDurationCall(Result, Scale, RootNode))
@@ -199,11 +245,28 @@
   if (IsLiteralZero(Result, RootNode))
     return std::string("absl::ZeroDuration()");
 
-  return (llvm::Twine(getFactoryForScale(Scale)) + "(" +
+  return (llvm::Twine(getDurationFactoryForScale(Scale)) + "(" +
           simplifyDurationFactoryArg(Result, RootNode) + ")")
       .str();
 }
 
+bool isNotInMacro(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();
+}
+
 } // namespace abseil
 } // namespace tidy
 } // namespace clang
diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h
index 97103b6..54a60f6 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,7 @@
 
 /// 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);
 
 // Determine if `Node` represents a literal floating point or integral zero.
 bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result,
@@ -61,14 +60,32 @@
 
 /// 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> &
+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`.
-llvm::Optional<std::string> rewriteExprFromNumberToDuration(
+std::string rewriteExprFromNumberToDuration(
     const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale,
     const Expr *Node);
 
+/// Return `true` 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 isNotInMacro(const ast_matchers::MatchFinder::MatchResult &Result,
+                  const Expr *E);
+
 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<FunctionDecl>,
                      DurationConversionFunction) {
   using namespace clang::ast_matchers;
@@ -89,6 +106,14 @@
                                  "::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"));
+}
+
 } // namespace abseil
 } // namespace tidy
 } // namespace clang
diff --git a/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tidy/abseil/DurationSubtractionCheck.cpp
index 8b85bd2..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,14 +37,13 @@
   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;
 
-  llvm::Optional<std::string> RhsReplacement =
+  std::string RhsReplacement =
       rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS());
-  if (!RhsReplacement)
-    return;
 
   const Expr *LhsArg = Result.Nodes.getNodeAs<Expr>("lhs_arg");
 
@@ -54,7 +52,7 @@
              Binop->getSourceRange(),
              (llvm::Twine("absl::") + FuncDecl->getName() + "(" +
               tooling::fixit::getText(*LhsArg, *Result.Context) + " - " +
-              *RhsReplacement + ")")
+              RhsReplacement + ")")
                  .str());
 }
 
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..83650cd
--- /dev/null
+++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp
@@ -0,0 +1,58 @@
+//===--- 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();
+
+    Finder->addMatcher(
+        callExpr(
+            callee(functionDecl(hasName(DurationFactory))),
+            hasArgument(0, callExpr(callee(functionDecl(hasAnyName(
+                                        FloatConversion, IntegerConversion))),
+                                    hasArgument(0, expr().bind("arg")))))
+            .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 (!isNotInMacro(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..9009647 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/abseil/StringFindStartswithCheck.h b/clang-tidy/abseil/StringFindStartswithCheck.h
index 1c04e80..68bae50 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
 //
 //===----------------------------------------------------------------------===//
 
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..898392b 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,10 +60,9 @@
     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
 //
 //===----------------------------------------------------------------------===//
 
@@ -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
 //
 //===----------------------------------------------------------------------===//
 
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..da6c669 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
 //
 //===----------------------------------------------------------------------===//
 ///
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..53e8b8e 100644
--- a/clang-tidy/android/ComparisonInTempFailureRetryCheck.h
+++ b/clang-tidy/android/ComparisonInTempFailureRetryCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..e166615 100644
--- a/clang-tidy/boost/UseToStringCheck.h
+++ b/clang-tidy/boost/UseToStringCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..451b309 100644
--- a/clang-tidy/bugprone/ArgumentCommentCheck.h
+++ b/clang-tidy/bugprone/ArgumentCommentCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -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..ffc8000 100644
--- a/clang-tidy/bugprone/AssertSideEffectCheck.h
+++ b/clang-tidy/bugprone/AssertSideEffectCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7ddaab2 100644
--- a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h
+++ b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..16e4678 100644
--- a/clang-tidy/bugprone/CopyConstructorInitCheck.h
+++ b/clang-tidy/bugprone/CopyConstructorInitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tidy/bugprone/DanglingHandleCheck.cpp
index 81b799e..9cefc20 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/DanglingHandleCheck.h b/clang-tidy/bugprone/DanglingHandleCheck.h
index add8d42..801240f 100644
--- a/clang-tidy/bugprone/DanglingHandleCheck.h
+++ b/clang-tidy/bugprone/DanglingHandleCheck.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/bugprone/ExceptionEscapeCheck.cpp b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp
index 3c8a6c5..0849e2e 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,12 @@
       .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));
 }
 
 void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
@@ -194,22 +59,25 @@
                          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.throwsException(MatchedDecl))
+    // 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..4626e42 100644
--- a/clang-tidy/bugprone/ExceptionEscapeCheck.h
+++ b/clang-tidy/bugprone/ExceptionEscapeCheck.h
@@ -1,9 +1,8 @@
-//===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,7 +10,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_ESCAPE_H
 
 #include "../ClangTidy.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..dce71ac 100644
--- a/clang-tidy/bugprone/FoldInitTypeCheck.h
+++ b/clang-tidy/bugprone/FoldInitTypeCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..dfecddc 100644
--- a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h
+++ b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7f3a422 100644
--- a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h
+++ b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tidy/bugprone/InaccurateEraseCheck.cpp
index c1e65b5..b236e99 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.h b/clang-tidy/bugprone/InaccurateEraseCheck.h
index d6b3729..7a8b3aa 100644
--- a/clang-tidy/bugprone/InaccurateEraseCheck.h
+++ b/clang-tidy/bugprone/InaccurateEraseCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..1c84316 100644
--- a/clang-tidy/bugprone/IncorrectRoundingsCheck.h
+++ b/clang-tidy/bugprone/IncorrectRoundingsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2077668 100644
--- a/clang-tidy/bugprone/IntegerDivisionCheck.h
+++ b/clang-tidy/bugprone/IntegerDivisionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
index bdb769d..bcd1ab8 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.h b/clang-tidy/bugprone/LambdaFunctionNameCheck.h
index b7b1b44..b00df53 100644
--- a/clang-tidy/bugprone/LambdaFunctionNameCheck.h
+++ b/clang-tidy/bugprone/LambdaFunctionNameCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.cpp b/clang-tidy/bugprone/MacroParenthesesCheck.cpp
index 6846bc2..2bebf4a 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.h b/clang-tidy/bugprone/MacroParenthesesCheck.h
index 383a6cc..4b9e181 100644
--- a/clang-tidy/bugprone/MacroParenthesesCheck.h
+++ b/clang-tidy/bugprone/MacroParenthesesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp
index 30c770e..91ec094 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
index a2a3134..6917c5b 100644
--- a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
+++ b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..aede5ff 100644
--- a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h
+++ b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..ccf4cf7 100644
--- a/clang-tidy/bugprone/MisplacedWideningCastCheck.h
+++ b/clang-tidy/bugprone/MisplacedWideningCastCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2565dcd 100644
--- a/clang-tidy/bugprone/MoveForwardingReferenceCheck.h
+++ b/clang-tidy/bugprone/MoveForwardingReferenceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..0fd91eb 100644
--- a/clang-tidy/bugprone/MultipleStatementMacroCheck.h
+++ b/clang-tidy/bugprone/MultipleStatementMacroCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.cpp b/clang-tidy/bugprone/ParentVirtualCallCheck.cpp
index 919a691..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -50,9 +49,7 @@
     // TypePtr is the nearest base class to ThisClass between ThisClass and
     // GrandParent, where MemberDecl is overridden. TypePtr is the class the
     // check proposes to fix to.
-    const Type *TypePtr =
-        ActualMemberDecl->getThisType(ActualMemberDecl->getASTContext())
-            .getTypePtr();
+    const Type *TypePtr = ActualMemberDecl->getThisType().getTypePtr();
     const CXXRecordDecl *RecordDeclType = TypePtr->getPointeeCXXRecordDecl();
     assert(RecordDeclType && "TypePtr is not a pointer to CXXRecordDecl!");
     if (RecordDeclType->getCanonicalDecl()->isDerivedFrom(&GrandParent))
diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.h b/clang-tidy/bugprone/ParentVirtualCallCheck.h
index 08c3aef..a1753cd 100755
--- a/clang-tidy/bugprone/ParentVirtualCallCheck.h
+++ b/clang-tidy/bugprone/ParentVirtualCallCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..e358279 100644
--- a/clang-tidy/bugprone/SizeofContainerCheck.h
+++ b/clang-tidy/bugprone/SizeofContainerCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index d662657..959e0ae 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.h b/clang-tidy/bugprone/SizeofExpressionCheck.h
index 8e14c31..b06551a 100644
--- a/clang-tidy/bugprone/SizeofExpressionCheck.h
+++ b/clang-tidy/bugprone/SizeofExpressionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tidy/bugprone/StringConstructorCheck.cpp
index d888230..3a4e75b 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -100,6 +99,15 @@
                                        integerLiteral().bind("int"))))))
           .bind("constructor"),
       this);
+
+  // Check the literal string constructor with char pointer.
+  // [i.e. string (const char* s);]
+  Finder->addMatcher(
+      cxxConstructExpr(hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
+                       hasArgument(0, expr().bind("from-ptr")),
+                       hasArgument(1, unless(hasType(isInteger()))))
+          .bind("constructor"),
+      this);
 }
 
 void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) {
@@ -128,6 +136,13 @@
     if (Lit->getValue().ugt(Str->getLength())) {
       diag(Loc, "length is bigger then string literal size");
     }
+  } else if (const auto *Ptr = Result.Nodes.getNodeAs<Expr>("from-ptr")) {
+    Expr::EvalResult ConstPtr;
+    if (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..2274015 100644
--- a/clang-tidy/bugprone/StringConstructorCheck.h
+++ b/clang-tidy/bugprone/StringConstructorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp
index f49a570..cce0de9 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
index 42fa53e..66da587 100644
--- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
+++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6888510 100644
--- a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h
+++ b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..32c4a0b 100644
--- a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h
+++ b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..98872e6 100644
--- a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h
+++ b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..d1f58a4 100644
--- a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h
+++ b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp b/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp
index f92fc37..576fba5 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
index adfced1..12829b1 100644
--- a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
+++ b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..409d79b 100644
--- a/clang-tidy/bugprone/SuspiciousStringCompareCheck.h
+++ b/clang-tidy/bugprone/SuspiciousStringCompareCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..a1e10df 100644
--- a/clang-tidy/bugprone/SwappedArgumentsCheck.h
+++ b/clang-tidy/bugprone/SwappedArgumentsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6d58949 100644
--- a/clang-tidy/bugprone/TerminatingContinueCheck.h
+++ b/clang-tidy/bugprone/TerminatingContinueCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..76b4dc1 100644
--- a/clang-tidy/bugprone/ThrowKeywordMissingCheck.h
+++ b/clang-tidy/bugprone/ThrowKeywordMissingCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp
index 59cc185..395885e 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
index 0819fcf..54589ac 100644
--- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
+++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..01903df 100644
--- a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
+++ b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..9eda29c 100644
--- a/clang-tidy/bugprone/UndelegatedConstructorCheck.h
+++ b/clang-tidy/bugprone/UndelegatedConstructorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7a4a6ef 100644
--- a/clang-tidy/bugprone/UnusedRaiiCheck.h
+++ b/clang-tidy/bugprone/UnusedRaiiCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..35678ed 100644
--- a/clang-tidy/bugprone/UnusedReturnValueCheck.h
+++ b/clang-tidy/bugprone/UnusedReturnValueCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tidy/bugprone/UseAfterMoveCheck.cpp
index 11799eb..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -207,7 +206,7 @@
 }
 
 bool isStandardSmartPointer(const ValueDecl *VD) {
-  const Type *TheType = VD->getType().getTypePtrOrNull();
+  const Type *TheType = VD->getType().getNonReferenceType().getTypePtrOrNull();
   if (!TheType)
     return false;
 
diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.h b/clang-tidy/bugprone/UseAfterMoveCheck.h
index f6dea68..c0984b4 100644
--- a/clang-tidy/bugprone/UseAfterMoveCheck.h
+++ b/clang-tidy/bugprone/UseAfterMoveCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..38314ee 100644
--- a/clang-tidy/bugprone/VirtualNearMissCheck.h
+++ b/clang-tidy/bugprone/VirtualNearMissCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..cfc2f37 100644
--- a/clang-tidy/cert/CommandProcessorCheck.cpp
+++ b/clang-tidy/cert/CommandProcessorCheck.cpp
@@ -1,9 +1,8 @@
 //===--- Env33CCheck.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..1f172e4 100644
--- a/clang-tidy/cert/CommandProcessorCheck.h
+++ b/clang-tidy/cert/CommandProcessorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..06de157 100644
--- a/clang-tidy/cert/DontModifyStdNamespaceCheck.h
+++ b/clang-tidy/cert/DontModifyStdNamespaceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7752c6e 100644
--- a/clang-tidy/cert/FloatLoopCounter.h
+++ b/clang-tidy/cert/FloatLoopCounter.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..b88145e 100644
--- a/clang-tidy/cert/LimitedRandomnessCheck.h
+++ b/clang-tidy/cert/LimitedRandomnessCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6b7eda2 100644
--- a/clang-tidy/cert/PostfixOperatorCheck.h
+++ b/clang-tidy/cert/PostfixOperatorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..4fbca8f 100644
--- a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
+++ b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/SetLongJmpCheck.cpp b/clang-tidy/cert/SetLongJmpCheck.cpp
index 89ba5e7..6b418d4 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/SetLongJmpCheck.h b/clang-tidy/cert/SetLongJmpCheck.h
index 1d6c098..ea20ba7 100644
--- a/clang-tidy/cert/SetLongJmpCheck.h
+++ b/clang-tidy/cert/SetLongJmpCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6b59b85 100644
--- a/clang-tidy/cert/StaticObjectExceptionCheck.h
+++ b/clang-tidy/cert/StaticObjectExceptionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/StrToNumCheck.cpp b/clang-tidy/cert/StrToNumCheck.cpp
index 0b3ea43..38e2dc0 100644
--- a/clang-tidy/cert/StrToNumCheck.cpp
+++ b/clang-tidy/cert/StrToNumCheck.cpp
@@ -1,9 +1,8 @@
 //===--- Err34CCheck.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..423a905 100644
--- a/clang-tidy/cert/StrToNumCheck.h
+++ b/clang-tidy/cert/StrToNumCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..042b98c 100644
--- a/clang-tidy/cert/ThrownExceptionTypeCheck.h
+++ b/clang-tidy/cert/ThrownExceptionTypeCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.cpp b/clang-tidy/cert/VariadicFunctionDefCheck.cpp
index ea6112a..4fe6b7a 100644
--- a/clang-tidy/cert/VariadicFunctionDefCheck.cpp
+++ b/clang-tidy/cert/VariadicFunctionDefCheck.cpp
@@ -1,9 +1,8 @@
 //===--- 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..7f8d479 100644
--- a/clang-tidy/cert/VariadicFunctionDefCheck.h
+++ b/clang-tidy/cert/VariadicFunctionDefCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..fdf2880 100644
--- a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- CppCoreGuidelinesModule.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.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..07351b8 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/MacroUsageCheck.h b/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
index a39d55a..fc96e33 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
 //
 //===----------------------------------------------------------------------===//
 
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..32e3fb5 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
index 28b24a6..c056926 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
 //
 //===----------------------------------------------------------------------===//
 
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..b31145c 100644
--- a/clang-tidy/fuchsia/DefaultArgumentsCheck.h
+++ b/clang-tidy/fuchsia/DefaultArgumentsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..02d4cff 100644
--- a/clang-tidy/fuchsia/MultipleInheritanceCheck.h
+++ b/clang-tidy/fuchsia/MultipleInheritanceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp b/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
index 8e6c74f..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,6 +20,8 @@
     if (CXXMethodNode->isCopyAssignmentOperator() ||
         CXXMethodNode->isMoveAssignmentOperator())
       return false;
+    if (CXXMethodNode->getParent()->isLambda())
+      return false;
   }
   return Node.isOverloadedOperator();
 }
diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.h b/clang-tidy/fuchsia/OverloadedOperatorCheck.h
index a22e5ae..6d99e8b 100644
--- a/clang-tidy/fuchsia/OverloadedOperatorCheck.h
+++ b/clang-tidy/fuchsia/OverloadedOperatorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp
index 4817e90..e42e32c 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
index d4e5ac1..64da2e7 100644
--- a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
+++ b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..5e16d0a 100644
--- a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
+++ b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..181d142 100644
--- a/clang-tidy/fuchsia/TrailingReturnCheck.h
+++ b/clang-tidy/fuchsia/TrailingReturnCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..8e39d81 100644
--- a/clang-tidy/fuchsia/VirtualInheritanceCheck.h
+++ b/clang-tidy/fuchsia/VirtualInheritanceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..0f6ec2e 100644
--- a/clang-tidy/google/AvoidCStyleCastsCheck.h
+++ b/clang-tidy/google/AvoidCStyleCastsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..bc50bc2 100644
--- a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
+++ b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp
new file mode 100644
index 0000000..fbc47b7
--- /dev/null
+++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp
@@ -0,0 +1,89 @@
+//===--- 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(
+    CompilerInstance &Compiler) {
+  Compiler.getPreprocessor().addPPCallbacks(
+      llvm::make_unique<AvoidUnderscoreInGoogletestNameCallback>(
+          &Compiler.getPreprocessor(), 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..8a1a2f2
--- /dev/null
+++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h
@@ -0,0 +1,33 @@
+//===--- 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 "../ClangTidy.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(CompilerInstance &Compiler) 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..cbaa0a6 100644
--- a/clang-tidy/google/DefaultArgumentsCheck.h
+++ b/clang-tidy/google/DefaultArgumentsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7efc104 100644
--- a/clang-tidy/google/ExplicitConstructorCheck.h
+++ b/clang-tidy/google/ExplicitConstructorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..1eb5528 100644
--- a/clang-tidy/google/ExplicitMakePairCheck.h
+++ b/clang-tidy/google/ExplicitMakePairCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp
index f706470..3eeb6fa 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/FunctionNamingCheck.h b/clang-tidy/google/FunctionNamingCheck.h
index 46499e9..6efea26 100644
--- a/clang-tidy/google/FunctionNamingCheck.h
+++ b/clang-tidy/google/FunctionNamingCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..80247bc 100644
--- a/clang-tidy/google/GlobalNamesInHeadersCheck.h
+++ b/clang-tidy/google/GlobalNamesInHeadersCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp
index 6388523..b2ad276 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.h b/clang-tidy/google/GlobalVariableDeclarationCheck.h
index ed0352b..7213beb 100644
--- a/clang-tidy/google/GlobalVariableDeclarationCheck.h
+++ b/clang-tidy/google/GlobalVariableDeclarationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..c9a1f3b 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/IntegerTypesCheck.h b/clang-tidy/google/IntegerTypesCheck.h
index 8d8f903..d8a846d 100644
--- a/clang-tidy/google/IntegerTypesCheck.h
+++ b/clang-tidy/google/IntegerTypesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2b7ea8f 100644
--- a/clang-tidy/google/NonConstReferences.h
+++ b/clang-tidy/google/NonConstReferences.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2208b37 100644
--- a/clang-tidy/google/OverloadedUnaryAndCheck.h
+++ b/clang-tidy/google/OverloadedUnaryAndCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/TodoCommentCheck.cpp b/clang-tidy/google/TodoCommentCheck.cpp
index f1c79ce..c46f07d 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/google/TodoCommentCheck.h b/clang-tidy/google/TodoCommentCheck.h
index dbdc366..eb89dd0 100644
--- a/clang-tidy/google/TodoCommentCheck.h
+++ b/clang-tidy/google/TodoCommentCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..92cece2 100644
--- a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
+++ b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..eb636ea 100644
--- a/clang-tidy/google/UsingNamespaceDirectiveCheck.h
+++ b/clang-tidy/google/UsingNamespaceDirectiveCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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/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..3d23644 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/IncludeOrderCheck.h b/clang-tidy/llvm/IncludeOrderCheck.h
index ad876b9..b10496e 100644
--- a/clang-tidy/llvm/IncludeOrderCheck.h
+++ b/clang-tidy/llvm/IncludeOrderCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tidy/llvm/LLVMTidyModule.cpp
index ea46ca9..f524268 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
 //
 //===----------------------------------------------------------------------===//
 
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..c2b03e8 100644
--- a/clang-tidy/llvm/TwineLocalCheck.h
+++ b/clang-tidy/llvm/TwineLocalCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..8e5eb7c 100644
--- a/clang-tidy/misc/DefinitionsInHeadersCheck.h
+++ b/clang-tidy/misc/DefinitionsInHeadersCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..a156e3e 100644
--- a/clang-tidy/misc/MisplacedConstCheck.h
+++ b/clang-tidy/misc/MisplacedConstCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..46a3bb7 100644
--- a/clang-tidy/misc/NewDeleteOverloadsCheck.h
+++ b/clang-tidy/misc/NewDeleteOverloadsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..5ebaba8 100644
--- a/clang-tidy/misc/NonCopyableObjects.h
+++ b/clang-tidy/misc/NonCopyableObjects.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6072eae 100644
--- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
+++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..02d37e1 100644
--- a/clang-tidy/misc/RedundantExpressionCheck.h
+++ b/clang-tidy/misc/RedundantExpressionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/StaticAssertCheck.cpp b/clang-tidy/misc/StaticAssertCheck.cpp
index 583ed7a..18d9412 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/StaticAssertCheck.h b/clang-tidy/misc/StaticAssertCheck.h
index faefce1..f3d3586 100644
--- a/clang-tidy/misc/StaticAssertCheck.h
+++ b/clang-tidy/misc/StaticAssertCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6b79c20 100644
--- a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
+++ b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..761701d 100644
--- a/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
+++ b/clang-tidy/misc/UnconventionalAssignOperatorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..d013f32 100644
--- a/clang-tidy/misc/UniqueptrResetReleaseCheck.h
+++ b/clang-tidy/misc/UniqueptrResetReleaseCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..af27ef0 100644
--- a/clang-tidy/misc/UnusedAliasDeclsCheck.h
+++ b/clang-tidy/misc/UnusedAliasDeclsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f4e0708 100644
--- a/clang-tidy/misc/UnusedParametersCheck.h
+++ b/clang-tidy/misc/UnusedParametersCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index 48009b5..532dbfd 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.h b/clang-tidy/misc/UnusedUsingDeclsCheck.h
index 2a41a8f..acc6a44 100644
--- a/clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ b/clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..c1042d5 100644
--- a/clang-tidy/modernize/AvoidBindCheck.h
+++ b/clang-tidy/modernize/AvoidBindCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..ef638e9 100644
--- a/clang-tidy/modernize/AvoidCArraysCheck.h
+++ b/clang-tidy/modernize/AvoidCArraysCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/CMakeLists.txt b/clang-tidy/modernize/CMakeLists.txt
index cfacc95..bb5c0ae 100644
--- a/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tidy/modernize/CMakeLists.txt
@@ -26,6 +26,7 @@
   UseEmplaceCheck.cpp
   UseEqualsDefaultCheck.cpp
   UseEqualsDeleteCheck.cpp
+  UseNodiscardCheck.cpp
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp
index bef85f7..33ac856 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
index 547690d..7f3c693 100644
--- a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
+++ b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tidy/modernize/DeprecatedHeadersCheck.cpp
index 1ff3f89..ffc041b 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tidy/modernize/DeprecatedHeadersCheck.h
index ee7254e..4be4ad9 100644
--- a/clang-tidy/modernize/DeprecatedHeadersCheck.h
+++ b/clang-tidy/modernize/DeprecatedHeadersCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..bbb5ff7 100644
--- a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h
+++ b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f98a1dc 100644
--- a/clang-tidy/modernize/LoopConvertCheck.h
+++ b/clang-tidy/modernize/LoopConvertCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..9b0c5d8 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tidy/modernize/MakeSmartPtrCheck.h
index 02428d7..82855e2 100644
--- a/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ b/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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 6bad6cb..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -32,6 +31,7 @@
 #include "UseEmplaceCheck.h"
 #include "UseEqualsDefaultCheck.h"
 #include "UseEqualsDeleteCheck.h"
+#include "UseNodiscardCheck.h"
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
@@ -82,6 +82,8 @@
     CheckFactories.registerCheck<UseEqualsDefaultCheck>("modernize-use-equals-default");
     CheckFactories.registerCheck<UseEqualsDeleteCheck>(
         "modernize-use-equals-delete");
+    CheckFactories.registerCheck<UseNodiscardCheck>(
+        "modernize-use-nodiscard");
     CheckFactories.registerCheck<UseNoexceptCheck>("modernize-use-noexcept");
     CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr");
     CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
diff --git a/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tidy/modernize/PassByValueCheck.cpp
index f54c575..15c3725 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/PassByValueCheck.h b/clang-tidy/modernize/PassByValueCheck.h
index 37deb3f..fde6517 100644
--- a/clang-tidy/modernize/PassByValueCheck.h
+++ b/clang-tidy/modernize/PassByValueCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..370400c 100644
--- a/clang-tidy/modernize/RawStringLiteralCheck.h
+++ b/clang-tidy/modernize/RawStringLiteralCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tidy/modernize/RedundantVoidArgCheck.cpp
index ea49ab7..96eb7a2 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.h b/clang-tidy/modernize/RedundantVoidArgCheck.h
index c990ef4..6c90fa3 100644
--- a/clang-tidy/modernize/RedundantVoidArgCheck.h
+++ b/clang-tidy/modernize/RedundantVoidArgCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
index 3281ef6..0de835e 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.h b/clang-tidy/modernize/ReplaceAutoPtrCheck.h
index 5b73d51..174676e 100644
--- a/clang-tidy/modernize/ReplaceAutoPtrCheck.h
+++ b/clang-tidy/modernize/ReplaceAutoPtrCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
index 9a71569..73afec7 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
index 050d740..6536708 100644
--- a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
+++ b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2c60a4e 100644
--- a/clang-tidy/modernize/ReturnBracedInitListCheck.h
+++ b/clang-tidy/modernize/ReturnBracedInitListCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2f87374 100644
--- a/clang-tidy/modernize/ShrinkToFitCheck.h
+++ b/clang-tidy/modernize/ShrinkToFitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..e1e9588 100644
--- a/clang-tidy/modernize/UnaryStaticAssertCheck.h
+++ b/clang-tidy/modernize/UnaryStaticAssertCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f10cd08 100644
--- a/clang-tidy/modernize/UseAutoCheck.h
+++ b/clang-tidy/modernize/UseAutoCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..898d9f3 100644
--- a/clang-tidy/modernize/UseBoolLiteralsCheck.h
+++ b/clang-tidy/modernize/UseBoolLiteralsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..77f0e73 100644
--- a/clang-tidy/modernize/UseDefaultMemberInitCheck.h
+++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6a55ffb 100644
--- a/clang-tidy/modernize/UseEmplaceCheck.h
+++ b/clang-tidy/modernize/UseEmplaceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..486ccb2 100644
--- a/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ b/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7d1c74d 100644
--- a/clang-tidy/modernize/UseEqualsDeleteCheck.h
+++ b/clang-tidy/modernize/UseEqualsDeleteCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tidy/modernize/UseNodiscardCheck.cpp
new file mode 100644
index 0000000..d2ac7d5
--- /dev/null
+++ b/clang-tidy/modernize/UseNodiscardCheck.cpp
@@ -0,0 +1,144 @@
+//===--- UseNodiscardCheck.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 "UseNodiscardCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+static bool doesNoDiscardMacroExist(ASTContext &Context,
+                                    const llvm::StringRef &MacroId) {
+  // Don't check for the Macro existence if we are using an attribute
+  // either a C++17 standard attribute or pre C++17 syntax
+  if (MacroId.startswith("[[") || MacroId.startswith("__attribute__"))
+    return true;
+
+  // Otherwise look up the macro name in the context to see if its defined.
+  return Context.Idents.get(MacroId).hasMacroDefinition();
+}
+
+namespace {
+AST_MATCHER(CXXMethodDecl, isOverloadedOperator) {
+  // Don't put ``[[nodiscard]]`` in front of operators.
+  return Node.isOverloadedOperator();
+}
+AST_MATCHER(CXXMethodDecl, isConversionOperator) {
+  // Don't put ``[[nodiscard]]`` in front of a conversion decl
+  // like operator bool().
+  return isa<CXXConversionDecl>(Node);
+}
+AST_MATCHER(CXXMethodDecl, hasClassMutableFields) {
+  // Don't put ``[[nodiscard]]`` on functions on classes with
+  // mutable member variables.
+  return Node.getParent()->hasMutableFields();
+}
+AST_MATCHER(ParmVarDecl, hasParameterPack) {
+  // Don't put ``[[nodiscard]]`` on functions with parameter pack arguments.
+  return Node.isParameterPack();
+}
+AST_MATCHER(CXXMethodDecl, hasTemplateReturnType) {
+  // Don't put ``[[nodiscard]]`` in front of functions returning a template
+  // type.
+  return Node.getReturnType()->isTemplateTypeParmType() ||
+         Node.getReturnType()->isInstantiationDependentType();
+}
+AST_MATCHER(CXXMethodDecl, isDefinitionOrInline) {
+  // A function definition, with optional inline but not the declaration.
+  return !(Node.isThisDeclarationADefinition() && Node.isOutOfLine());
+}
+AST_MATCHER(QualType, isInstantiationDependentType) {
+  return Node->isInstantiationDependentType();
+}
+AST_MATCHER(QualType, isNonConstReferenceOrPointer) {
+  // If the function has any non-const-reference arguments
+  //    bool foo(A &a)
+  // or pointer arguments
+  //    bool foo(A*)
+  // then they may not care about the return value because of passing data
+  // via the arguments.
+  return (Node->isTemplateTypeParmType() || Node->isPointerType() ||
+          (Node->isReferenceType() &&
+           !Node.getNonReferenceType().isConstQualified()) ||
+          Node->isInstantiationDependentType());
+}
+} // namespace
+
+UseNodiscardCheck::UseNodiscardCheck(StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      NoDiscardMacro(Options.get("ReplacementString", "[[nodiscard]]")) {}
+
+void UseNodiscardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "ReplacementString", NoDiscardMacro);
+}
+
+void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) {
+  // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a
+  // macro or ``__attribute__`` with pre c++17 compilers by using
+  // ReplacementString option.
+  if ((NoDiscardMacro == "[[nodiscard]]" && !getLangOpts().CPlusPlus17) ||
+      !getLangOpts().CPlusPlus)
+    return;
+
+  auto FunctionObj =
+      cxxRecordDecl(hasAnyName("::std::function", "::boost::function"));
+
+  // Find all non-void const methods which have not already been marked to
+  // warn on unused result.
+  Finder->addMatcher(
+      cxxMethodDecl(
+          allOf(isConst(), isDefinitionOrInline(),
+                unless(anyOf(
+                    returns(voidType()), isNoReturn(), isOverloadedOperator(),
+                    isVariadic(), hasTemplateReturnType(),
+                    hasClassMutableFields(), isConversionOperator(),
+                    hasAttr(clang::attr::WarnUnusedResult),
+                    hasType(isInstantiationDependentType()),
+                    hasAnyParameter(anyOf(
+                        parmVarDecl(anyOf(hasType(FunctionObj),
+                                          hasType(references(FunctionObj)))),
+                        hasType(isNonConstReferenceOrPointer()),
+                        hasParameterPack()))))))
+          .bind("no_discard"),
+      this);
+}
+
+void UseNodiscardCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<CXXMethodDecl>("no_discard");
+  // Don't make replacements if the location is invalid or in a macro.
+  SourceLocation Loc = MatchedDecl->getLocation();
+  if (Loc.isInvalid() || Loc.isMacroID())
+    return;
+
+  SourceLocation RetLoc = MatchedDecl->getInnerLocStart();
+
+  ASTContext &Context = *Result.Context;
+
+  auto Diag = diag(RetLoc, "function %0 should be marked " + NoDiscardMacro)
+              << MatchedDecl;
+
+  // Check for the existence of the keyword being used as the ``[[nodiscard]]``.
+  if (!doesNoDiscardMacroExist(Context, NoDiscardMacro))
+    return;
+
+  // Possible false positives include:
+  // 1. A const member function which returns a variable which is ignored
+  // but performs some external I/O operation and the return value could be
+  // ignored.
+  Diag << FixItHint::CreateInsertion(RetLoc, NoDiscardMacro + " ");
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/modernize/UseNodiscardCheck.h b/clang-tidy/modernize/UseNodiscardCheck.h
new file mode 100644
index 0000000..004ef58
--- /dev/null
+++ b/clang-tidy/modernize/UseNodiscardCheck.h
@@ -0,0 +1,49 @@
+//===--- UseNodiscardCheck.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_MODERNIZE_USENODISCARDCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USENODISCARDCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// \brief Add ``[[nodiscard]]`` to non-void const-member functions with no
+/// arguments or pass-by-value or pass by const-reference arguments.
+/// \code
+///    bool empty() const;
+///    bool empty(const Bar &) const;
+///    bool empty(int bar) const;
+/// \endcode
+/// Is converted to:
+/// \code
+///    [[nodiscard]] bool empty() const;
+///    [[nodiscard]] bool empty(const Bar &) const;
+///    [[nodiscard]] bool empty(int bar) const;
+/// \endcode
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-nodiscard.html
+class UseNodiscardCheck : public ClangTidyCheck {
+public:
+  UseNodiscardCheck(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 std::string NoDiscardMacro;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USENODISCARDCHECK_H
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..f947d5d 100644
--- a/clang-tidy/modernize/UseNoexceptCheck.h
+++ b/clang-tidy/modernize/UseNoexceptCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..7fa8b4f 100644
--- a/clang-tidy/modernize/UseNullptrCheck.h
+++ b/clang-tidy/modernize/UseNullptrCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tidy/modernize/UseOverrideCheck.cpp
index 9429eb2..6b06595 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/modernize/UseOverrideCheck.h b/clang-tidy/modernize/UseOverrideCheck.h
index 83ce7da..0f31609 100644
--- a/clang-tidy/modernize/UseOverrideCheck.h
+++ b/clang-tidy/modernize/UseOverrideCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..effc754 100644
--- a/clang-tidy/modernize/UseTransparentFunctorsCheck.h
+++ b/clang-tidy/modernize/UseTransparentFunctorsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..80db6a6 100644
--- a/clang-tidy/modernize/UseUncaughtExceptionsCheck.h
+++ b/clang-tidy/modernize/UseUncaughtExceptionsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..0975751 100644
--- a/clang-tidy/modernize/UseUsingCheck.h
+++ b/clang-tidy/modernize/UseUsingCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..833608b 100644
--- a/clang-tidy/mpi/BufferDerefCheck.h
+++ b/clang-tidy/mpi/BufferDerefCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..28ff605 100644
--- a/clang-tidy/mpi/TypeMismatchCheck.h
+++ b/clang-tidy/mpi/TypeMismatchCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..33deaba 100644
--- a/clang-tidy/objc/AvoidNSErrorInitCheck.h
+++ b/clang-tidy/objc/AvoidNSErrorInitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2a3cd40 100644
--- a/clang-tidy/objc/AvoidSpinlockCheck.h
+++ b/clang-tidy/objc/AvoidSpinlockCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..93ebc7e 100644
--- a/clang-tidy/objc/ForbiddenSubclassingCheck.h
+++ b/clang-tidy/objc/ForbiddenSubclassingCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tidy/objc/ObjCTidyModule.cpp
index 19152c2..5686c9f 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp
index 94b82f0..653c6bb 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h
index b2683ba..d28bde4 100644
--- a/clang-tidy/objc/PropertyDeclarationCheck.h
+++ b/clang-tidy/objc/PropertyDeclarationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..9b28e50 100644
--- a/clang-tidy/performance/FasterStringFindCheck.h
+++ b/clang-tidy/performance/FasterStringFindCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..6621f39 100644
--- a/clang-tidy/performance/ForRangeCopyCheck.h
+++ b/clang-tidy/performance/ForRangeCopyCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..3c27498 100644
--- a/clang-tidy/performance/ImplicitConversionInLoopCheck.h
+++ b/clang-tidy/performance/ImplicitConversionInLoopCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..09e2c95 100644
--- a/clang-tidy/performance/InefficientAlgorithmCheck.h
+++ b/clang-tidy/performance/InefficientAlgorithmCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..cfefa33 100644
--- a/clang-tidy/performance/InefficientStringConcatenationCheck.h
+++ b/clang-tidy/performance/InefficientStringConcatenationCheck.h
@@ -1,10 +1,9 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..c978592 100644
--- a/clang-tidy/performance/InefficientVectorOperationCheck.h
+++ b/clang-tidy/performance/InefficientVectorOperationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..ec1b81b 100644
--- a/clang-tidy/performance/MoveConstArgCheck.h
+++ b/clang-tidy/performance/MoveConstArgCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tidy/performance/MoveConstructorInitCheck.cpp
index 52283fb..abc5f4f 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/MoveConstructorInitCheck.h b/clang-tidy/performance/MoveConstructorInitCheck.h
index 3b7dda0..34a202e 100644
--- a/clang-tidy/performance/MoveConstructorInitCheck.h
+++ b/clang-tidy/performance/MoveConstructorInitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..43a8345 100644
--- a/clang-tidy/performance/NoexceptMoveConstructorCheck.h
+++ b/clang-tidy/performance/NoexceptMoveConstructorCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tidy/performance/PerformanceTidyModule.cpp
index 646c659..0a5a0be 100644
--- a/clang-tidy/performance/PerformanceTidyModule.cpp
+++ b/clang-tidy/performance/PerformanceTidyModule.cpp
@@ -1,9 +1,8 @@
 //===--- PeformanceTidyModule.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..7b9b1f7 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/TypePromotionInMathFnCheck.h b/clang-tidy/performance/TypePromotionInMathFnCheck.h
index 2242957..bb5900a 100644
--- a/clang-tidy/performance/TypePromotionInMathFnCheck.h
+++ b/clang-tidy/performance/TypePromotionInMathFnCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..bf785e6 100644
--- a/clang-tidy/performance/UnnecessaryCopyInitialization.h
+++ b/clang-tidy/performance/UnnecessaryCopyInitialization.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
index ff3674f..44f5fc2 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.h b/clang-tidy/performance/UnnecessaryValueParamCheck.h
index a1d6586..84252ed 100644
--- a/clang-tidy/performance/UnnecessaryValueParamCheck.h
+++ b/clang-tidy/performance/UnnecessaryValueParamCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..9d5cb55 100644
--- a/clang-tidy/portability/SIMDIntrinsicsCheck.h
+++ b/clang-tidy/portability/SIMDIntrinsicsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..c8b96b6 100644
--- a/clang-tidy/readability/AvoidConstParamsInDecls.h
+++ b/clang-tidy/readability/AvoidConstParamsInDecls.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..fb45def 100644
--- a/clang-tidy/readability/BracesAroundStatementsCheck.h
+++ b/clang-tidy/readability/BracesAroundStatementsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/CMakeLists.txt b/clang-tidy/readability/CMakeLists.txt
index c429b81..b48e307 100644
--- a/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tidy/readability/CMakeLists.txt
@@ -24,6 +24,7 @@
   RedundantDeclarationCheck.cpp
   RedundantFunctionPtrDereferenceCheck.cpp
   RedundantMemberInitCheck.cpp
+  RedundantPreprocessorCheck.cpp
   RedundantSmartptrGetCheck.cpp
   RedundantStringCStrCheck.cpp
   RedundantStringInitCheck.cpp
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..58ebc55 100644
--- a/clang-tidy/readability/ConstReturnTypeCheck.h
+++ b/clang-tidy/readability/ConstReturnTypeCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..3d8615b 100644
--- a/clang-tidy/readability/ContainerSizeEmptyCheck.h
+++ b/clang-tidy/readability/ContainerSizeEmptyCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f877322 100644
--- a/clang-tidy/readability/DeleteNullPointerCheck.h
+++ b/clang-tidy/readability/DeleteNullPointerCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..5acf6e2 100644
--- a/clang-tidy/readability/DeletedDefaultCheck.h
+++ b/clang-tidy/readability/DeletedDefaultCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2feb3aa 100644
--- a/clang-tidy/readability/ElseAfterReturnCheck.h
+++ b/clang-tidy/readability/ElseAfterReturnCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tidy/readability/FunctionSizeCheck.cpp
index 9547afb..7be502b 100644
--- a/clang-tidy/readability/FunctionSizeCheck.cpp
+++ b/clang-tidy/readability/FunctionSizeCheck.cpp
@@ -1,9 +1,8 @@
 //===--- FunctionSize.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
 //
 //===----------------------------------------------------------------------===//
 
@@ -145,7 +144,12 @@
 }
 
 void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(functionDecl(unless(isInstantiated())).bind("func"), this);
+  // Lambdas ignored - historically considered part of enclosing function.
+  // FIXME: include them instead? Top-level lambdas are currently never counted.
+  Finder->addMatcher(functionDecl(unless(isInstantiated()),
+                                  unless(cxxMethodDecl(ofClass(isLambda()))))
+                         .bind("func"),
+                     this);
 }
 
 void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tidy/readability/FunctionSizeCheck.h b/clang-tidy/readability/FunctionSizeCheck.h
index 7defccd..33340e6 100644
--- a/clang-tidy/readability/FunctionSizeCheck.h
+++ b/clang-tidy/readability/FunctionSizeCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tidy/readability/IdentifierNamingCheck.cpp
index fb3c02e..56ece5c 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tidy/readability/IdentifierNamingCheck.h
index c236ad5..0023a6f 100644
--- a/clang-tidy/readability/IdentifierNamingCheck.h
+++ b/clang-tidy/readability/IdentifierNamingCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..91d14a7 100644
--- a/clang-tidy/readability/ImplicitBoolConversionCheck.h
+++ b/clang-tidy/readability/ImplicitBoolConversionCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..2002b09 100644
--- a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h
+++ b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h
@@ -1,9 +1,8 @@
 //===- 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
 //
 //===----------------------------------------------------------------------===//
 
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..a172d21 100644
--- a/clang-tidy/readability/IsolateDeclarationCheck.h
+++ b/clang-tidy/readability/IsolateDeclarationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..1ec9db2 100644
--- a/clang-tidy/readability/MagicNumbersCheck.h
+++ b/clang-tidy/readability/MagicNumbersCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tidy/readability/MisleadingIndentationCheck.cpp
index 9791531..767406e 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/MisleadingIndentationCheck.h b/clang-tidy/readability/MisleadingIndentationCheck.h
index 0ca50bb..c39212a 100644
--- a/clang-tidy/readability/MisleadingIndentationCheck.h
+++ b/clang-tidy/readability/MisleadingIndentationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..55bab95 100644
--- a/clang-tidy/readability/MisplacedArrayIndexCheck.h
+++ b/clang-tidy/readability/MisplacedArrayIndexCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f783c58 100644
--- a/clang-tidy/readability/NamedParameterCheck.h
+++ b/clang-tidy/readability/NamedParameterCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tidy/readability/NamespaceCommentCheck.cpp
index 229cc62..17184ec 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/NamespaceCommentCheck.h b/clang-tidy/readability/NamespaceCommentCheck.h
index 1b1a231..8fb3275 100644
--- a/clang-tidy/readability/NamespaceCommentCheck.h
+++ b/clang-tidy/readability/NamespaceCommentCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..74634c2 100644
--- a/clang-tidy/readability/NonConstParameterCheck.h
+++ b/clang-tidy/readability/NonConstParameterCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tidy/readability/ReadabilityTidyModule.cpp
index 8dab296..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,6 +30,7 @@
 #include "RedundantDeclarationCheck.h"
 #include "RedundantFunctionPtrDereferenceCheck.h"
 #include "RedundantMemberInitCheck.h"
+#include "RedundantPreprocessorCheck.h"
 #include "RedundantSmartptrGetCheck.h"
 #include "RedundantStringCStrCheck.h"
 #include "RedundantStringInitCheck.h"
@@ -83,6 +83,8 @@
         "readability-redundant-function-ptr-dereference");
     CheckFactories.registerCheck<RedundantMemberInitCheck>(
         "readability-redundant-member-init");
+    CheckFactories.registerCheck<RedundantPreprocessorCheck>(
+        "readability-redundant-preprocessor");
     CheckFactories.registerCheck<SimplifySubscriptExprCheck>(
         "readability-simplify-subscript-expr");
     CheckFactories.registerCheck<StaticAccessedThroughInstanceCheck>(
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..1943398 100644
--- a/clang-tidy/readability/RedundantControlFlowCheck.h
+++ b/clang-tidy/readability/RedundantControlFlowCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..5286bff 100644
--- a/clang-tidy/readability/RedundantDeclarationCheck.h
+++ b/clang-tidy/readability/RedundantDeclarationCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..19db1d3 100644
--- a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h
+++ b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..f4c4c09 100644
--- a/clang-tidy/readability/RedundantMemberInitCheck.h
+++ b/clang-tidy/readability/RedundantMemberInitCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.cpp b/clang-tidy/readability/RedundantPreprocessorCheck.cpp
new file mode 100644
index 0000000..e208c58
--- /dev/null
+++ b/clang-tidy/readability/RedundantPreprocessorCheck.cpp
@@ -0,0 +1,108 @@
+//===--- RedundantPreprocessorCheck.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 "RedundantPreprocessorCheck.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+namespace {
+/// Information about an opening preprocessor directive.
+struct PreprocessorEntry {
+  SourceLocation Loc;
+  /// Condition used after the preprocessor directive.
+  std::string Condition;
+};
+
+class RedundantPreprocessorCallbacks : public PPCallbacks {
+  enum DirectiveKind { DK_If = 0, DK_Ifdef = 1, DK_Ifndef = 2 };
+
+public:
+  explicit RedundantPreprocessorCallbacks(ClangTidyCheck &Check,
+                                          Preprocessor &PP)
+      : Check(Check), PP(PP),
+        WarningDescription("nested redundant %select{#if|#ifdef|#ifndef}0; "
+                           "consider removing it"),
+        NoteDescription("previous %select{#if|#ifdef|#ifndef}0 was here") {}
+
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override {
+    StringRef Condition =
+        Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange),
+                             PP.getSourceManager(), PP.getLangOpts());
+    CheckMacroRedundancy(Loc, Condition, IfStack, DK_If, DK_If, true);
+  }
+
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDefinition &MacroDefinition) override {
+    std::string MacroName = PP.getSpelling(MacroNameTok);
+    CheckMacroRedundancy(Loc, MacroName, IfdefStack, DK_Ifdef, DK_Ifdef, true);
+    CheckMacroRedundancy(Loc, MacroName, IfndefStack, DK_Ifdef, DK_Ifndef,
+                         false);
+  }
+
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDefinition &MacroDefinition) override {
+    std::string MacroName = PP.getSpelling(MacroNameTok);
+    CheckMacroRedundancy(Loc, MacroName, IfndefStack, DK_Ifndef, DK_Ifndef,
+                         true);
+    CheckMacroRedundancy(Loc, MacroName, IfdefStack, DK_Ifndef, DK_Ifdef,
+                         false);
+  }
+
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
+    if (!IfStack.empty() && IfLoc == IfStack.back().Loc)
+      IfStack.pop_back();
+    if (!IfdefStack.empty() && IfLoc == IfdefStack.back().Loc)
+      IfdefStack.pop_back();
+    if (!IfndefStack.empty() && IfLoc == IfndefStack.back().Loc)
+      IfndefStack.pop_back();
+  }
+
+private:
+  void CheckMacroRedundancy(SourceLocation Loc, StringRef MacroName,
+                            SmallVector<PreprocessorEntry, 4> &Stack,
+                            DirectiveKind WarningKind, DirectiveKind NoteKind,
+                            bool Store) {
+    if (PP.getSourceManager().isInMainFile(Loc)) {
+      for (const auto &Entry : Stack) {
+        if (Entry.Condition == MacroName) {
+          Check.diag(Loc, WarningDescription) << WarningKind;
+          Check.diag(Entry.Loc, NoteDescription, DiagnosticIDs::Note)
+              << NoteKind;
+        }
+      }
+    }
+
+    if (Store)
+      // This is an actual directive to be remembered.
+      Stack.push_back({Loc, MacroName});
+  }
+
+  ClangTidyCheck &Check;
+  Preprocessor &PP;
+  SmallVector<PreprocessorEntry, 4> IfStack;
+  SmallVector<PreprocessorEntry, 4> IfdefStack;
+  SmallVector<PreprocessorEntry, 4> IfndefStack;
+  const std::string WarningDescription;
+  const std::string NoteDescription;
+};
+} // namespace
+
+void RedundantPreprocessorCheck::registerPPCallbacks(
+    CompilerInstance &Compiler) {
+  Compiler.getPreprocessor().addPPCallbacks(
+      ::llvm::make_unique<RedundantPreprocessorCallbacks>(
+          *this, Compiler.getPreprocessor()));
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.h b/clang-tidy/readability/RedundantPreprocessorCheck.h
new file mode 100644
index 0000000..cb70ac7
--- /dev/null
+++ b/clang-tidy/readability/RedundantPreprocessorCheck.h
@@ -0,0 +1,34 @@
+//===--- RedundantPreprocessorCheck.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_READABILITY_REDUNDANTPREPROCESSORCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPREPROCESSORCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// This check flags redundant preprocessor directives: nested directives with
+/// the same condition.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundant-preprocessor.html
+class RedundantPreprocessorCheck : public ClangTidyCheck {
+public:
+  RedundantPreprocessorCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPREPROCESSORCHECK_H
diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tidy/readability/RedundantSmartptrGetCheck.cpp
index 189130e..73157c9 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.h b/clang-tidy/readability/RedundantSmartptrGetCheck.h
index a6f5706..d4d311f 100644
--- a/clang-tidy/readability/RedundantSmartptrGetCheck.h
+++ b/clang-tidy/readability/RedundantSmartptrGetCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..dd53e18 100644
--- a/clang-tidy/readability/RedundantStringCStrCheck.h
+++ b/clang-tidy/readability/RedundantStringCStrCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..38399ed 100644
--- a/clang-tidy/readability/RedundantStringInitCheck.h
+++ b/clang-tidy/readability/RedundantStringInitCheck.h
@@ -1,9 +1,8 @@
 //===- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
index b565a5f..aa58ad1 100644
--- a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -1,9 +1,8 @@
 //===--- SimplifyBooleanExpr.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
 //
 //===----------------------------------------------------------------------===//
 
@@ -319,8 +318,6 @@
 } // namespace
 
 class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
-  using Base = RecursiveASTVisitor<Visitor>;
-
  public:
   Visitor(SimplifyBooleanExprCheck *Check,
           const MatchFinder::MatchResult &Result)
@@ -507,16 +504,8 @@
                 ChainedConditionalAssignment);
 }
 
-// This is a silly hack to let us run a RecursiveASTVisitor on the Context.
-// We want to match exactly one node in the AST, doesn't matter which.
-AST_MATCHER_P(Decl, matchOnce, bool *, Matched) {
-  if (*Matched)
-    return false;
-  return *Matched = true;
-}
-
 void SimplifyBooleanExprCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(matchOnce(&MatchedOnce), this);
+  Finder->addMatcher(translationUnitDecl().bind("top"), this);
 
   matchBoolCondition(Finder, true, ConditionThenStmtId);
   matchBoolCondition(Finder, false, ConditionElseStmtId);
@@ -535,8 +524,10 @@
 }
 
 void SimplifyBooleanExprCheck::check(const MatchFinder::MatchResult &Result) {
-  if (const CXXBoolLiteralExpr *TrueConditionRemoved =
-          getBoolLiteral(Result, ConditionThenStmtId))
+  if (Result.Nodes.getNodeAs<TranslationUnitDecl>("top"))
+    Visitor(this, Result).TraverseAST(*Result.Context);
+  else if (const CXXBoolLiteralExpr *TrueConditionRemoved =
+               getBoolLiteral(Result, ConditionThenStmtId))
     replaceWithThenStatement(Result, TrueConditionRemoved);
   else if (const CXXBoolLiteralExpr *FalseConditionRemoved =
                getBoolLiteral(Result, ConditionElseStmtId))
@@ -564,10 +555,6 @@
   else if (const auto *Compound =
                Result.Nodes.getNodeAs<CompoundStmt>(CompoundNotBoolId))
     replaceCompoundReturnWithCondition(Result, Compound, true);
-  else { // MatchOnce matcher
-    assert(MatchedOnce);
-    Visitor(this, Result).TraverseAST(*Result.Context);
-  }
 }
 
 void SimplifyBooleanExprCheck::issueDiag(
diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tidy/readability/SimplifyBooleanExprCheck.h
index 14ac82d..dc1daa2 100644
--- a/clang-tidy/readability/SimplifyBooleanExprCheck.h
+++ b/clang-tidy/readability/SimplifyBooleanExprCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -79,7 +78,6 @@
                  SourceLocation Loc, StringRef Description,
                  SourceRange ReplacementRange, StringRef Replacement);
 
-  bool MatchedOnce = false;
   const bool ChainedConditionalReturn;
   const bool ChainedConditionalAssignment;
 };
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..2929fbe 100644
--- a/clang-tidy/readability/SimplifySubscriptExprCheck.h
+++ b/clang-tidy/readability/SimplifySubscriptExprCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..d01d8ac 100644
--- a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h
+++ b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..1260197 100644
--- a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
+++ b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/StringCompareCheck.cpp b/clang-tidy/readability/StringCompareCheck.cpp
index 38ac43f..395f406 100644
--- a/clang-tidy/readability/StringCompareCheck.cpp
+++ b/clang-tidy/readability/StringCompareCheck.cpp
@@ -1,9 +1,8 @@
 //===--- MiscStringCompare.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..39e5bd5 100644
--- a/clang-tidy/readability/StringCompareCheck.h
+++ b/clang-tidy/readability/StringCompareCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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..492c642 100644
--- a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
+++ b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp
index eeaece1..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -183,12 +182,14 @@
     StringRef Name, ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       NewSuffixes(
-          utils::options::parseStringList(Options.get("NewSuffixes", ""))) {}
+          utils::options::parseStringList(Options.get("NewSuffixes", ""))),
+      IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", 1) != 0) {}
 
 void UppercaseLiteralSuffixCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "NewSuffixes",
                 utils::options::serializeStringList(NewSuffixes));
+  Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
 void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) {
@@ -216,6 +217,8 @@
   // We might have a suffix that is already uppercase.
   if (auto Details = shouldReplaceLiteralSuffix<LiteralType>(
           *Literal, NewSuffixes, *Result.SourceManager, getLangOpts())) {
+    if (Details->LiteralLocation.getBegin().isMacroID() && IgnoreMacros)
+      return true;
     auto Complaint = diag(Details->LiteralLocation.getBegin(),
                           "%0 literal has suffix '%1', which is not uppercase")
                      << LiteralType::Name << Details->OldSuffix;
diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
index 8d26e6c..69ddd63 100644
--- a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
+++ b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -35,6 +34,7 @@
   bool checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result);
 
   const std::vector<std::string> NewSuffixes;
+  const bool IgnoreMacros;
 };
 
 } // namespace readability
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/ClangTidyMain.cpp b/clang-tidy/tool/ClangTidyMain.cpp
index 12a6024..469f360 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
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clang-tidy/tool/clang-tidy-diff.py b/clang-tidy/tool/clang-tidy-diff.py
index f2c15e5..cf6db4a 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
 #
 #===------------------------------------------------------------------------===#
 
@@ -57,6 +56,9 @@
                       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.')
   parser.add_argument('-extra-arg', dest='extra_arg',
                       action='append', default=[],
                       help='Additional argument to append to the compiler '
@@ -122,6 +124,8 @@
   command.append('-line-filter=' + quote + line_filter_json + quote)
   if args.fix:
     command.append('-fix')
+  if args.export_fixes:
+    command.append('-export-fixes=' + args.export_fixes)
   if args.checks != '':
     command.append('-checks=' + quote + args.checks + quote)
   if args.quiet:
diff --git a/clang-tidy/tool/run-clang-tidy.py b/clang-tidy/tool/run-clang-tidy.py
index 93635cb..5ec40f2 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
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..7f1ca52
--- /dev/null
+++ b/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -0,0 +1,154 @@
+//===--- 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"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+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; });
+}
+
+namespace tidy {
+namespace utils {
+
+ExceptionAnalyzer::TypeVec ExceptionAnalyzer::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;
+}
+
+ExceptionAnalyzer::TypeVec ExceptionAnalyzer::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;
+}
+
+bool ExceptionAnalyzer::throwsException(const FunctionDecl *Func) {
+  // Check if the function has already been analyzed and reuse that result.
+  if (FunctionCache.count(Func) > 0)
+    return FunctionCache[Func];
+
+  llvm::SmallSet<const FunctionDecl *, 32> CallStack;
+  TypeVec ExceptionList = throwsException(Func, CallStack);
+
+  // Remove all ignored exceptions from the list of exceptions that can be
+  // thrown.
+  auto NewEnd = llvm::remove_if(ExceptionList, [this](const Type *Exception) {
+    return isIgnoredExceptionType(Exception);
+  });
+  ExceptionList.erase(NewEnd, ExceptionList.end());
+
+  // Cache the result of the analysis.
+  bool FunctionThrows = ExceptionList.size() > 0;
+  FunctionCache.insert(std::make_pair(Func, FunctionThrows));
+
+  return FunctionThrows;
+}
+
+bool ExceptionAnalyzer::isIgnoredExceptionType(const Type *Exception) {
+  if (const auto *TD = Exception->getAsTagDecl()) {
+    if (TD->getDeclName().isIdentifier())
+      return IgnoredExceptions.count(TD->getName()) > 0;
+  }
+  return false;
+}
+
+} // 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..327da30
--- /dev/null
+++ b/clang-tidy/utils/ExceptionAnalyzer.h
@@ -0,0 +1,48 @@
+//===--- 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 "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:
+  ExceptionAnalyzer() = default;
+
+  bool throwsException(const FunctionDecl *Func);
+  void ignoreExceptions(llvm::StringSet<> ExceptionNames) {
+    IgnoredExceptions = std::move(ExceptionNames);
+  }
+
+private:
+  using TypeVec = llvm::SmallVector<const Type *, 8>;
+
+  TypeVec throwsException(const FunctionDecl *Func,
+                          llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
+  TypeVec throwsException(const Stmt *St, const TypeVec &Caught,
+                          llvm::SmallSet<const FunctionDecl *, 32> &CallStack);
+  bool isIgnoredExceptionType(const Type *Exception);
+
+  llvm::StringSet<> IgnoredExceptions;
+  llvm::DenseMap<const FunctionDecl *, bool> 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..cc56b3f 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clang-tidy/utils/HeaderGuard.h b/clang-tidy/utils/HeaderGuard.h
index a2d8288..f2062e5 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
 //
 //===----------------------------------------------------------------------===//
 
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..a56b5ab 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
 //
 //===----------------------------------------------------------------------===//
 
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..30b7664 100644
--- a/clang-tidy/utils/OptionsUtils.cpp
+++ b/clang-tidy/utils/OptionsUtils.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
 //
 //===----------------------------------------------------------------------===//
 
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..ae06601 100644
--- a/clang-tidy/zircon/TemporaryObjectsCheck.h
+++ b/clang-tidy/zircon/TemporaryObjectsCheck.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
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 dea4567..47559c1 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -18,7 +17,6 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ScopedPrinter.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -35,8 +33,8 @@
   // macros, we should use the location where the whole definition occurs.
   if (Loc.isMacroID()) {
     std::string PrintLoc = SM.getSpellingLoc(Loc).printToString(SM);
-    if (StringRef(PrintLoc).startswith("<scratch") ||
-        StringRef(PrintLoc).startswith("<command line>"))
+    if (llvm::StringRef(PrintLoc).startswith("<scratch") ||
+        llvm::StringRef(PrintLoc).startswith("<command line>"))
       return false;
   }
   return true;
@@ -44,7 +42,7 @@
 
 bool isImplementationDetail(const Decl *D) { return !isSpelledInSourceCode(D); }
 
-SourceLocation findNameLoc(const clang::Decl* D) {
+SourceLocation findNameLoc(const clang::Decl *D) {
   const auto &SM = D->getASTContext().getSourceManager();
   if (!isSpelledInSourceCode(D))
     // Use the expansion location as spelling location is not interesting.
@@ -54,7 +52,7 @@
 
 std::string printQualifiedName(const NamedDecl &ND) {
   std::string QName;
-  raw_string_ostream OS(QName);
+  llvm::raw_string_ostream OS(QName);
   PrintingPolicy Policy(ND.getASTContext().getLangOpts());
   // Note that inline namespaces are treated as transparent scopes. This
   // reflects the way they're most commonly used for lookup. Ideally we'd
@@ -115,18 +113,19 @@
   return "";
 }
 
-Optional<SymbolID> getSymbolID(const Decl *D) {
-  SmallString<128> USR;
+llvm::Optional<SymbolID> getSymbolID(const Decl *D) {
+  llvm::SmallString<128> USR;
   if (index::generateUSRForDecl(D, USR))
     return None;
   return SymbolID(USR);
 }
 
-Optional<SymbolID> getSymbolID(const IdentifierInfo &II, const MacroInfo *MI,
-                               const SourceManager &SM) {
+llvm::Optional<SymbolID> getSymbolID(const IdentifierInfo &II,
+                                     const MacroInfo *MI,
+                                     const SourceManager &SM) {
   if (MI == nullptr)
     return None;
-  SmallString<128> USR;
+  llvm::SmallString<128> USR;
   if (index::generateUSRForMacro(II.getName(), MI->getDefinitionLoc(), SM, USR))
     return None;
   return SymbolID(USR);
diff --git a/clangd/AST.h b/clangd/AST.h
index aa787ac..15c46a4 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,9 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_
 
+#include "index/Index.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/SourceLocation.h"
-#include "index/Index.h"
 
 namespace clang {
 class SourceManager;
diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt
index 39467bd..6db7892 100644
--- a/clangd/CMakeLists.txt
+++ b/clangd/CMakeLists.txt
@@ -1,7 +1,20 @@
+# Configure the Features.inc file.
+llvm_canonicalize_cmake_booleans(
+  CLANGD_BUILD_XPC)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/Features.inc.in
+  ${CMAKE_CURRENT_BINARY_DIR}/Features.inc
+)
+
 set(LLVM_LINK_COMPONENTS
   Support
   )
 
+if(CLANG_BUILT_STANDALONE)
+  # needed to get HAVE_CXX_ATOMICS64_WITHOUT_LIB defined
+  include(CheckAtomic)
+endif()
+
 set(CLANGD_ATOMIC_LIB "")
 if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
   list(APPEND CLANGD_ATOMIC_LIB "atomic")
@@ -27,11 +40,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
@@ -57,6 +72,8 @@
   index/dex/PostingList.cpp
   index/dex/Trigram.cpp
 
+  refactor/Tweak.cpp
+
   LINK_LIBS
   clangAST
   clangASTMatchers
@@ -94,6 +111,7 @@
   ${CLANGD_ATOMIC_LIB}
   )
 
+add_subdirectory(refactor/tweaks)
 if( LLVM_LIB_FUZZING_ENGINE OR LLVM_USE_SANITIZE_COVERAGE )
   add_subdirectory(fuzzer)
 endif()
@@ -104,3 +122,6 @@
 if (LLVM_INCLUDE_BENCHMARKS)
   add_subdirectory(benchmarks)
 endif()
+if ( CLANGD_BUILD_XPC )
+  add_subdirectory(xpc)
+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 a9d1795..981c69d 100644
--- a/clangd/ClangdLSPServer.cpp
+++ b/clangd/ClangdLSPServer.cpp
@@ -1,27 +1,59 @@
 //===--- 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/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"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
+class IgnoreCompletionError : public llvm::ErrorInfo<CancelledError> {
+public:
+  void log(llvm::raw_ostream &OS) const override {
+    OS << "ignored auto-triggered completion, preceding char did not match";
+  }
+  std::error_code convertToErrorCode() const override {
+    return std::make_error_code(std::errc::operation_canceled);
+  }
+};
+
+/// 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) {
@@ -60,7 +92,7 @@
 public:
   MessageHandler(ClangdLSPServer &Server) : Server(Server) {}
 
-  bool onNotify(StringRef Method, json::Value Params) override {
+  bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override {
     log("<-- {0}", Method);
     if (Method == "exit")
       return false;
@@ -75,7 +107,8 @@
     return true;
   }
 
-  bool onCall(StringRef Method, json::Value Params, json::Value ID) override {
+  bool onCall(llvm::StringRef Method, llvm::json::Value Params,
+              llvm::json::Value ID) override {
     // Calls can be canceled by the client. Add cancellation context.
     WithContext WithCancel(cancelableRequestContext(ID));
     trace::Span Tracer(Method);
@@ -84,22 +117,23 @@
     log("<-- {0}({1})", Method, ID);
     if (!Server.Server && Method != "initialize") {
       elog("Call {0} before initialization.", Method);
-      Reply(make_error<LSPError>("server not initialized",
-                                 ErrorCode::ServerNotInitialized));
+      Reply(llvm::make_error<LSPError>("server not initialized",
+                                       ErrorCode::ServerNotInitialized));
     } else if (auto Handler = Calls.lookup(Method))
       Handler(std::move(Params), std::move(Reply));
     else
-      Reply(
-          make_error<LSPError>("method not found", ErrorCode::MethodNotFound));
+      Reply(llvm::make_error<LSPError>("method not found",
+                                       ErrorCode::MethodNotFound));
     return true;
   }
 
-  bool onReply(json::Value ID, Expected<json::Value> Result) override {
+  bool onReply(llvm::json::Value ID,
+               llvm::Expected<llvm::json::Value> Result) override {
     // We ignore replies, just log them.
     if (Result)
       log("<-- reply({0})", ID);
     else
-      log("<-- reply({0}) error: {1}", ID, toString(Result.takeError()));
+      log("<-- reply({0}) error: {1}", ID, llvm::toString(Result.takeError()));
     return true;
   }
 
@@ -107,15 +141,15 @@
   template <typename Param, typename Result>
   void bind(const char *Method,
             void (ClangdLSPServer::*Handler)(const Param &, Callback<Result>)) {
-    Calls[Method] = [Method, Handler, this](json::Value RawParams,
+    Calls[Method] = [Method, Handler, this](llvm::json::Value RawParams,
                                             ReplyOnce Reply) {
       Param P;
       if (fromJSON(RawParams, P)) {
         (Server.*Handler)(P, std::move(Reply));
       } else {
         elog("Failed to decode {0} request.", Method);
-        Reply(make_error<LSPError>("failed to decode request",
-                                   ErrorCode::InvalidRequest));
+        Reply(llvm::make_error<LSPError>("failed to decode request",
+                                         ErrorCode::InvalidRequest));
       }
     };
   }
@@ -124,7 +158,8 @@
   template <typename Param>
   void bind(const char *Method,
             void (ClangdLSPServer::*Handler)(const Param &)) {
-    Notifications[Method] = [Method, Handler, this](json::Value RawParams) {
+    Notifications[Method] = [Method, Handler,
+                             this](llvm::json::Value RawParams) {
       Param P;
       if (!fromJSON(RawParams, P)) {
         elog("Failed to decode {0} request.", Method);
@@ -145,14 +180,14 @@
   class ReplyOnce {
     std::atomic<bool> Replied = {false};
     std::chrono::steady_clock::time_point Start;
-    json::Value ID;
+    llvm::json::Value ID;
     std::string Method;
     ClangdLSPServer *Server; // Null when moved-from.
-    json::Object *TraceArgs;
+    llvm::json::Object *TraceArgs;
 
   public:
-    ReplyOnce(const json::Value &ID, StringRef Method, ClangdLSPServer *Server,
-              json::Object *TraceArgs)
+    ReplyOnce(const llvm::json::Value &ID, llvm::StringRef Method,
+              ClangdLSPServer *Server, llvm::json::Object *TraceArgs)
         : Start(std::chrono::steady_clock::now()), ID(ID), Method(Method),
           Server(Server), TraceArgs(TraceArgs) {
       assert(Server);
@@ -163,20 +198,20 @@
           Server(Other.Server), TraceArgs(Other.TraceArgs) {
       Other.Server = nullptr;
     }
-    ReplyOnce& operator=(ReplyOnce&&) = delete;
+    ReplyOnce &operator=(ReplyOnce &&) = delete;
     ReplyOnce(const ReplyOnce &) = delete;
-    ReplyOnce& operator=(const ReplyOnce&) = delete;
+    ReplyOnce &operator=(const ReplyOnce &) = delete;
 
     ~ReplyOnce() {
       if (Server && !Replied) {
         elog("No reply to message {0}({1})", Method, ID);
         assert(false && "must reply to all calls!");
-        (*this)(make_error<LSPError>("server failed to reply",
-                                     ErrorCode::InternalError));
+        (*this)(llvm::make_error<LSPError>("server failed to reply",
+                                           ErrorCode::InternalError));
       }
     }
 
-    void operator()(Expected<json::Value> Reply) {
+    void operator()(llvm::Expected<llvm::json::Value> Reply) {
       assert(Server && "moved-from!");
       if (Replied.exchange(true)) {
         elog("Replied twice to message {0}({1})", Method, ID);
@@ -191,34 +226,34 @@
         std::lock_guard<std::mutex> Lock(Server->TranspWriter);
         Server->Transp.reply(std::move(ID), std::move(Reply));
       } else {
-        Error Err = Reply.takeError();
+        llvm::Error Err = Reply.takeError();
         log("--> reply:{0}({1}) {2:ms}, error: {3}", Method, ID, Duration, Err);
         if (TraceArgs)
-          (*TraceArgs)["Error"] = to_string(Err);
+          (*TraceArgs)["Error"] = llvm::to_string(Err);
         std::lock_guard<std::mutex> Lock(Server->TranspWriter);
         Server->Transp.reply(std::move(ID), std::move(Err));
       }
     }
   };
 
-  StringMap<std::function<void(json::Value)>> Notifications;
-  StringMap<std::function<void(json::Value, ReplyOnce)>> Calls;
+  llvm::StringMap<std::function<void(llvm::json::Value)>> Notifications;
+  llvm::StringMap<std::function<void(llvm::json::Value, ReplyOnce)>> Calls;
 
   // Method calls may be cancelled by ID, so keep track of their state.
   // This needs a mutex: handlers may finish on a different thread, and that's
   // when we clean up entries in the map.
   mutable std::mutex RequestCancelersMutex;
-  StringMap<std::pair<Canceler, /*Cookie*/ unsigned>> RequestCancelers;
+  llvm::StringMap<std::pair<Canceler, /*Cookie*/ unsigned>> RequestCancelers;
   unsigned NextRequestCookie = 0; // To disambiguate reused IDs, see below.
-  void onCancel(const json::Value &Params) {
-    const json::Value *ID = nullptr;
+  void onCancel(const llvm::json::Value &Params) {
+    const llvm::json::Value *ID = nullptr;
     if (auto *O = Params.getAsObject())
       ID = O->get("id");
     if (!ID) {
       elog("Bad cancellation request: {0}", Params);
       return;
     }
-    auto StrID = to_string(*ID);
+    auto StrID = llvm::to_string(*ID);
     std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
     auto It = RequestCancelers.find(StrID);
     if (It != RequestCancelers.end())
@@ -228,9 +263,9 @@
   //  - allows cancellation using RequestCancelers[ID]
   //  - cleans up the entry in RequestCancelers when it's no longer needed
   // If a client reuses an ID, the last wins and the first cannot be canceled.
-  Context cancelableRequestContext(const json::Value &ID) {
+  Context cancelableRequestContext(const llvm::json::Value &ID) {
     auto Task = cancelableTask();
-    auto StrID = to_string(ID);        // JSON-serialize ID for map key.
+    auto StrID = llvm::to_string(ID);  // JSON-serialize ID for map key.
     auto Cookie = NextRequestCookie++; // No lock, only called on main thread.
     {
       std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
@@ -239,7 +274,7 @@
     // When the request ends, we can clean up the entry we just added.
     // The cookie lets us check that it hasn't been overwritten due to ID
     // reuse.
-    return Task.first.derive(make_scope_exit([this, StrID, Cookie] {
+    return Task.first.derive(llvm::make_scope_exit([this, StrID, Cookie] {
       std::lock_guard<std::mutex> Lock(RequestCancelersMutex);
       auto It = RequestCancelers.find(StrID);
       if (It != RequestCancelers.end() && It->second.second == Cookie)
@@ -251,7 +286,7 @@
 };
 
 // call(), notify(), and reply() wrap the Transport, adding logging and locking.
-void ClangdLSPServer::call(StringRef Method, json::Value Params) {
+void ClangdLSPServer::call(llvm::StringRef Method, llvm::json::Value Params) {
   auto ID = NextCallID++;
   log("--> {0}({1})", Method, ID);
   // We currently don't handle responses, so no need to store ID anywhere.
@@ -259,27 +294,28 @@
   Transp.call(Method, std::move(Params), ID);
 }
 
-void ClangdLSPServer::notify(StringRef Method, json::Value Params) {
+void ClangdLSPServer::notify(llvm::StringRef Method, llvm::json::Value Params) {
   log("--> {0}", Method);
   std::lock_guard<std::mutex> Lock(TranspWriter);
   Transp.notify(Method, std::move(Params));
 }
 
 void ClangdLSPServer::onInitialize(const InitializeParams &Params,
-                                   Callback<json::Value> Reply) {
+                                   Callback<llvm::json::Value> Reply) {
   if (Params.rootUri && *Params.rootUri)
     ClangdServerOpts.WorkspaceRoot = Params.rootUri->file();
   else if (Params.rootPath && !Params.rootPath->empty())
     ClangdServerOpts.WorkspaceRoot = *Params.rootPath;
   if (Server)
-    return Reply(make_error<LSPError>("server already initialized",
-                                      ErrorCode::InvalidRequest));
+    return Reply(llvm::make_error<LSPError>("server already initialized",
+                                            ErrorCode::InvalidRequest));
   if (const auto &Dir = Params.initializationOptions.compilationDatabasePath)
     CompileCommandsDir = Dir;
   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);
@@ -294,28 +330,31 @@
   SupportsCodeAction = Params.capabilities.CodeActionStructure;
   SupportsHierarchicalDocumentSymbol =
       Params.capabilities.HierarchicalDocumentSymbol;
-
-  Reply(json::Object{
+  SupportFileStatus = Params.initializationOptions.FileStatus;
+  Reply(llvm::json::Object{
       {{"capabilities",
-        json::Object{
+        llvm::json::Object{
             {"textDocumentSync", (int)TextDocumentSyncKind::Incremental},
             {"documentFormattingProvider", true},
             {"documentRangeFormattingProvider", true},
             {"documentOnTypeFormattingProvider",
-             json::Object{
+             llvm::json::Object{
                  {"firstTriggerCharacter", "}"},
                  {"moreTriggerCharacter", {}},
              }},
             {"codeActionProvider", true},
             {"completionProvider",
-             json::Object{
+             llvm::json::Object{
                  {"resolveProvider", false},
+                 // We do extra checks for '>' and ':' in completion to only
+                 // trigger on '->' and '::'.
                  {"triggerCharacters", {".", ">", ":"}},
              }},
             {"signatureHelpProvider",
-             json::Object{
+             llvm::json::Object{
                  {"triggerCharacters", {"(", ","}},
              }},
+            {"declarationProvider", true},
             {"definitionProvider", true},
             {"documentHighlightProvider", true},
             {"hoverProvider", true},
@@ -324,8 +363,10 @@
             {"workspaceSymbolProvider", true},
             {"referencesProvider", true},
             {"executeCommandProvider",
-             json::Object{
-                 {"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}},
+             llvm::json::Object{
+                 {"commands",
+                  {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND,
+                   ExecuteCommandParams::CLANGD_APPLY_TWEAK}},
              }},
         }}}});
 }
@@ -344,8 +385,8 @@
   if (Server->blockUntilIdleForTest(/*TimeoutSeconds=*/60))
     Reply(nullptr);
   else
-    Reply(createStringError(llvm::inconvertibleErrorCode(),
-                            "Not idle after a minute"));
+    Reply(llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                  "Not idle after a minute"));
 }
 
 void ClangdLSPServer::onDocumentDidOpen(
@@ -366,7 +407,7 @@
                                                   : WantDiagnostics::No;
 
   PathRef File = Params.textDocument.uri.file();
-  Expected<std::string> Contents =
+  llvm::Expected<std::string> Contents =
       DraftMgr.updateDraft(File, Params.contentChanges);
   if (!Contents) {
     // If this fails, we are most likely going to be not in sync anymore with
@@ -386,8 +427,8 @@
 }
 
 void ClangdLSPServer::onCommand(const ExecuteCommandParams &Params,
-                                Callback<json::Value> Reply) {
-  auto ApplyEdit = [&](WorkspaceEdit WE) {
+                                Callback<llvm::json::Value> Reply) {
+  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
@@ -407,12 +448,37 @@
 
     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
     // more commands are added, this will be here has a safe guard.
-    Reply(make_error<LSPError>(
-        formatv("Unsupported command \"{0}\".", Params.command).str(),
+    Reply(llvm::make_error<LSPError>(
+        llvm::formatv("Unsupported command \"{0}\".", Params.command).str(),
         ErrorCode::InvalidParams));
   }
 }
@@ -424,7 +490,7 @@
       Params.query, CCOpts.Limit,
       Bind(
           [this](decltype(Reply) Reply,
-                 Expected<std::vector<SymbolInformation>> Items) {
+                 llvm::Expected<std::vector<SymbolInformation>> Items) {
             if (!Items)
               return Reply(Items.takeError());
             for (auto &Sym : *Items)
@@ -438,17 +504,17 @@
 void ClangdLSPServer::onRename(const RenameParams &Params,
                                Callback<WorkspaceEdit> Reply) {
   Path File = Params.textDocument.uri.file();
-  Optional<std::string> Code = DraftMgr.getDraft(File);
+  llvm::Optional<std::string> Code = DraftMgr.getDraft(File);
   if (!Code)
-    return Reply(make_error<LSPError>("onRename called for non-added file",
-                                      ErrorCode::InvalidParams));
+    return Reply(llvm::make_error<LSPError>(
+        "onRename called for non-added file", ErrorCode::InvalidParams));
 
   Server->rename(
       File, Params.position, Params.newName,
       Bind(
-          [File, Code,
-           Params](decltype(Reply) Reply,
-                   Expected<std::vector<tooling::Replacement>> Replacements) {
+          [File, Code, Params](
+              decltype(Reply) Reply,
+              llvm::Expected<std::vector<tooling::Replacement>> Replacements) {
             if (!Replacements)
               return Reply(Replacements.takeError());
 
@@ -477,7 +543,7 @@
   auto File = Params.textDocument.uri.file();
   auto Code = DraftMgr.getDraft(File);
   if (!Code)
-    return Reply(make_error<LSPError>(
+    return Reply(llvm::make_error<LSPError>(
         "onDocumentOnTypeFormatting called for non-added file",
         ErrorCode::InvalidParams));
 
@@ -494,7 +560,7 @@
   auto File = Params.textDocument.uri.file();
   auto Code = DraftMgr.getDraft(File);
   if (!Code)
-    return Reply(make_error<LSPError>(
+    return Reply(llvm::make_error<LSPError>(
         "onDocumentRangeFormatting called for non-added file",
         ErrorCode::InvalidParams));
 
@@ -511,9 +577,9 @@
   auto File = Params.textDocument.uri.file();
   auto Code = DraftMgr.getDraft(File);
   if (!Code)
-    return Reply(
-        make_error<LSPError>("onDocumentFormatting called for non-added file",
-                             ErrorCode::InvalidParams));
+    return Reply(llvm::make_error<LSPError>(
+        "onDocumentFormatting called for non-added file",
+        ErrorCode::InvalidParams));
 
   auto ReplacementsOrError = Server->formatFile(*Code, File);
   if (ReplacementsOrError)
@@ -529,8 +595,8 @@
                        const URIForFile &FileURI) {
 
   std::vector<SymbolInformation> Results;
-  std::function<void(const DocumentSymbol &, StringRef)> Process =
-      [&](const DocumentSymbol &S, Optional<StringRef> ParentName) {
+  std::function<void(const DocumentSymbol &, llvm::StringRef)> Process =
+      [&](const DocumentSymbol &S, llvm::Optional<llvm::StringRef> ParentName) {
         SymbolInformation SI;
         SI.containerName = ParentName ? "" : *ParentName;
         SI.name = S.name;
@@ -550,13 +616,13 @@
 }
 
 void ClangdLSPServer::onDocumentSymbol(const DocumentSymbolParams &Params,
-                                       Callback<json::Value> Reply) {
+                                       Callback<llvm::json::Value> Reply) {
   URIForFile FileURI = Params.textDocument.uri;
   Server->documentSymbols(
       Params.textDocument.uri.file(),
       Bind(
           [this, FileURI](decltype(Reply) Reply,
-                          Expected<std::vector<DocumentSymbol>> Items) {
+                          llvm::Expected<std::vector<DocumentSymbol>> Items) {
             if (!Items)
               return Reply(Items.takeError());
             adjustSymbolKinds(*Items, SupportedSymbolKinds);
@@ -568,7 +634,7 @@
           std::move(Reply)));
 }
 
-static Optional<Command> asCommand(const CodeAction &Action) {
+static llvm::Optional<Command> asCommand(const CodeAction &Action) {
   Command Cmd;
   if (Action.command && Action.edit)
     return None; // Not representable. (We never emit these anyway).
@@ -587,37 +653,58 @@
 }
 
 void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
-                                   Callback<json::Value> Reply) {
-  auto Code = DraftMgr.getDraft(Params.textDocument.uri.file());
+                                   Callback<llvm::json::Value> Reply) {
+  URIForFile File = Params.textDocument.uri;
+  auto Code = DraftMgr.getDraft(File.file());
   if (!Code)
-    return Reply(make_error<LSPError>("onCodeAction called for non-added file",
-                                      ErrorCode::InvalidParams));
+    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(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(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 TextDocumentPositionParams &Params,
+void ClangdLSPServer::onCompletion(const CompletionParams &Params,
                                    Callback<CompletionList> Reply) {
+  if (!shouldRunCompletion(Params))
+    return Reply(llvm::make_error<IgnoreCompletionError>());
   Server->codeComplete(Params.textDocument.uri.file(), Params.position, CCOpts,
                        Bind(
                            [this](decltype(Reply) Reply,
-                                  Expected<CodeCompleteResult> List) {
+                                  llvm::Expected<CodeCompleteResult> List) {
                              if (!List)
                                return Reply(List.takeError());
                              CompletionList LSPList;
@@ -639,15 +726,70 @@
                         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,
                                            Callback<std::string> Reply) {
-  Optional<Path> Result = Server->switchSourceHeader(Params.uri.file());
+  llvm::Optional<Path> Result = Server->switchSourceHeader(Params.uri.file());
   Reply(Result ? URI::createFile(*Result).toString() : "");
 }
 
@@ -659,7 +801,7 @@
 }
 
 void ClangdLSPServer::onHover(const TextDocumentPositionParams &Params,
-                              Callback<Optional<Hover>> Reply) {
+                              Callback<llvm::Optional<Hover>> Reply) {
   Server->findHover(Params.textDocument.uri.file(), Params.position,
                     std::move(Reply));
 }
@@ -695,7 +837,7 @@
 void ClangdLSPServer::onReference(const ReferenceParams &Params,
                                   Callback<std::vector<Location>> Reply) {
   Server->findReferences(Params.textDocument.uri.file(), Params.position,
-                         std::move(Reply));
+                         CCOpts.Limit, std::move(Reply));
 }
 
 void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,
@@ -705,11 +847,13 @@
 }
 
 ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
+                                 const FileSystemProvider &FSProvider,
                                  const clangd::CodeCompleteOptions &CCOpts,
-                                 Optional<Path> CompileCommandsDir,
+                                 llvm::Optional<Path> CompileCommandsDir,
                                  bool UseDirBasedCDB,
                                  const ClangdServer::Options &Opts)
-    : Transp(Transp), MsgHandler(new MessageHandler(*this)), CCOpts(CCOpts),
+    : Transp(Transp), MsgHandler(new MessageHandler(*this)),
+      FSProvider(FSProvider), CCOpts(CCOpts),
       SupportedSymbolKinds(defaultSymbolKinds()),
       SupportedCompletionItemKinds(defaultCompletionItemKinds()),
       UseDirBasedCDB(UseDirBasedCDB),
@@ -726,6 +870,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);
@@ -758,7 +903,7 @@
   return CleanExit && ShutdownRequestReceived;
 }
 
-std::vector<Fix> ClangdLSPServer::getFixes(StringRef File,
+std::vector<Fix> ClangdLSPServer::getFixes(llvm::StringRef File,
                                            const clangd::Diagnostic &D) {
   std::lock_guard<std::mutex> Lock(FixItsMutex);
   auto DiagToFixItsIter = FixItsMap.find(File);
@@ -773,6 +918,41 @@
   return FixItsIter->second;
 }
 
+bool ClangdLSPServer::shouldRunCompletion(
+    const CompletionParams &Params) const {
+  llvm::StringRef Trigger = Params.context.triggerCharacter;
+  if (Params.context.triggerKind != CompletionTriggerKind::TriggerCharacter ||
+      (Trigger != ">" && Trigger != ":"))
+    return true;
+
+  auto Code = DraftMgr.getDraft(Params.textDocument.uri.file());
+  if (!Code)
+    return true; // completion code will log the error for untracked doc.
+
+  // A completion request is sent when the user types '>' or ':', but we only
+  // want to trigger on '->' and '::'. We check the preceeding character to make
+  // sure it matches what we expected.
+  // Running the lexer here would be more robust (e.g. we can detect comments
+  // and avoid triggering completion there), but we choose to err on the side
+  // of simplicity here.
+  auto Offset = positionToOffset(*Code, Params.position,
+                                 /*AllowColumnsBeyondLineLength=*/false);
+  if (!Offset) {
+    vlog("could not convert position '{0}' to offset for file '{1}'",
+         Params.position, Params.textDocument.uri.file());
+    return true;
+  }
+  if (*Offset < 2)
+    return false;
+
+  if (Trigger == ">")
+    return (*Code)[*Offset - 2] == '-'; // trigger only on '->'.
+  if (Trigger == ":")
+    return (*Code)[*Offset - 2] == ':'; // trigger only on '::'.
+  assert(false && "unhandled trigger character");
+  return true;
+}
+
 void ClangdLSPServer::onDiagnosticsReady(PathRef File,
                                          std::vector<Diag> Diagnostics) {
   auto URI = URIForFile::canonicalize(File, /*TUPath=*/File);
@@ -780,7 +960,7 @@
   DiagnosticToReplacementMap LocalFixIts; // Temporary storage
   for (auto &Diag : Diagnostics) {
     toLSPDiags(Diag, URI, DiagOpts,
-               [&](clangd::Diagnostic Diag, ArrayRef<Fix> Fixes) {
+               [&](clangd::Diagnostic Diag, llvm::ArrayRef<Fix> Fixes) {
                  auto &FixItsForDiagnostic = LocalFixIts[Diag];
                  llvm::copy(Fixes, std::back_inserter(FixItsForDiagnostic));
                  LSPDiagnostics.push_back(std::move(Diag));
@@ -796,12 +976,25 @@
 
   // Publish diagnostics.
   notify("textDocument/publishDiagnostics",
-         json::Object{
+         llvm::json::Object{
              {"uri", URI},
              {"diagnostics", std::move(LSPDiagnostics)},
          });
 }
 
+void ClangdLSPServer::onFileUpdated(PathRef File, const TUStatus &Status) {
+  if (!SupportFileStatus)
+    return;
+  // FIXME: we don't emit "BuildingFile" and `RunningAction`, as these
+  // two statuses are running faster in practice, which leads the UI constantly
+  // changing, and doesn't provide much value. We may want to emit status at a
+  // reasonable time interval (e.g. 0.5s).
+  if (Status.Action.S == TUAction::BuildingFile ||
+      Status.Action.S == TUAction::RunningAction)
+    return;
+  notify("textDocument/clangd.fileStatus", Status.render(File));
+}
+
 void ClangdLSPServer::reparseOpenedFiles() {
   for (const Path &FilePath : DraftMgr.getActiveFiles())
     Server->addDocument(FilePath, *DraftMgr.getDraft(FilePath),
diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h
index 8f8b951..cda46ad 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,7 +37,8 @@
   /// 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,
                   const ClangdServer::Options &Opts);
   ~ClangdLSPServer();
@@ -52,6 +52,7 @@
 private:
   // Implement DiagnosticsConsumer.
   void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;
+  void onFileUpdated(PathRef File, const TUStatus &Status) override;
 
   // LSP methods. Notifications have signature void(const Params&).
   // Calls have signature void(const Params&, Callback<Response>).
@@ -73,10 +74,11 @@
   void onDocumentSymbol(const DocumentSymbolParams &,
                         Callback<llvm::json::Value>);
   void onCodeAction(const CodeActionParams &, Callback<llvm::json::Value>);
-  void onCompletion(const TextDocumentPositionParams &,
-                    Callback<CompletionList>);
+  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>>);
@@ -97,6 +99,12 @@
 
   std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
 
+  /// Checks if completion request should be ignored. We need this due to the
+  /// limitation of the LSP. Per LSP, a client sends requests for all "trigger
+  /// character" we specify, but for '>' and ':' we need to check they actually
+  /// produce '->' and '::', respectively.
+  bool shouldRunCompletion(const CompletionParams &Params) const;
+
   /// Forces a reparse of all currently opened files.  As a result, this method
   /// may be very expensive.  This method is normally called when the
   /// compilation database is changed.
@@ -123,7 +131,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.
@@ -132,11 +140,12 @@
   SymbolKindBitset SupportedSymbolKinds;
   /// The supported completion item kinds of the client.
   CompletionItemKindBitset SupportedCompletionItemKinds;
-  // Whether the client supports CodeAction response objects.
+  /// Whether the client supports CodeAction response objects.
   bool SupportsCodeAction = false;
   /// From capabilities of textDocument/documentSymbol.
   bool SupportsHierarchicalDocumentSymbol = false;
-
+  /// Whether the client supports showing file status.
+  bool SupportFileStatus = false;
   // Store of the current versions of the open documents.
   DraftStore DraftMgr;
 
diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp
index da491ee..9dc3328 100644
--- a/clangd/ClangdServer.cpp
+++ b/clangd/ClangdServer.cpp
@@ -1,26 +1,28 @@
 //===--- 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 "SourceCode.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,26 +30,22 @@
 #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>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
-std::string getStandardResourceDir() {
-  static int Dummy; // Just an address in this process.
-  return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy);
-}
-
 class RefactoringResultCollector final
     : public tooling::RefactoringResultConsumer {
 public:
-  void handleError(Error Err) override {
+  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
@@ -63,7 +61,7 @@
     Result = std::move(SourceReplacements);
   }
 
-  Optional<Expected<tooling::AtomicChanges>> Result;
+  llvm::Optional<llvm::Expected<tooling::AtomicChanges>> Result;
 };
 
 // Update the FileIndex with new ASTs and plumb the diagnostics responses.
@@ -72,9 +70,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 {
@@ -109,11 +108,11 @@
                            DiagnosticsConsumer &DiagConsumer,
                            const Options &Opts)
     : CDB(CDB), FSProvider(FSProvider),
-      ResourceDir(Opts.ResourceDir ? *Opts.ResourceDir
-                                   : getStandardResourceDir()),
       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
@@ -138,7 +137,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());
@@ -147,21 +146,27 @@
     AddIndex(DynamicIdx.get());
 }
 
-void ClangdServer::addDocument(PathRef File, StringRef Contents,
+void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
                                WantDiagnostics WantDiags) {
+  ParseOptions Opts;
+  Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults();
+  if (ClangTidyOptProvider)
+    Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File);
+  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
   // 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);
+  ParseInputs Inputs;
+  Inputs.CompileCommand = getCompileCommand(File);
+  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);
-}
+void ClangdServer::removeDocument(PathRef File) { WorkScheduler.remove(File); }
 
 void ClangdServer::codeComplete(PathRef File, Position Pos,
                                 const clangd::CodeCompleteOptions &Opts,
@@ -177,13 +182,13 @@
 
   auto Task = [PCHs, Pos, FS, CodeCompleteOpts,
                this](Path File, Callback<CodeCompleteResult> CB,
-                     Expected<InputsAndPreamble> IP) {
+                     llvm::Expected<InputsAndPreamble> IP) {
     if (!IP)
       return CB(IP.takeError());
     if (isCancelled())
-      return CB(make_error<CancelledError>());
+      return CB(llvm::make_error<CancelledError>());
 
-    Optional<SpeculativeFuzzyFind> SpecFuzzyFind;
+    llvm::Optional<SpeculativeFuzzyFind> SpecFuzzyFind;
     if (CodeCompleteOpts.Index && CodeCompleteOpts.SpeculativeIndexRequest) {
       SpecFuzzyFind.emplace();
       {
@@ -224,7 +229,7 @@
   auto FS = FSProvider.getFileSystem();
   auto *Index = this->Index;
   auto Action = [Pos, FS, PCHs, Index](Path File, Callback<SignatureHelp> CB,
-                                       Expected<InputsAndPreamble> IP) {
+                                       llvm::Expected<InputsAndPreamble> IP) {
     if (!IP)
       return CB(IP.takeError());
 
@@ -241,43 +246,44 @@
                                 Bind(Action, File.str(), std::move(CB)));
 }
 
-Expected<tooling::Replacements>
-ClangdServer::formatRange(StringRef Code, PathRef File, Range Rng) {
-  Expected<size_t> Begin = positionToOffset(Code, Rng.start);
+llvm::Expected<tooling::Replacements>
+ClangdServer::formatRange(llvm::StringRef Code, PathRef File, Range Rng) {
+  llvm::Expected<size_t> Begin = positionToOffset(Code, Rng.start);
   if (!Begin)
     return Begin.takeError();
-  Expected<size_t> End = positionToOffset(Code, Rng.end);
+  llvm::Expected<size_t> End = positionToOffset(Code, Rng.end);
   if (!End)
     return End.takeError();
   return formatCode(Code, File, {tooling::Range(*Begin, *End - *Begin)});
 }
 
-Expected<tooling::Replacements> ClangdServer::formatFile(StringRef Code,
-                                                         PathRef File) {
+llvm::Expected<tooling::Replacements>
+ClangdServer::formatFile(llvm::StringRef Code, PathRef File) {
   // Format everything.
   return formatCode(Code, File, {tooling::Range(0, Code.size())});
 }
 
-Expected<tooling::Replacements>
-ClangdServer::formatOnType(StringRef Code, PathRef File, Position Pos) {
+llvm::Expected<tooling::Replacements>
+ClangdServer::formatOnType(llvm::StringRef Code, PathRef File, Position Pos) {
   // Look for the previous opening brace from the character position and
   // format starting from there.
-  Expected<size_t> CursorPos = positionToOffset(Code, Pos);
+  llvm::Expected<size_t> CursorPos = positionToOffset(Code, Pos);
   if (!CursorPos)
     return CursorPos.takeError();
-  size_t PreviousLBracePos = StringRef(Code).find_last_of('{', *CursorPos);
-  if (PreviousLBracePos == StringRef::npos)
+  size_t PreviousLBracePos =
+      llvm::StringRef(Code).find_last_of('{', *CursorPos);
+  if (PreviousLBracePos == llvm::StringRef::npos)
     PreviousLBracePos = *CursorPos;
   size_t Len = *CursorPos - PreviousLBracePos;
 
   return formatCode(Code, File, {tooling::Range(PreviousLBracePos, Len)});
 }
 
-void ClangdServer::rename(PathRef File, Position Pos, StringRef NewName,
+void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
                           Callback<std::vector<tooling::Replacement>> CB) {
   auto Action = [Pos](Path File, std::string NewName,
                       Callback<std::vector<tooling::Replacement>> CB,
-                      Expected<InputsAndAST> InpAST) {
+                      llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
     auto &AST = InpAST->AST;
@@ -324,16 +330,75 @@
       "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,
-                           unique_function<void(std::string)> Callback) {
-  auto Action = [](decltype(Callback) Callback, Expected<InputsAndAST> InpAST) {
+                           llvm::unique_function<void(std::string)> Callback) {
+  auto Action = [](decltype(Callback) Callback,
+                   llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST) {
       llvm::consumeError(InpAST.takeError());
       return Callback("<no-ast>");
     }
     std::string Result;
 
-    raw_string_ostream ResultOS(Result);
+    llvm::raw_string_ostream ResultOS(Result);
     clangd::dumpAST(InpAST->AST, ResultOS);
     ResultOS.flush();
 
@@ -343,25 +408,25 @@
   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,
-                            Expected<InputsAndAST> InpAST) {
+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)));
 }
 
-Optional<Path> ClangdServer::switchSourceHeader(PathRef Path) {
+llvm::Optional<Path> ClangdServer::switchSourceHeader(PathRef Path) {
 
-  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
-                                  ".c++", ".m", ".mm"};
-  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
+  llvm::StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
+                                        ".c++", ".m", ".mm"};
+  llvm::StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
 
-  StringRef PathExt = sys::path::extension(Path);
+  llvm::StringRef PathExt = llvm::sys::path::extension(Path);
 
   // Lookup in a list of known extensions.
   auto SourceIter =
@@ -383,28 +448,28 @@
 
   // Array to lookup extensions for the switch. An opposite of where original
   // extension was found.
-  ArrayRef<StringRef> NewExts;
+  llvm::ArrayRef<llvm::StringRef> NewExts;
   if (IsSource)
     NewExts = HeaderExtensions;
   else
     NewExts = SourceExtensions;
 
   // Storage for the new path.
-  SmallString<128> NewPath = StringRef(Path);
+  llvm::SmallString<128> NewPath = llvm::StringRef(Path);
 
   // Instance of vfs::FileSystem, used for file existence checks.
   auto FS = FSProvider.getFileSystem();
 
   // Loop through switched extension candidates.
-  for (StringRef NewExt : NewExts) {
-    sys::path::replace_extension(NewPath, NewExt);
+  for (llvm::StringRef NewExt : NewExts) {
+    llvm::sys::path::replace_extension(NewPath, NewExt);
     if (FS->exists(NewPath))
       return NewPath.str().str(); // First str() to convert from SmallString to
                                   // StringRef, second to convert from StringRef
                                   // to std::string
 
     // Also check NewExt in upper-case, just in case.
-    sys::path::replace_extension(NewPath, NewExt.upper());
+    llvm::sys::path::replace_extension(NewPath, NewExt.upper());
     if (FS->exists(NewPath))
       return NewPath.str().str();
   }
@@ -412,9 +477,9 @@
   return None;
 }
 
-Expected<tooling::Replacements>
-ClangdServer::formatCode(StringRef Code, PathRef File,
-                         ArrayRef<tooling::Range> Ranges) {
+llvm::Expected<tooling::Replacements>
+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,
@@ -437,7 +502,7 @@
 void ClangdServer::findDocumentHighlights(
     PathRef File, Position Pos, Callback<std::vector<DocumentHighlight>> CB) {
   auto Action = [Pos](Callback<std::vector<DocumentHighlight>> CB,
-                      Expected<InputsAndAST> InpAST) {
+                      llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
     CB(clangd::findDocumentHighlights(InpAST->AST, Pos));
@@ -447,9 +512,9 @@
 }
 
 void ClangdServer::findHover(PathRef File, Position Pos,
-                             Callback<Optional<Hover>> CB) {
-  auto Action = [Pos](Callback<Optional<Hover>> CB,
-                      Expected<InputsAndAST> InpAST) {
+                             Callback<llvm::Optional<Hover>> CB) {
+  auto Action = [Pos](Callback<llvm::Optional<Hover>> CB,
+                      llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
     CB(clangd::getHover(InpAST->AST, Pos));
@@ -460,13 +525,9 @@
 
 tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) {
   trace::Span Span("GetCompileCommand");
-  Optional<tooling::CompileCommand> C = CDB.getCompileCommand(File);
+  llvm::Optional<tooling::CompileCommand> C = CDB.getCompileCommand(File);
   if (!C) // FIXME: Suppress diagnostics? Let the user know?
     C = CDB.getFallbackCommand(File);
-
-  // 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);
 }
 
@@ -476,7 +537,8 @@
 }
 
 void ClangdServer::workspaceSymbols(
-    StringRef Query, int Limit, Callback<std::vector<SymbolInformation>> CB) {
+    llvm::StringRef Query, int Limit,
+    Callback<std::vector<SymbolInformation>> CB) {
   std::string QueryCopy = Query;
   WorkScheduler.run(
       "getWorkspaceSymbols",
@@ -488,7 +550,7 @@
           std::move(CB)));
 }
 
-void ClangdServer::documentSymbols(StringRef File,
+void ClangdServer::documentSymbols(llvm::StringRef File,
                                    Callback<std::vector<DocumentSymbol>> CB) {
   auto Action = [](Callback<std::vector<DocumentSymbol>> CB,
                    llvm::Expected<InputsAndAST> InpAST) {
@@ -500,13 +562,13 @@
                            Bind(Action, std::move(CB)));
 }
 
-void ClangdServer::findReferences(PathRef File, Position Pos,
+void ClangdServer::findReferences(PathRef File, Position Pos, uint32_t Limit,
                                   Callback<std::vector<Location>> CB) {
-  auto Action = [Pos, this](Callback<std::vector<Location>> CB,
-                            Expected<InputsAndAST> InpAST) {
+  auto Action = [Pos, Limit, this](Callback<std::vector<Location>> CB,
+                                   llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
-    CB(clangd::findReferences(InpAST->AST, Pos, Index));
+    CB(clangd::findReferences(InpAST->AST, Pos, Limit, Index));
   };
 
   WorkScheduler.runWithAST("References", File, Bind(Action, std::move(CB)));
@@ -515,7 +577,7 @@
 void ClangdServer::symbolInfo(PathRef File, Position Pos,
                               Callback<std::vector<SymbolDetails>> CB) {
   auto Action = [Pos](Callback<std::vector<SymbolDetails>> CB,
-                      Expected<InputsAndAST> InpAST) {
+                      llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
     CB(clangd::getSymbolInfo(InpAST->AST, Pos));
@@ -530,7 +592,7 @@
 }
 
 LLVM_NODISCARD bool
-ClangdServer::blockUntilIdleForTest(Optional<double> TimeoutSeconds) {
+ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
   return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds)) &&
          (!BackgroundIdx ||
           BackgroundIdx->blockUntilIdleForTest(TimeoutSeconds));
diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h
index 4ce1506..f329418 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"
@@ -93,6 +96,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 +117,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 +168,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.
@@ -181,7 +193,7 @@
                        Callback<std::vector<DocumentSymbol>> CB);
 
   /// Retrieve locations for symbol references.
-  void findReferences(PathRef File, Position Pos,
+  void findReferences(PathRef File, Position Pos, uint32_t Limit,
                       Callback<std::vector<Location>> CB);
 
   /// Run formatting for \p Rng inside \p File with content \p Code.
@@ -202,6 +214,18 @@
   void rename(PathRef File, Position Pos, llvm::StringRef NewName,
               Callback<std::vector<tooling::Replacement>> 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
   /// \p File. \p File must be in the list of added documents.
@@ -258,6 +282,13 @@
   // 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;
diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp
index 013d180..b07abd9 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,9 +11,13 @@
 #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/Frontend/CompilerInstance.h"
@@ -31,12 +34,13 @@
 #include "clang/Serialization/ASTWriter.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>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -45,7 +49,7 @@
                              const tooling::CompileCommand &RHS) {
   // We don't check for Output, it should not matter to clangd.
   return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
-         makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine);
+         llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine);
 }
 
 template <class T> std::size_t getUsedBytes(const std::vector<T> &Vec) {
@@ -80,8 +84,8 @@
   std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
 
 protected:
-  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
-                                                 StringRef InFile) override {
+  std::unique_ptr<ASTConsumer>
+  CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
     return llvm::make_unique<DeclTrackingASTConsumer>(/*ref*/ TopLevelDecls);
   }
 
@@ -92,15 +96,19 @@
 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); }
 
+  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 {
@@ -112,10 +120,17 @@
     return collectIncludeStructureCallback(*SourceMgr, &Includes);
   }
 
+  CommentHandler *getCommentHandler() override {
+    IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes);
+    return IWYUHandler.get();
+  }
+
 private:
   PathRef File;
   PreambleParsedCallback ParsedCallback;
   IncludeStructure Includes;
+  CanonicalIncludes CanonIncludes;
+  std::unique_ptr<CommentHandler> IWYUHandler = nullptr;
   SourceManager *SourceMgr = nullptr;
 };
 
@@ -134,6 +149,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())));
@@ -179,12 +197,12 @@
       if (Inc.Resolved != "")
         File = SM.getFileManager().getFile(Inc.Resolved);
 
-      StringRef WrittenFilename =
-          StringRef(Inc.Written).drop_front().drop_back();
-      bool Angled = StringRef(Inc.Written).startswith("<");
+      llvm::StringRef WrittenFilename =
+          llvm::StringRef(Inc.Written).drop_front().drop_back();
+      bool Angled = llvm::StringRef(Inc.Written).startswith("<");
 
       // Re-lex the #include directive to find its interesting parts.
-      StringRef Src = SM.getBufferData(SM.getMainFileID());
+      llvm::StringRef Src = SM.getBufferData(SM.getMainFileID());
       Lexer RawLexer(SM.getLocForStartOfFile(SM.getMainFileID()), LangOpts,
                      Src.begin(), Src.begin() + Inc.HashOffset, Src.end());
       Token HashTok, IncludeTok, FilenameTok;
@@ -205,7 +223,7 @@
       if (File)
         Delegate->FileSkipped(*File, FilenameTok, Inc.FileKind);
       else {
-        SmallString<1> UnusedRecovery;
+        llvm::SmallString<1> UnusedRecovery;
         Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
       }
     }
@@ -220,16 +238,17 @@
 
 } // namespace
 
-void dumpAST(ParsedAST &AST, raw_ostream &OS) {
+void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
   AST.getASTContext().getTranslationUnitDecl()->dump(OS, true);
 }
 
-Optional<ParsedAST>
+llvm::Optional<ParsedAST>
 ParsedAST::build(std::unique_ptr<CompilerInvocation> CI,
                  std::shared_ptr<const PreambleData> Preamble,
-                 std::unique_ptr<MemoryBuffer> Buffer,
+                 std::unique_ptr<llvm::MemoryBuffer> Buffer,
                  std::shared_ptr<PCHContainerOperations> PCHs,
-                 IntrusiveRefCntPtr<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.
@@ -238,9 +257,11 @@
       Preamble ? &Preamble->Preamble : nullptr;
 
   StoreDiags ASTDiags;
+  std::string Content = Buffer->getBuffer();
+
   auto Clang =
       prepareCompilerInstance(std::move(CI), PreamblePCH, std::move(Buffer),
-                              std::move(PCHs), std::move(VFS), ASTDiags);
+                              std::move(PCHs), VFS, ASTDiags);
   if (!Clang)
     return None;
 
@@ -263,18 +284,13 @@
   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());
@@ -287,6 +303,28 @@
     }
   }
 
+  // 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{};
@@ -299,6 +337,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());
 
@@ -328,7 +377,7 @@
     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;
@@ -362,7 +411,7 @@
   return Clang->getPreprocessor();
 }
 
-ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
+llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
   return LocalTopLevelDecls;
 }
 
@@ -404,53 +453,32 @@
   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::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)), 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;
-  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,
@@ -460,7 +488,7 @@
               PreambleParsedCallback PreambleCallback) {
   // Note that we don't need to copy the input contents, preamble can live
   // without those.
-  auto ContentsBuffer = MemoryBuffer::getMemBuffer(Inputs.Contents);
+  auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Inputs.Contents);
   auto Bounds =
       ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
 
@@ -468,7 +496,7 @@
       compileCommandsAreEqual(Inputs.CompileCommand, OldCompileCommand) &&
       OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
                                      Inputs.FS.get())) {
-    vlog("Reusing preamble for file {0}", Twine(FileName));
+    vlog("Reusing preamble for file {0}", llvm::Twine(FileName));
     return OldPreamble;
   }
   vlog("Preamble for file {0} cannot be reused. Attempting to rebuild it.",
@@ -477,7 +505,7 @@
   trace::Span Tracer("BuildPreamble");
   SPAN_ATTACH(Tracer, "File", FileName);
   StoreDiags PreambleDiagnostics;
-  IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
+  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
       CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(),
                                           &PreambleDiagnostics, false);
 
@@ -496,7 +524,7 @@
     // dirs.
   }
 
-  SmallString<32> AbsFileName(FileName);
+  llvm::SmallString<32> AbsFileName(FileName);
   Inputs.FS->makeAbsolute(AbsFileName);
   auto StatCache = llvm::make_unique<PreambleFileStatusCache>(AbsFileName);
   auto BuiltPreamble = PrecompiledPreamble::Build(
@@ -513,18 +541,19 @@
          FileName);
     return std::make_shared<PreambleData>(
         std::move(*BuiltPreamble), PreambleDiagnostics.take(),
-        SerializedDeclsCollector.takeIncludes(), std::move(StatCache));
+        SerializedDeclsCollector.takeIncludes(), std::move(StatCache),
+        SerializedDeclsCollector.takeCanonicalIncludes());
   } else {
     elog("Could not build a preamble for file {0}", FileName);
     return nullptr;
   }
 }
 
-Optional<ParsedAST> buildAST(PathRef FileName,
-                             std::unique_ptr<CompilerInvocation> Invocation,
-                             const ParseInputs &Inputs,
-                             std::shared_ptr<const PreambleData> Preamble,
-                             std::shared_ptr<PCHContainerOperations> PCHs) {
+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) {
   trace::Span Tracer("BuildAST");
   SPAN_ATTACH(Tracer, "File", FileName);
 
@@ -537,9 +566,10 @@
     // dirs.
   }
 
-  return ParsedAST::build(
-      llvm::make_unique<CompilerInvocation>(*Invocation), Preamble,
-      MemoryBuffer::getMemBufferCopy(Inputs.Contents), PCHs, std::move(VFS));
+  return ParsedAST::build(llvm::make_unique<CompilerInvocation>(*Invocation),
+                          Preamble,
+                          llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents),
+                          PCHs, 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..d5bdd1a 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,7 +33,7 @@
 
 namespace vfs {
 class FileSystem;
-}
+} // namespace vfs
 } // namespace llvm
 
 namespace clang {
@@ -39,7 +41,7 @@
 
 namespace tooling {
 struct CompileCommand;
-}
+} // namespace tooling
 
 namespace clangd {
 
@@ -47,7 +49,8 @@
 struct PreambleData {
   PreambleData(PrecompiledPreamble Preamble, std::vector<Diag> Diags,
                IncludeStructure Includes,
-               std::unique_ptr<PreambleFileStatusCache> StatCache);
+               std::unique_ptr<PreambleFileStatusCache> StatCache,
+               CanonicalIncludes CanonIncludes);
 
   tooling::CompileCommand CompileCommand;
   PrecompiledPreamble Preamble;
@@ -58,13 +61,7 @@
   // 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.
@@ -77,7 +74,8 @@
         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 +103,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 +129,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.
diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp
index 74b90bc..b059216 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -59,7 +58,6 @@
 // We log detailed candidate here if you run with -debug-only=codecomplete.
 #define DEBUG_TYPE "CodeComplete"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -179,40 +177,19 @@
   return Result;
 }
 
-/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal
-/// include.
-static Expected<HeaderFile> toHeaderFile(StringRef Header, 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};
-}
-
 /// A code completion result, in clang-native form.
 /// It may be promoted to a CompletionItem if it's among the top-ranked results.
 struct CompletionCandidate {
-  StringRef Name; // Used for filtering and sorting.
+  llvm::StringRef Name; // Used for filtering and sorting.
   // We may have a result from Sema, from the index, or both.
   const CodeCompletionResult *SemaResult = nullptr;
   const Symbol *IndexResult = nullptr;
-  SmallVector<StringRef, 1> RankedIncludeHeaders;
+  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 {
-    SmallString<256> Scratch;
+    llvm::SmallString<256> Scratch;
     if (IndexResult) {
       switch (IndexResult->SymInfo.Kind) {
       case index::SymbolKind::ClassMethod:
@@ -226,7 +203,7 @@
       case index::SymbolKind::Function:
         // We can't group overloads together that need different #includes.
         // This could break #include insertion.
-        return hash_combine(
+        return llvm::hash_combine(
             (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
             headerToInsertIfAllowed().getValueOr(""));
       default:
@@ -239,14 +216,15 @@
     if (!D || !D->isFunctionOrFunctionTemplate())
       return 0;
     {
-      raw_svector_ostream OS(Scratch);
+      llvm::raw_svector_ostream OS(Scratch);
       D->printQualifiedName(OS);
     }
-    return hash_combine(Scratch, headerToInsertIfAllowed().getValueOr(""));
+    return llvm::hash_combine(Scratch,
+                              headerToInsertIfAllowed().getValueOr(""));
   }
 
   // The best header to include if include insertion is allowed.
-  Optional<StringRef> headerToInsertIfAllowed() const {
+  llvm::Optional<llvm::StringRef> headerToInsertIfAllowed() const {
     if (RankedIncludeHeaders.empty())
       return None;
     if (SemaResult && SemaResult->Declaration) {
@@ -260,7 +238,7 @@
     return RankedIncludeHeaders[0];
   }
 
-  using Bundle = SmallVector<CompletionCandidate, 4>;
+  using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
 };
 using ScoredBundle =
     std::pair<CompletionCandidate::Bundle, CodeCompletion::Scores>;
@@ -283,8 +261,9 @@
 struct CodeCompletionBuilder {
   CodeCompletionBuilder(ASTContext &ASTCtx, const CompletionCandidate &C,
                         CodeCompletionString *SemaCCS,
-                        ArrayRef<std::string> QueryScopes,
-                        const IncludeInserter &Includes, StringRef FileName,
+                        llvm::ArrayRef<std::string> QueryScopes,
+                        const IncludeInserter &Includes,
+                        llvm::StringRef FileName,
                         CodeCompletionContext::Kind ContextKind,
                         const CodeCompleteOptions &Opts)
       : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments),
@@ -292,7 +271,7 @@
     add(C, SemaCCS);
     if (C.SemaResult) {
       Completion.Origin |= SymbolOrigin::AST;
-      Completion.Name = StringRef(SemaCCS->getTypedText());
+      Completion.Name = llvm::StringRef(SemaCCS->getTypedText());
       if (Completion.Scope.empty()) {
         if ((C.SemaResult->Kind == CodeCompletionResult::RK_Declaration) ||
             (C.SemaResult->Kind == CodeCompletionResult::RK_Pattern))
@@ -330,9 +309,9 @@
       // If the completion was visible to Sema, no qualifier is needed. This
       // avoids unneeded qualifiers in cases like with `using ns::X`.
       if (Completion.RequiredQualifier.empty() && !C.SemaResult) {
-        StringRef ShortestQualifier = C.IndexResult->Scope;
-        for (StringRef Scope : QueryScopes) {
-          StringRef Qualifier = C.IndexResult->Scope;
+        llvm::StringRef ShortestQualifier = C.IndexResult->Scope;
+        for (llvm::StringRef Scope : QueryScopes) {
+          llvm::StringRef Qualifier = C.IndexResult->Scope;
           if (Qualifier.consume_front(Scope) &&
               Qualifier.size() < ShortestQualifier.size())
             ShortestQualifier = Qualifier;
@@ -343,8 +322,8 @@
     }
 
     // Turn absolute path into a literal string that can be #included.
-    auto Inserted =
-        [&](StringRef Header) -> Expected<std::pair<std::string, bool>> {
+    auto Inserted = [&](llvm::StringRef Header)
+        -> llvm::Expected<std::pair<std::string, bool>> {
       auto ResolvedDeclaring =
           toHeaderFile(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
       if (!ResolvedDeclaring)
@@ -462,7 +441,7 @@
       //   foo<${1:class}>(${2:int p1}).
       //   We transform this pattern to '<$1>()$0' or '<$0>()'.
 
-      bool EmptyArgs = StringRef(*Snippet).endswith("()");
+      bool EmptyArgs = llvm::StringRef(*Snippet).endswith("()");
       if (Snippet->front() == '<')
         return EmptyArgs ? "<$1>()$0" : "<$1>($0)";
       if (Snippet->front() == '(')
@@ -476,7 +455,7 @@
 
       // Classes and template using aliases can only have template arguments,
       // e.g. Foo<${1:class}>.
-      if (StringRef(*Snippet).endswith("<>"))
+      if (llvm::StringRef(*Snippet).endswith("<>"))
         return "<>"; // can happen with defaulted template arguments.
       return "<$0>";
     }
@@ -492,14 +471,14 @@
 
   ASTContext &ASTCtx;
   CodeCompletion Completion;
-  SmallVector<BundledEntry, 1> Bundled;
+  llvm::SmallVector<BundledEntry, 1> Bundled;
   bool ExtractDocumentation;
   bool EnableFunctionArgSnippets;
 };
 
 // Determine the symbol ID for a Sema code completion result, if possible.
-Optional<SymbolID> getSymbolID(const CodeCompletionResult &R,
-                               const SourceManager &SM) {
+llvm::Optional<SymbolID> getSymbolID(const CodeCompletionResult &R,
+                                     const SourceManager &SM) {
   switch (R.Kind) {
   case CodeCompletionResult::RK_Declaration:
   case CodeCompletionResult::RK_Pattern: {
@@ -539,13 +518,13 @@
   std::vector<std::string> AccessibleScopes;
   // The full scope qualifier as typed by the user (without the leading "::").
   // Set if the qualifier is not fully resolved by Sema.
-  Optional<std::string> UnresolvedQualifier;
+  llvm::Optional<std::string> UnresolvedQualifier;
 
   // Construct scopes being queried in indexes. The results are deduplicated.
   // This method format the scopes to match the index request representation.
   std::vector<std::string> scopesForIndexQuery() {
     std::set<std::string> Results;
-    for (StringRef AS : AccessibleScopes)
+    for (llvm::StringRef AS : AccessibleScopes)
       Results.insert(
           ((UnresolvedQualifier ? *UnresolvedQualifier : "") + AS).str());
     return {Results.begin(), Results.end()};
@@ -688,7 +667,7 @@
 // within the callback.
 struct CompletionRecorder : public CodeCompleteConsumer {
   CompletionRecorder(const CodeCompleteOptions &Opts,
-                     unique_function<void()> ResultsCallback)
+                     llvm::unique_function<void()> ResultsCallback)
       : CodeCompleteConsumer(Opts.getClangCompleteOpts(),
                              /*OutputIsBinary=*/false),
         CCContext(CodeCompletionContext::CCC_Other), Opts(Opts),
@@ -766,7 +745,7 @@
 
   // Returns the filtering/sorting name for Result, which must be from Results.
   // Returned string is owned by this recorder (or the AST).
-  StringRef getName(const CodeCompletionResult &Result) {
+  llvm::StringRef getName(const CodeCompletionResult &Result) {
     switch (Result.Kind) {
     case CodeCompletionResult::RK_Declaration:
       if (auto *ID = Result.Declaration->getIdentifier())
@@ -796,13 +775,13 @@
   CodeCompleteOptions Opts;
   std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
   CodeCompletionTUInfo CCTUInfo;
-  unique_function<void()> ResultsCallback;
+  llvm::unique_function<void()> ResultsCallback;
 };
 
 struct ScoredSignature {
   // When set, requires documentation to be requested from the index with this
   // ID.
-  Optional<SymbolID> IDForDoc;
+  llvm::Optional<SymbolID> IDForDoc;
   SignatureInformation Signature;
   SignatureQualitySignals Quality;
 };
@@ -862,7 +841,7 @@
 
     // Sema does not load the docs from the preamble, so we need to fetch extra
     // docs from the index instead.
-    DenseMap<SymbolID, std::string> FetchedDocs;
+    llvm::DenseMap<SymbolID, std::string> FetchedDocs;
     if (Index) {
       LookupRequest IndexRequest;
       for (const auto &S : ScoredSignatures) {
@@ -879,38 +858,37 @@
           IndexRequest.IDs.size(), FetchedDocs.size());
     }
 
-    llvm::sort(
-        ScoredSignatures,
-        [](const ScoredSignature &L, const ScoredSignature &R) {
-          // Ordering follows:
-          // - Less number of parameters is better.
-          // - Function is better than FunctionType which is better than
-          // Function Template.
-          // - High score is better.
-          // - Shorter signature is better.
-          // - Alphebatically smaller is better.
-          if (L.Quality.NumberOfParameters != R.Quality.NumberOfParameters)
-            return L.Quality.NumberOfParameters < R.Quality.NumberOfParameters;
-          if (L.Quality.NumberOfOptionalParameters !=
-              R.Quality.NumberOfOptionalParameters)
-            return L.Quality.NumberOfOptionalParameters <
-                   R.Quality.NumberOfOptionalParameters;
-          if (L.Quality.Kind != R.Quality.Kind) {
-            using OC = CodeCompleteConsumer::OverloadCandidate;
-            switch (L.Quality.Kind) {
-            case OC::CK_Function:
-              return true;
-            case OC::CK_FunctionType:
-              return R.Quality.Kind != OC::CK_Function;
-            case OC::CK_FunctionTemplate:
-              return false;
-            }
-            llvm_unreachable("Unknown overload candidate type.");
-          }
-          if (L.Signature.label.size() != R.Signature.label.size())
-            return L.Signature.label.size() < R.Signature.label.size();
-          return L.Signature.label < R.Signature.label;
-        });
+    llvm::sort(ScoredSignatures, [](const ScoredSignature &L,
+                                    const ScoredSignature &R) {
+      // Ordering follows:
+      // - Less number of parameters is better.
+      // - Function is better than FunctionType which is better than
+      // Function Template.
+      // - High score is better.
+      // - Shorter signature is better.
+      // - Alphebatically smaller is better.
+      if (L.Quality.NumberOfParameters != R.Quality.NumberOfParameters)
+        return L.Quality.NumberOfParameters < R.Quality.NumberOfParameters;
+      if (L.Quality.NumberOfOptionalParameters !=
+          R.Quality.NumberOfOptionalParameters)
+        return L.Quality.NumberOfOptionalParameters <
+               R.Quality.NumberOfOptionalParameters;
+      if (L.Quality.Kind != R.Quality.Kind) {
+        using OC = CodeCompleteConsumer::OverloadCandidate;
+        switch (L.Quality.Kind) {
+        case OC::CK_Function:
+          return true;
+        case OC::CK_FunctionType:
+          return R.Quality.Kind != OC::CK_Function;
+        case OC::CK_FunctionTemplate:
+          return false;
+        }
+        llvm_unreachable("Unknown overload candidate type.");
+      }
+      if (L.Signature.label.size() != R.Signature.label.size())
+        return L.Signature.label.size() < R.Signature.label.size();
+      return L.Signature.label < R.Signature.label;
+    });
 
     for (auto &SS : ScoredSignatures) {
       auto IndexDocIt =
@@ -931,7 +909,7 @@
   // CompletionString.h.
   ScoredSignature processOverloadCandidate(const OverloadCandidate &Candidate,
                                            const CodeCompletionString &CCS,
-                                           StringRef DocComment) const {
+                                           llvm::StringRef DocComment) const {
     SignatureInformation Signature;
     SignatureQualitySignals Signal;
     const char *ReturnType = nullptr;
@@ -1003,9 +981,9 @@
   PathRef FileName;
   const tooling::CompileCommand &Command;
   const PreambleData *Preamble;
-  StringRef Contents;
+  llvm::StringRef Contents;
   Position Pos;
-  IntrusiveRefCntPtr<vfs::FileSystem> VFS;
+  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
   std::shared_ptr<PCHContainerOperations> PCHs;
 };
 
@@ -1016,33 +994,21 @@
                       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.
-  }
-
-  IntrusiveRefCntPtr<vfs::FileSystem> VFS = Input.VFS;
+  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.
@@ -1057,8 +1023,8 @@
            FrontendOpts.CodeCompletionAt.Column) =
       offsetToClangLineColumn(Input.Contents, *Offset);
 
-  std::unique_ptr<MemoryBuffer> ContentsBuffer =
-      MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
+  std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
+      llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName);
   // The diagnostic options must be set before creating a CompilerInstance.
   CI->getDiagnosticOpts().IgnoreWarnings = true;
   // We reuse the preamble whether it's valid or not. This is a
@@ -1072,6 +1038,7 @@
       *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
@@ -1140,8 +1107,10 @@
 // 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.
-Optional<FuzzyFindRequest> speculativeFuzzyFindRequestForCompletion(
-    FuzzyFindRequest CachedReq, PathRef File, StringRef Content, Position Pos) {
+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 "
@@ -1153,46 +1122,6 @@
   return CachedReq;
 }
 
-} // namespace
-
-clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
-  clang::CodeCompleteOptions Result;
-  Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
-  Result.IncludeMacros = IncludeMacros;
-  Result.IncludeGlobals = true;
-  // We choose to include full comments and not do doxygen parsing in
-  // completion.
-  // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
-  // formatting of the comments.
-  Result.IncludeBriefComments = false;
-
-  // When an is used, Sema is responsible for completing the main file,
-  // the index can provide results from the preamble.
-  // Tell Sema not to deserialize the preamble to look for results.
-  Result.LoadExternal = !Index;
-  Result.IncludeFixIts = IncludeFixIts;
-
-  return Result;
-}
-
-// 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.
-SmallVector<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;
-  });
-  SmallVector<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:
@@ -1224,30 +1153,30 @@
 //   - TopN determines the results with the best score.
 class CodeCompleteFlow {
   PathRef FileName;
-  IncludeStructure Includes; // Complete once the compiler runs.
+  IncludeStructure Includes;           // Complete once the compiler runs.
   SpeculativeFuzzyFind *SpecFuzzyFind; // Can be nullptr.
   const CodeCompleteOptions &Opts;
 
   // 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?
-  Optional<FuzzyMatcher> Filter;        // Initialized once Sema runs.
+  bool Incomplete = false;       // Would more be available with a higher limit?
+  llvm::Optional<FuzzyMatcher> Filter;  // Initialized once Sema runs.
   std::vector<std::string> QueryScopes; // Initialized once Sema runs.
   // Initialized once QueryScopes is initialized, if there are scopes.
-  Optional<ScopeDistance> ScopeProximity;
+  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;
   // Include-insertion and proximity scoring rely on the include structure.
   // This is available after Sema has run.
-  Optional<IncludeInserter> Inserter;  // Available during runWithSema.
-  Optional<URIDistance> FileProximity; // Initialized once Sema runs.
+  llvm::Optional<IncludeInserter> Inserter;  // Available during runWithSema.
+  llvm::Optional<URIDistance> FileProximity; // Initialized once Sema runs.
   /// Speculative request based on the cached request and the filter text before
   /// the cursor.
   /// Initialized right before sema run. This is only set if `SpecFuzzyFind` is
   /// set and contains a cached request.
-  Optional<FuzzyFindRequest> SpecReq;
+  llvm::Optional<FuzzyFindRequest> SpecReq;
 
 public:
   // A CodeCompleteFlow object is only useful for calling run() exactly once.
@@ -1273,19 +1202,12 @@
     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();
-      }
+      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());
       for (const auto &Inc : Includes.MainFileIncludes)
@@ -1297,7 +1219,7 @@
       // The per-result proximity scoring is (amortized) very cheap.
       FileDistanceOptions ProxOpts{}; // Use defaults.
       const auto &SM = Recorder->CCSema->getSourceManager();
-      StringMap<SourceParams> ProxSources;
+      llvm::StringMap<SourceParams> ProxSources;
       for (auto &Entry : Includes.includeDepth(
                SM.getFileEntryForID(SM.getMainFileID())->getName())) {
         auto &Source = ProxSources[Entry.getKey()];
@@ -1317,7 +1239,7 @@
       log("Code complete: sema context {0}, query scopes [{1}] (AnyScope={2}), "
           "expected type {3}",
           getCompletionKindString(Recorder->CCContext.getKind()),
-          join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
+          llvm::join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
           PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
                         : "<none>");
     });
@@ -1411,6 +1333,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)
@@ -1442,7 +1366,7 @@
                const SymbolSlab &IndexResults) {
     trace::Span Tracer("Merge and score results");
     std::vector<CompletionCandidate::Bundle> Bundles;
-    DenseMap<size_t, size_t> BundleLookup;
+    llvm::DenseMap<size_t, size_t> BundleLookup;
     auto AddToBundles = [&](const CodeCompletionResult *SemaResult,
                             const Symbol *IndexResult) {
       CompletionCandidate C;
@@ -1461,7 +1385,7 @@
         Bundles.back().push_back(std::move(C));
       }
     };
-    DenseSet<const Symbol *> UsedIndexResults;
+    llvm::DenseSet<const Symbol *> UsedIndexResults;
     auto CorrespondingIndexResult =
         [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
       if (auto SymID =
@@ -1491,7 +1415,7 @@
     return std::move(Top).items();
   }
 
-  Optional<float> fuzzyScore(const CompletionCandidate &C) {
+  llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) {
     // Macros can be very spammy, so we only support prefix completion.
     // We won't end up with underfull index results, as macros are sema-only.
     if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro &&
@@ -1558,8 +1482,8 @@
                                : Scores.Quality;
 
     dlog("CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name,
-         to_string(Origin), Scores.Total, to_string(Quality),
-         to_string(Relevance));
+         llvm::to_string(Origin), Scores.Total, llvm::to_string(Quality),
+         llvm::to_string(Relevance));
 
     NSema += bool(Origin & SymbolOrigin::AST);
     NIndex += FromIndex;
@@ -1569,7 +1493,7 @@
   }
 
   CodeCompletion toCodeCompletion(const CompletionCandidate::Bundle &Bundle) {
-    Optional<CodeCompletionBuilder> Builder;
+    llvm::Optional<CodeCompletionBuilder> Builder;
     for (const auto &Item : Bundle) {
       CodeCompletionString *SemaCCS =
           Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
@@ -1585,21 +1509,44 @@
   }
 };
 
-Expected<StringRef> speculateCompletionFilter(StringRef Content, Position Pos) {
+} // namespace
+
+clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
+  clang::CodeCompleteOptions Result;
+  Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
+  Result.IncludeMacros = IncludeMacros;
+  Result.IncludeGlobals = true;
+  // We choose to include full comments and not do doxygen parsing in
+  // completion.
+  // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
+  // formatting of the comments.
+  Result.IncludeBriefComments = false;
+
+  // When an is used, Sema is responsible for completing the main file,
+  // the index can provide results from the preamble.
+  // Tell Sema not to deserialize the preamble to look for results.
+  Result.LoadExternal = !Index;
+  Result.IncludeFixIts = IncludeFixIts;
+
+  return Result;
+}
+
+llvm::Expected<llvm::StringRef>
+speculateCompletionFilter(llvm::StringRef Content, Position Pos) {
   auto Offset = positionToOffset(Content, Pos);
   if (!Offset)
-    return make_error<StringError>(
+    return llvm::make_error<llvm::StringError>(
         "Failed to convert position to offset in content.",
-        inconvertibleErrorCode());
+        llvm::inconvertibleErrorCode());
   if (*Offset == 0)
     return "";
 
   // 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 == '_'));
+  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) {
@@ -1611,8 +1558,8 @@
 
 CodeCompleteResult
 codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
-             const PreambleData *Preamble, StringRef Contents, Position Pos,
-             IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+             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,
@@ -1623,9 +1570,9 @@
 
 SignatureHelp signatureHelp(PathRef FileName,
                             const tooling::CompileCommand &Command,
-                            const PreambleData *Preamble, StringRef Contents,
-                            Position Pos,
-                            IntrusiveRefCntPtr<vfs::FileSystem> VFS,
+                            const PreambleData *Preamble,
+                            llvm::StringRef Contents, Position Pos,
+                            llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
                             std::shared_ptr<PCHContainerOperations> PCHs,
                             const SymbolIndex *Index) {
   SignatureHelp Result;
@@ -1670,12 +1617,12 @@
   LSP.label = ((InsertInclude && InsertInclude->Insertion)
                    ? Opts.IncludeIndicator.Insert
                    : Opts.IncludeIndicator.NoInsert) +
-              (Opts.ShowOrigins ? "[" + to_string(Origin) + "]" : "") +
+              (Opts.ShowOrigins ? "[" + llvm::to_string(Origin) + "]" : "") +
               RequiredQualifier + Name + Signature;
 
   LSP.kind = Kind;
-  LSP.detail =
-      BundleSize > 1 ? formatv("[{0} overloads]", BundleSize) : ReturnType;
+  LSP.detail = BundleSize > 1 ? llvm::formatv("[{0} overloads]", BundleSize)
+                              : ReturnType;
   LSP.deprecated = Deprecated;
   if (InsertInclude)
     LSP.detail += "\n" + InsertInclude->Header;
@@ -1691,7 +1638,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 {
@@ -1712,12 +1659,13 @@
   return LSP;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const CodeCompletion &C) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeCompletion &C) {
   // For now just lean on CompletionItem.
   return OS << C.render(CodeCompleteOptions());
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const CodeCompleteResult &R) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const CodeCompleteResult &R) {
   OS << "CodeCompleteResult: " << R.Completions.size() << (R.HasMore ? "+" : "")
      << " (" << getCompletionKindString(R.Context) << ")"
      << " items:\n";
diff --git a/clangd/CodeComplete.h b/clangd/CodeComplete.h
index 4d32414..0815137 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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/CodeCompletionStrings.cpp b/clangd/CodeCompletionStrings.cpp
index f7e3161..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,17 +13,16 @@
 #include "clang/Basic/SourceManager.h"
 #include <utility>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 bool isInformativeQualifierChunk(CodeCompletionString::Chunk const &Chunk) {
   return Chunk.Kind == CodeCompletionString::CK_Informative &&
-         StringRef(Chunk.Text).endswith("::");
+         llvm::StringRef(Chunk.Text).endswith("::");
 }
 
-void appendEscapeSnippet(const StringRef Text, std::string *Out) {
+void appendEscapeSnippet(const llvm::StringRef Text, std::string *Out) {
   for (const auto Character : Text) {
     if (Character == '$' || Character == '}' || Character == '\\')
       Out->push_back('\\');
@@ -32,13 +30,13 @@
   }
 }
 
-bool looksLikeDocComment(StringRef CommentText) {
+bool looksLikeDocComment(llvm::StringRef CommentText) {
   // We don't report comments that only contain "special" chars.
   // This avoids reporting various delimiters, like:
   //   =================
   //   -----------------
   //   *****************
-  return CommentText.find_first_not_of("/*-= \t\r\n") != StringRef::npos;
+  return CommentText.find_first_not_of("/*-= \t\r\n") != llvm::StringRef::npos;
 }
 
 } // namespace
@@ -69,7 +67,8 @@
   // Sanity check that the comment does not come from the PCH. We choose to not
   // write them into PCH, because they are racy and slow to load.
   assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
-  std::string Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
+  std::string Doc =
+      RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
   return looksLikeDocComment(Doc) ? Doc : "";
 }
 
@@ -96,12 +95,12 @@
       //   treat them carefully. For Objective-C methods, all typed-text chunks
       //   will end in ':' (unless there are no arguments, in which case we
       //   can safely treat them as C++).
-      if (!StringRef(Chunk.Text).endswith(":")) {  // Treat as C++.
+      if (!llvm::StringRef(Chunk.Text).endswith(":")) { // Treat as C++.
         if (RequiredQualifiers)
           *RequiredQualifiers = std::move(*Signature);
         Signature->clear();
         Snippet->clear();
-      } else {  // Objective-C method with args.
+      } else { // Objective-C method with args.
         // If this is the first TypedText to the Objective-C method, discard any
         // text that we've previously seen (such as previous parameter selector,
         // which will be marked as Informative text).
@@ -111,7 +110,7 @@
         if (!HadObjCArguments) {
           HadObjCArguments = true;
           Signature->clear();
-        } else {  // Subsequent argument, considered part of snippet/signature.
+        } else { // Subsequent argument, considered part of snippet/signature.
           *Signature += Chunk.Text;
           *Snippet += Chunk.Text;
         }
@@ -170,7 +169,7 @@
 }
 
 std::string formatDocumentation(const CodeCompletionString &CCS,
-                                StringRef DocComment) {
+                                llvm::StringRef DocComment) {
   // Things like __attribute__((nonnull(1,3))) and [[noreturn]]. Present this
   // information in the documentation field.
   std::string Result;
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 011841c..1eecce9 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,21 +13,20 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/FormatVariadic.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
 void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel,
                             const clang::Diagnostic &Info) {
   // FIXME: format lazily, in case vlog is off.
-  SmallString<64> Message;
+  llvm::SmallString<64> Message;
   Info.FormatDiagnostic(Message);
 
-  SmallString<64> Location;
+  llvm::SmallString<64> Location;
   if (Info.hasSourceManager() && Info.getLocation().isValid()) {
     auto &SourceMgr = Info.getSourceManager();
     auto Loc = SourceMgr.getFileLoc(Info.getLocation());
-    raw_svector_ostream OS(Location);
+    llvm::raw_svector_ostream OS(Location);
     Loc.print(OS, SourceMgr);
     OS << ":";
   }
@@ -41,11 +39,41 @@
   IgnoreDiagnostics::log(DiagLevel, Info);
 }
 
-std::unique_ptr<CompilerInstance> prepareCompilerInstance(
-    std::unique_ptr<clang::CompilerInvocation> CI,
-    const PrecompiledPreamble *Preamble, std::unique_ptr<MemoryBuffer> Buffer,
-    std::shared_ptr<PCHContainerOperations> PCHs,
-    IntrusiveRefCntPtr<vfs::FileSystem> VFS, DiagnosticConsumer &DiagsClient) {
+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");
   assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers &&
          "Setting RetainRemappedFileBuffers to true will cause a memory leak "
diff --git a/clangd/Compiler.h b/clangd/Compiler.h
index 7a3c43d..9466d8e 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 "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
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 a8bfa29..8387621 100644
--- a/clangd/Diagnostics.cpp
+++ b/clangd/Diagnostics.cpp
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,7 +16,6 @@
 #include "llvm/Support/Path.h"
 #include <algorithm>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -57,7 +55,7 @@
     if (locationInRange(Loc, R, M))
       return halfOpenToRange(M, R);
   }
-  Optional<Range> FallbackRange;
+  llvm::Optional<Range> FallbackRange;
   // The range may be given as a fixit hint instead.
   for (const auto &F : D.getFixItHints()) {
     auto R = Lexer::makeFileCharRange(F.RemoveRange, M, L);
@@ -93,7 +91,7 @@
   return L == DiagnosticsEngine::Note || L == DiagnosticsEngine::Remark;
 }
 
-StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) {
+llvm::StringRef diagLeveltoString(DiagnosticsEngine::Level Lvl) {
   switch (Lvl) {
   case DiagnosticsEngine::Ignored:
     return "ignored";
@@ -122,12 +120,12 @@
 ///
 ///     dir1/dir2/dir3/../../dir4/header.h:12:23
 ///     error: undeclared identifier
-void printDiag(raw_string_ostream &OS, const DiagBase &D) {
+void printDiag(llvm::raw_string_ostream &OS, const DiagBase &D) {
   if (D.InsideMainFile) {
     // Paths to main files are often taken from compile_command.json, where they
     // are typically absolute. To reduce noise we print only basename for them,
     // it should not be confusing and saves space.
-    OS << sys::path::filename(D.File) << ":";
+    OS << llvm::sys::path::filename(D.File) << ":";
   } else {
     OS << D.File << ":";
   }
@@ -147,7 +145,7 @@
 /// Capitalizes the first word in the diagnostic's message.
 std::string capitalize(std::string Message) {
   if (!Message.empty())
-    Message[0] = toUpper(Message[0]);
+    Message[0] = llvm::toUpper(Message[0]);
   return Message;
 }
 
@@ -165,8 +163,10 @@
 ///     note: candidate function not viable: requires 3 arguments
 std::string mainMessage(const Diag &D) {
   std::string Result;
-  raw_string_ostream OS(Result);
+  llvm::raw_string_ostream OS(Result);
   OS << D.Message;
+  if (!D.Fixes.empty())
+    OS << " (" << (D.Fixes.size() > 1 ? "fixes" : "fix") << " available)";
   for (auto &Note : D.Notes) {
     OS << "\n\n";
     printDiag(OS, Note);
@@ -180,7 +180,7 @@
 /// for the user to understand the note.
 std::string noteMessage(const Diag &Main, const DiagBase &Note) {
   std::string Result;
-  raw_string_ostream OS(Result);
+  llvm::raw_string_ostream OS(Result);
   OS << Note.Message;
   OS << "\n\n";
   printDiag(OS, Main);
@@ -189,7 +189,7 @@
 }
 } // namespace
 
-raw_ostream &operator<<(raw_ostream &OS, const DiagBase &D) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const DiagBase &D) {
   OS << "[";
   if (!D.InsideMainFile)
     OS << D.File << ":";
@@ -198,7 +198,7 @@
   return OS << D.Message;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Fix &F) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Fix &F) {
   OS << F.Message << " {";
   const char *Sep = "";
   for (const auto &Edit : F.Edits) {
@@ -208,7 +208,7 @@
   return OS << "}";
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Diag &D) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diag &D) {
   OS << static_cast<const DiagBase &>(D);
   if (!D.Notes.empty()) {
     OS << ", notes: {";
@@ -242,7 +242,7 @@
 
 void toLSPDiags(
     const Diag &D, const URIForFile &File, const ClangdDiagnosticOptions &Opts,
-    function_ref<void(clangd::Diagnostic, ArrayRef<Fix>)> OutFn) {
+    llvm::function_ref<void(clangd::Diagnostic, llvm::ArrayRef<Fix>)> OutFn) {
   auto FillBasicFields = [](const DiagBase &D) -> clangd::Diagnostic {
     clangd::Diagnostic Res;
     Res.range = D.Range;
@@ -269,7 +269,7 @@
       continue;
     clangd::Diagnostic Res = FillBasicFields(Note);
     Res.message = noteMessage(D, Note);
-    OutFn(std::move(Res), ArrayRef<Fix>());
+    OutFn(std::move(Res), llvm::ArrayRef<Fix>());
   }
 }
 
@@ -315,7 +315,7 @@
 
   auto FillDiagBase = [&](DiagBase &D) {
     D.Range = diagnosticRange(Info, *LangOpts);
-    SmallString<64> Message;
+    llvm::SmallString<64> Message;
     Info.FormatDiagnostic(Message);
     D.Message = Message.str();
     D.InsideMainFile = InsideMainFile;
@@ -333,7 +333,7 @@
     if (!InsideMainFile)
       return false;
 
-    SmallVector<TextEdit, 1> Edits;
+    llvm::SmallVector<TextEdit, 1> Edits;
     for (auto &FixIt : Info.getFixItHints()) {
       if (!isInsideMainFile(FixIt.RemoveRange.getBegin(),
                             Info.getSourceManager()))
@@ -341,16 +341,16 @@
       Edits.push_back(toTextEdit(FixIt, Info.getSourceManager(), *LangOpts));
     }
 
-    SmallString<64> Message;
+    llvm::SmallString<64> Message;
     // If requested and possible, create a message like "change 'foo' to 'bar'".
     if (SyntheticMessage && Info.getNumFixItHints() == 1) {
       const auto &FixIt = Info.getFixItHint(0);
       bool Invalid = false;
-      StringRef Remove = Lexer::getSourceText(
+      llvm::StringRef Remove = Lexer::getSourceText(
           FixIt.RemoveRange, Info.getSourceManager(), *LangOpts, &Invalid);
-      StringRef Insert = FixIt.CodeToInsert;
+      llvm::StringRef Insert = FixIt.CodeToInsert;
       if (!Invalid) {
-        raw_svector_ostream M(Message);
+        llvm::raw_svector_ostream M(Message);
         if (!Remove.empty() && !Insert.empty())
           M << "change '" << Remove << "' to '" << Insert << "'";
         else if (!Remove.empty())
@@ -376,6 +376,11 @@
 
     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) {
@@ -405,8 +410,8 @@
   if (mentionsMainFile(*LastDiag))
     Output.push_back(std::move(*LastDiag));
   else
-    log("Dropped diagnostic outside main file: {0}: {1}", LastDiag->File,
-        LastDiag->Message);
+    vlog("Dropped diagnostic outside main file: {0}: {1}", LastDiag->File,
+         LastDiag->Message);
   LastDiag.reset();
 }
 
diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h
index 6318e88..9130ad5 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -100,9 +99,15 @@
   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;
diff --git a/clangd/DraftStore.cpp b/clangd/DraftStore.cpp
index b5bcda8..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,11 +10,10 @@
 #include "SourceCode.h"
 #include "llvm/Support/Errc.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
-Optional<std::string> DraftStore::getDraft(PathRef File) const {
+llvm::Optional<std::string> DraftStore::getDraft(PathRef File) const {
   std::lock_guard<std::mutex> Lock(Mutex);
 
   auto It = Drafts.find(File);
@@ -35,20 +33,19 @@
   return ResultVector;
 }
 
-void DraftStore::addDraft(PathRef File, StringRef Contents) {
+void DraftStore::addDraft(PathRef File, llvm::StringRef Contents) {
   std::lock_guard<std::mutex> Lock(Mutex);
 
   Drafts[File] = Contents;
 }
 
-Expected<std::string>
-DraftStore::updateDraft(PathRef File,
-                        ArrayRef<TextDocumentContentChangeEvent> Changes) {
+llvm::Expected<std::string> DraftStore::updateDraft(
+    PathRef File, llvm::ArrayRef<TextDocumentContentChangeEvent> Changes) {
   std::lock_guard<std::mutex> Lock(Mutex);
 
   auto EntryIt = Drafts.find(File);
   if (EntryIt == Drafts.end()) {
-    return make_error<StringError>(
+    return llvm::make_error<llvm::StringError>(
         "Trying to do incremental update on non-added document: " + File,
         llvm::errc::invalid_argument);
   }
@@ -62,19 +59,21 @@
     }
 
     const Position &Start = Change.range->start;
-    Expected<size_t> StartIndex = positionToOffset(Contents, Start, false);
+    llvm::Expected<size_t> StartIndex =
+        positionToOffset(Contents, Start, false);
     if (!StartIndex)
       return StartIndex.takeError();
 
     const Position &End = Change.range->end;
-    Expected<size_t> EndIndex = positionToOffset(Contents, End, false);
+    llvm::Expected<size_t> EndIndex = positionToOffset(Contents, End, false);
     if (!EndIndex)
       return EndIndex.takeError();
 
     if (*EndIndex < *StartIndex)
-      return make_error<StringError>(
-          formatv("Range's end position ({0}) is before start position ({1})",
-                  End, Start),
+      return llvm::make_error<llvm::StringError>(
+          llvm::formatv(
+              "Range's end position ({0}) is before start position ({1})", End,
+              Start),
           llvm::errc::invalid_argument);
 
     // Since the range length between two LSP positions is dependent on the
@@ -88,10 +87,10 @@
         lspLength(Contents.substr(*StartIndex, *EndIndex - *StartIndex));
 
     if (Change.rangeLength && ComputedRangeLength != *Change.rangeLength)
-      return make_error<StringError>(
-          formatv("Change's rangeLength ({0}) doesn't match the "
-                  "computed range length ({1}).",
-                  *Change.rangeLength, *EndIndex - *StartIndex),
+      return llvm::make_error<llvm::StringError>(
+          llvm::formatv("Change's rangeLength ({0}) doesn't match the "
+                        "computed range length ({1}).",
+                        *Change.rangeLength, *EndIndex - *StartIndex),
           llvm::errc::invalid_argument);
 
     std::string NewContents;
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 5c9cec8..59d9e14 100644
--- a/clangd/ExpectedTypes.cpp
+++ b/clangd/ExpectedTypes.cpp
@@ -5,8 +5,6 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/ADT/STLExtras.h"
 
-using namespace llvm;
-
 namespace clang {
 namespace clangd {
 namespace {
@@ -33,11 +31,14 @@
   return T.getTypePtr();
 }
 
-static Optional<QualType> typeOfCompletion(const CodeCompletionResult &R) {
+static llvm::Optional<QualType>
+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.
@@ -49,13 +50,13 @@
 }
 } // namespace
 
-Optional<OpaqueType> OpaqueType::encode(ASTContext &Ctx, QualType T) {
+llvm::Optional<OpaqueType> OpaqueType::encode(ASTContext &Ctx, QualType T) {
   if (T.isNull())
     return None;
   const Type *C = toEquivClass(Ctx, T);
   if (!C)
     return None;
-  SmallString<128> Encoded;
+  llvm::SmallString<128> Encoded;
   if (index::generateUSRForType(QualType(C, 0), Ctx, Encoded))
     return None;
   return OpaqueType(Encoded.str());
@@ -63,11 +64,12 @@
 
 OpaqueType::OpaqueType(std::string Data) : Data(std::move(Data)) {}
 
-Optional<OpaqueType> OpaqueType::fromType(ASTContext &Ctx, QualType Type) {
+llvm::Optional<OpaqueType> OpaqueType::fromType(ASTContext &Ctx,
+                                                QualType Type) {
   return encode(Ctx, Type);
 }
 
-Optional<OpaqueType>
+llvm::Optional<OpaqueType>
 OpaqueType::fromCompletionResult(ASTContext &Ctx,
                                  const CodeCompletionResult &R) {
   auto T = typeOfCompletion(R);
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 e588e00..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,17 +11,17 @@
 #include "llvm/ADT/None.h"
 #include "llvm/Support/Path.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
-PreambleFileStatusCache::PreambleFileStatusCache(StringRef MainFilePath)
+PreambleFileStatusCache::PreambleFileStatusCache(llvm::StringRef MainFilePath)
     : MainFilePath(MainFilePath) {
-  assert(sys::path::is_absolute(MainFilePath));
+  assert(llvm::sys::path::is_absolute(MainFilePath));
 }
 
-void PreambleFileStatusCache::update(const vfs::FileSystem &FS, vfs::Status S) {
-  SmallString<32> PathStore(S.getName());
+void PreambleFileStatusCache::update(const llvm::vfs::FileSystem &FS,
+                                     llvm::vfs::Status S) {
+  llvm::SmallString<32> PathStore(S.getName());
   if (FS.makeAbsolute(PathStore))
     return;
   // Do not cache status for the main file.
@@ -32,25 +31,27 @@
   StatCache.insert({PathStore, std::move(S)});
 }
 
-Optional<vfs::Status> PreambleFileStatusCache::lookup(StringRef File) const {
+llvm::Optional<llvm::vfs::Status>
+PreambleFileStatusCache::lookup(llvm::StringRef File) const {
   auto I = StatCache.find(File);
   if (I != StatCache.end())
     return I->getValue();
   return None;
 }
 
-IntrusiveRefCntPtr<vfs::FileSystem> PreambleFileStatusCache::getProducingFS(
-    IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+PreambleFileStatusCache::getProducingFS(
+    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
   // This invalidates old status in cache if files are re-`open()`ed or
   // re-`stat()`ed in case file status has changed during preamble build.
-  class CollectFS : public vfs::ProxyFileSystem {
+  class CollectFS : public llvm::vfs::ProxyFileSystem {
   public:
-    CollectFS(IntrusiveRefCntPtr<vfs::FileSystem> FS,
+    CollectFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
               PreambleFileStatusCache &StatCache)
         : ProxyFileSystem(std::move(FS)), StatCache(StatCache) {}
 
-    ErrorOr<std::unique_ptr<vfs::File>>
-    openFileForRead(const Twine &Path) override {
+    llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
+    openFileForRead(const llvm::Twine &Path) override {
       auto File = getUnderlyingFS().openFileForRead(Path);
       if (!File || !*File)
         return File;
@@ -64,7 +65,7 @@
       return File;
     }
 
-    ErrorOr<vfs::Status> status(const Twine &Path) override {
+    llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override {
       auto S = getUnderlyingFS().status(Path);
       if (S)
         StatCache.update(getUnderlyingFS(), *S);
@@ -74,18 +75,20 @@
   private:
     PreambleFileStatusCache &StatCache;
   };
-  return IntrusiveRefCntPtr<CollectFS>(new CollectFS(std::move(FS), *this));
+  return llvm::IntrusiveRefCntPtr<CollectFS>(
+      new CollectFS(std::move(FS), *this));
 }
 
-IntrusiveRefCntPtr<vfs::FileSystem> PreambleFileStatusCache::getConsumingFS(
-    IntrusiveRefCntPtr<vfs::FileSystem> FS) const {
-  class CacheVFS : public vfs::ProxyFileSystem {
+llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+PreambleFileStatusCache::getConsumingFS(
+    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) const {
+  class CacheVFS : public llvm::vfs::ProxyFileSystem {
   public:
-    CacheVFS(IntrusiveRefCntPtr<vfs::FileSystem> FS,
+    CacheVFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
              const PreambleFileStatusCache &StatCache)
         : ProxyFileSystem(std::move(FS)), StatCache(StatCache) {}
 
-    ErrorOr<vfs::Status> status(const Twine &Path) override {
+    llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override {
       if (auto S = StatCache.lookup(Path.str()))
         return *S;
       return getUnderlyingFS().status(Path);
@@ -94,7 +97,7 @@
   private:
     const PreambleFileStatusCache &StatCache;
   };
-  return IntrusiveRefCntPtr<CacheVFS>(new CacheVFS(std::move(FS), *this));
+  return llvm::IntrusiveRefCntPtr<CacheVFS>(new CacheVFS(std::move(FS), *this));
 }
 
 } // namespace clangd
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 ccb64c5..be91574 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,8 +14,6 @@
 #include "llvm/Support/VirtualFileSystem.h"
 #include <memory>
 
-using namespace llvm;
-
 namespace clang {
 namespace clangd {
 
@@ -28,9 +25,9 @@
   explicit VolatileFileSystem(llvm::IntrusiveRefCntPtr<FileSystem> FS)
       : ProxyFileSystem(std::move(FS)) {}
 
-  llvm::ErrorOr<std::unique_ptr<vfs::File>>
-  openFileForRead(const Twine &InPath) override {
-    SmallString<128> Path;
+  llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
+  openFileForRead(const llvm::Twine &InPath) override {
+    llvm::SmallString<128> Path;
     InPath.toVector(Path);
 
     auto File = getUnderlyingFS().openFileForRead(Path);
@@ -38,29 +35,30 @@
       return File;
     // Try to guess preamble files, they can be memory-mapped even on Windows as
     // clangd has exclusive access to those.
-    StringRef FileName = llvm::sys::path::filename(Path);
+    llvm::StringRef FileName = llvm::sys::path::filename(Path);
     if (FileName.startswith("preamble-") && FileName.endswith(".pch"))
       return File;
-    return std::unique_ptr<VolatileFile>(
-        new VolatileFile(std::move(*File)));
+    return std::unique_ptr<VolatileFile>(new VolatileFile(std::move(*File)));
   }
 
 private:
-  class VolatileFile : public vfs::File {
+  class VolatileFile : public llvm::vfs::File {
   public:
-    VolatileFile(std::unique_ptr<vfs::File> Wrapped)
+    VolatileFile(std::unique_ptr<llvm::vfs::File> Wrapped)
         : Wrapped(std::move(Wrapped)) {
       assert(this->Wrapped);
     }
 
     virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-    getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
-              bool /*IsVolatile*/) override {
+    getBuffer(const llvm::Twine &Name, int64_t FileSize,
+              bool RequiresNullTerminator, bool /*IsVolatile*/) override {
       return Wrapped->getBuffer(Name, FileSize, RequiresNullTerminator,
                                 /*IsVolatile=*/true);
     }
 
-    llvm::ErrorOr<vfs::Status> status() override { return Wrapped->status(); }
+    llvm::ErrorOr<llvm::vfs::Status> status() override {
+      return Wrapped->status();
+    }
     llvm::ErrorOr<std::string> getName() override { return Wrapped->getName(); }
     std::error_code close() override { return Wrapped->close(); }
 
@@ -76,9 +74,9 @@
 // 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(vfs::getRealFileSystem());
+  return new VolatileFileSystem(llvm::vfs::getRealFileSystem());
 #else
-  return vfs::getRealFileSystem();
+  return llvm::vfs::getRealFileSystem();
 #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/Features.inc.in b/clangd/Features.inc.in
new file mode 100644
index 0000000..da75aa6
--- /dev/null
+++ b/clangd/Features.inc.in
@@ -0,0 +1 @@
+#define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@
diff --git a/clangd/FileDistance.cpp b/clangd/FileDistance.cpp
index 6bd73e5..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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -36,7 +35,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include <queue>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -45,21 +43,23 @@
 //   C:\foo\bar --> /c:/foo/bar
 //   /foo/      --> /foo
 //   a/b/c      --> /a/b/c
-static SmallString<128> canonicalize(StringRef Path) {
-  SmallString<128> Result = Path.rtrim('/');
-  native(Result, sys::path::Style::posix);
+static llvm::SmallString<128> canonicalize(llvm::StringRef Path) {
+  llvm::SmallString<128> Result = Path.rtrim('/');
+  native(Result, llvm::sys::path::Style::posix);
   if (Result.empty() || Result.front() != '/')
     Result.insert(Result.begin(), '/');
   return Result;
 }
 
 constexpr const unsigned FileDistance::Unreachable;
-const hash_code FileDistance::RootHash = hash_value(StringRef("/"));
+const llvm::hash_code FileDistance::RootHash =
+    llvm::hash_value(llvm::StringRef("/"));
 
-FileDistance::FileDistance(StringMap<SourceParams> Sources,
+FileDistance::FileDistance(llvm::StringMap<SourceParams> Sources,
                            const FileDistanceOptions &Opts)
     : Opts(Opts) {
-  DenseMap<hash_code, SmallVector<hash_code, 4>> DownEdges;
+  llvm::DenseMap<llvm::hash_code, llvm::SmallVector<llvm::hash_code, 4>>
+      DownEdges;
   // Compute the best distance following only up edges.
   // Keep track of down edges, in case we can use them to improve on this.
   for (const auto &S : Sources) {
@@ -67,13 +67,13 @@
     dlog("Source {0} = {1}, MaxUp = {2}", Canonical, S.second.Cost,
          S.second.MaxUpTraversals);
     // Walk up to ancestors of this source, assigning cost.
-    StringRef Rest = Canonical;
-    hash_code Hash = hash_value(Rest);
+    llvm::StringRef Rest = Canonical;
+    llvm::hash_code Hash = llvm::hash_value(Rest);
     for (unsigned I = 0; !Rest.empty(); ++I) {
-      Rest = parent_path(Rest, sys::path::Style::posix);
-      auto NextHash = hash_value(Rest);
+      Rest = parent_path(Rest, llvm::sys::path::Style::posix);
+      auto NextHash = llvm::hash_value(Rest);
       auto &Down = DownEdges[NextHash];
-      if (!is_contained(Down, Hash))
+      if (!llvm::is_contained(Down, Hash))
         Down.push_back(Hash);
       // We can't just break after MaxUpTraversals, must still set DownEdges.
       if (I > S.getValue().MaxUpTraversals) {
@@ -96,8 +96,8 @@
   }
   // Now propagate scores parent -> child if that's an improvement.
   // BFS ensures we propagate down chains (must visit parents before children).
-  std::queue<hash_code> Next;
-  for (auto Child : DownEdges.lookup(hash_value(StringRef(""))))
+  std::queue<llvm::hash_code> Next;
+  for (auto Child : DownEdges.lookup(llvm::hash_value(llvm::StringRef(""))))
     Next.push(Child);
   while (!Next.empty()) {
     auto Parent = Next.front();
@@ -115,14 +115,14 @@
   }
 }
 
-unsigned FileDistance::distance(StringRef Path) {
+unsigned FileDistance::distance(llvm::StringRef Path) {
   auto Canonical = canonicalize(Path);
   unsigned Cost = Unreachable;
-  SmallVector<hash_code, 16> Ancestors;
+  llvm::SmallVector<llvm::hash_code, 16> Ancestors;
   // Walk up ancestors until we find a path we know the distance for.
-  for (StringRef Rest = Canonical; !Rest.empty();
-       Rest = parent_path(Rest, sys::path::Style::posix)) {
-    auto Hash = hash_value(Rest);
+  for (llvm::StringRef Rest = Canonical; !Rest.empty();
+       Rest = parent_path(Rest, llvm::sys::path::Style::posix)) {
+    auto Hash = llvm::hash_value(Rest);
     if (Hash == RootHash && !Ancestors.empty() &&
         !Opts.AllowDownTraversalFromRoot) {
       Cost = Unreachable;
@@ -137,7 +137,7 @@
   }
   // Now we know the costs for (known node, queried node].
   // Fill these in, walking down the directory tree.
-  for (hash_code Hash : reverse(Ancestors)) {
+  for (llvm::hash_code Hash : llvm::reverse(Ancestors)) {
     if (Cost != Unreachable)
       Cost += Opts.DownCost;
     Cache.try_emplace(Hash, Cost);
@@ -146,8 +146,8 @@
   return Cost;
 }
 
-unsigned URIDistance::distance(StringRef URI) {
-  auto R = Cache.try_emplace(hash_value(URI), FileDistance::Unreachable);
+unsigned URIDistance::distance(llvm::StringRef URI) {
+  auto R = Cache.try_emplace(llvm::hash_value(URI), FileDistance::Unreachable);
   if (!R.second)
     return R.first->getSecond();
   if (auto U = clangd::URI::parse(URI)) {
@@ -159,15 +159,15 @@
   return R.first->second;
 }
 
-FileDistance &URIDistance::forScheme(StringRef Scheme) {
+FileDistance &URIDistance::forScheme(llvm::StringRef Scheme) {
   auto &Delegate = ByScheme[Scheme];
   if (!Delegate) {
-    StringMap<SourceParams> SchemeSources;
+    llvm::StringMap<SourceParams> SchemeSources;
     for (const auto &Source : Sources) {
       if (auto U = clangd::URI::create(Source.getKey(), Scheme))
         SchemeSources.try_emplace(U->body(), Source.getValue());
       else
-        consumeError(U.takeError());
+        llvm::consumeError(U.takeError());
     }
     dlog("FileDistance for scheme {0}: {1}/{2} sources", Scheme,
          SchemeSources.size(), Sources.size());
@@ -176,21 +176,23 @@
   return *Delegate;
 }
 
-static std::pair<std::string, int> scopeToPath(StringRef Scope) {
-  SmallVector<StringRef, 4> Split;
+static std::pair<std::string, int> scopeToPath(llvm::StringRef Scope) {
+  llvm::SmallVector<llvm::StringRef, 4> Split;
   Scope.split(Split, "::", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
-  return {"/" + join(Split, "/"), Split.size()};
+  return {"/" + llvm::join(Split, "/"), Split.size()};
 }
 
-static FileDistance createScopeFileDistance(ArrayRef<std::string> QueryScopes) {
+static FileDistance
+createScopeFileDistance(llvm::ArrayRef<std::string> QueryScopes) {
   FileDistanceOptions Opts;
   Opts.UpCost = 2;
   Opts.DownCost = 4;
   Opts.AllowDownTraversalFromRoot = false;
 
-  StringMap<SourceParams> Sources;
-  StringRef Preferred = QueryScopes.empty() ? "" : QueryScopes.front().c_str();
-  for (StringRef S : QueryScopes) {
+  llvm::StringMap<SourceParams> Sources;
+  llvm::StringRef Preferred =
+      QueryScopes.empty() ? "" : QueryScopes.front().c_str();
+  for (llvm::StringRef S : QueryScopes) {
     SourceParams Param;
     // Penalize the global scope even it's preferred, as all projects can define
     // symbols in it, and there is pattern where using-namespace is used in
@@ -209,10 +211,10 @@
   return FileDistance(Sources, Opts);
 }
 
-ScopeDistance::ScopeDistance(ArrayRef<std::string> QueryScopes)
+ScopeDistance::ScopeDistance(llvm::ArrayRef<std::string> QueryScopes)
     : Distance(createScopeFileDistance(QueryScopes)) {}
 
-unsigned ScopeDistance::distance(StringRef SymbolScope) {
+unsigned ScopeDistance::distance(llvm::StringRef SymbolScope) {
   return Distance.distance(scopeToPath(SymbolScope).first);
 }
 
diff --git a/clangd/FileDistance.h b/clangd/FileDistance.h
index d60afa2..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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -54,9 +53,9 @@
 namespace clangd {
 
 struct FileDistanceOptions {
-  unsigned UpCost = 2;      // |foo/bar.h -> foo|
-  unsigned DownCost = 1;    // |foo -> foo/bar.h|
-  unsigned IncludeCost = 2; // |foo.cc -> included_header.h|
+  unsigned UpCost = 2;                    // |foo/bar.h -> foo|
+  unsigned DownCost = 1;                  // |foo -> foo/bar.h|
+  unsigned IncludeCost = 2;               // |foo.cc -> included_header.h|
   bool AllowDownTraversalFromRoot = true; // | / -> /a |
 };
 
diff --git a/clangd/FindSymbols.cpp b/clangd/FindSymbols.cpp
index aca17f9..0081955 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"
@@ -25,7 +24,6 @@
 
 #define DEBUG_TYPE "FindSymbols"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -100,9 +98,9 @@
 
 } // namespace
 
-Expected<std::vector<SymbolInformation>>
-getWorkspaceSymbols(StringRef Query, int Limit, const SymbolIndex *const Index,
-                    StringRef HintPath) {
+llvm::Expected<std::vector<SymbolInformation>>
+getWorkspaceSymbols(llvm::StringRef Query, int Limit,
+                    const SymbolIndex *const Index, llvm::StringRef HintPath) {
   std::vector<SymbolInformation> Result;
   if (Query.empty() || !Index)
     return Result;
@@ -153,7 +151,7 @@
     L.range = {Start, End};
     SymbolKind SK = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind);
     std::string Scope = Sym.Scope;
-    StringRef ScopeRef = Scope;
+    llvm::StringRef ScopeRef = Scope;
     ScopeRef.consume_back("::");
     SymbolInformation Info = {Sym.Name, SK, L, ScopeRef};
 
@@ -190,7 +188,7 @@
   // 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 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;
diff --git a/clangd/FindSymbols.h b/clangd/FindSymbols.h
index a9c8c99..78bdbd3 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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/Function.h b/clangd/Function.h
index 52effe0..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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -133,7 +132,6 @@
     std::lock_guard<std::recursive_mutex> Lock(ListenersMu);
     Listeners.push_back({std::move(L), ++ListenerCount});
     return Subscription(this, ListenerCount);
-    ;
   }
 
   // Synchronously sends an event to all registered listeners.
diff --git a/clangd/FuzzyMatch.cpp b/clangd/FuzzyMatch.cpp
index c16712f..bc61386 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -60,7 +59,6 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/Format.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -75,7 +73,7 @@
 static bool isAwful(int S) { return S < AwfulScore / 2; }
 static constexpr int PerfectBonus = 3; // Perfect per-pattern-char score.
 
-FuzzyMatcher::FuzzyMatcher(StringRef Pattern)
+FuzzyMatcher::FuzzyMatcher(llvm::StringRef Pattern)
     : PatN(std::min<int>(MaxPat, Pattern.size())),
       ScoreScale(PatN ? float{1} / (PerfectBonus * PatN) : 0), WordN(0) {
   std::copy(Pattern.begin(), Pattern.begin() + PatN, Pat);
@@ -87,20 +85,20 @@
     for (int W = 0; W < P; ++W)
       for (Action A : {Miss, Match})
         Scores[P][W][A] = {AwfulScore, Miss};
-  PatTypeSet =
-      calculateRoles(StringRef(Pat, PatN), makeMutableArrayRef(PatRole, PatN));
+  PatTypeSet = calculateRoles(llvm::StringRef(Pat, PatN),
+                              llvm::makeMutableArrayRef(PatRole, PatN));
 }
 
-Optional<float> FuzzyMatcher::match(StringRef Word) {
+llvm::Optional<float> FuzzyMatcher::match(llvm::StringRef Word) {
   if (!(WordContainsPattern = init(Word)))
-    return None;
+    return llvm::None;
   if (!PatN)
     return 1;
   buildGraph();
   auto Best = std::max(Scores[PatN][WordN][Miss].Score,
                        Scores[PatN][WordN][Match].Score);
   if (isAwful(Best))
-    return None;
+    return llvm::None;
   float Score =
       ScoreScale * std::min(PerfectBonus * PatN, std::max<int>(0, Best));
   // If the pattern is as long as the word, we have an exact string match,
@@ -153,7 +151,8 @@
 template <typename T> static T packedLookup(const uint8_t *Data, int I) {
   return static_cast<T>((Data[I >> 2] >> ((I & 3) * 2)) & 3);
 }
-CharTypeSet calculateRoles(StringRef Text, MutableArrayRef<CharRole> Roles) {
+CharTypeSet calculateRoles(llvm::StringRef Text,
+                           llvm::MutableArrayRef<CharRole> Roles) {
   assert(Text.size() == Roles.size());
   if (Text.size() == 0)
     return 0;
@@ -179,7 +178,7 @@
 
 // Sets up the data structures matching Word.
 // Returns false if we can cheaply determine that no match is possible.
-bool FuzzyMatcher::init(StringRef NewWord) {
+bool FuzzyMatcher::init(llvm::StringRef NewWord) {
   WordN = std::min<int>(MaxWord, NewWord.size());
   if (PatN > WordN)
     return false;
@@ -200,8 +199,8 @@
   // FIXME: some words are hard to tokenize algorithmically.
   // e.g. vsprintf is V S Print F, and should match [pri] but not [int].
   // We could add a tokenization dictionary for common stdlib names.
-  WordTypeSet = calculateRoles(StringRef(Word, WordN),
-                               makeMutableArrayRef(WordRole, WordN));
+  WordTypeSet = calculateRoles(llvm::StringRef(Word, WordN),
+                               llvm::makeMutableArrayRef(WordRole, WordN));
   return true;
 }
 
@@ -299,13 +298,13 @@
   return S;
 }
 
-SmallString<256> FuzzyMatcher::dumpLast(raw_ostream &OS) const {
-  SmallString<256> Result;
-  OS << "=== Match \"" << StringRef(Word, WordN) << "\" against ["
-     << StringRef(Pat, PatN) << "] ===\n";
+llvm::SmallString<256> FuzzyMatcher::dumpLast(llvm::raw_ostream &OS) const {
+  llvm::SmallString<256> Result;
+  OS << "=== Match \"" << llvm::StringRef(Word, WordN) << "\" against ["
+     << llvm::StringRef(Pat, PatN) << "] ===\n";
   if (PatN == 0) {
     OS << "Pattern is empty: perfect match.\n";
-    return Result = StringRef(Word, WordN);
+    return Result = llvm::StringRef(Word, WordN);
   }
   if (WordN == 0) {
     OS << "Word is empty: no match.\n";
@@ -349,28 +348,28 @@
   if (A[WordN - 1] == Match)
     Result.push_back(']');
 
-  for (char C : StringRef(Word, WordN))
+  for (char C : llvm::StringRef(Word, WordN))
     OS << " " << C << " ";
   OS << "\n";
   for (int I = 0, J = 0; I < WordN; I++)
     OS << " " << (A[I] == Match ? Pat[J++] : ' ') << " ";
   OS << "\n";
   for (int I = 0; I < WordN; I++)
-    OS << format("%2d ", S[I]);
+    OS << llvm::format("%2d ", S[I]);
   OS << "\n";
 
   OS << "\nSegmentation:";
-  OS << "\n'" << StringRef(Word, WordN) << "'\n ";
+  OS << "\n'" << llvm::StringRef(Word, WordN) << "'\n ";
   for (int I = 0; I < WordN; ++I)
     OS << "?-+ "[static_cast<int>(WordRole[I])];
-  OS << "\n[" << StringRef(Pat, PatN) << "]\n ";
+  OS << "\n[" << llvm::StringRef(Pat, PatN) << "]\n ";
   for (int I = 0; I < PatN; ++I)
     OS << "?-+ "[static_cast<int>(PatRole[I])];
   OS << "\n";
 
   OS << "\nScoring table (last-Miss, last-Match):\n";
   OS << " |    ";
-  for (char C : StringRef(Word, WordN))
+  for (char C : llvm::StringRef(Word, WordN))
     OS << "  " << C << " ";
   OS << "\n";
   OS << "-+----" << std::string(WordN * 4, '-') << "\n";
@@ -379,8 +378,8 @@
       OS << ((I && A == Miss) ? Pat[I - 1] : ' ') << "|";
       for (int J = 0; J <= WordN; ++J) {
         if (!isAwful(Scores[I][J][A].Score))
-          OS << format("%3d%c", Scores[I][J][A].Score,
-                       Scores[I][J][A].Prev == Match ? '*' : ' ');
+          OS << llvm::format("%3d%c", Scores[I][J][A].Score,
+                             Scores[I][J][A].Prev == Match ? '*' : ' ');
         else
           OS << "    ";
       }
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 055f92c..a916197 100644
--- a/clangd/GlobalCompilationDatabase.cpp
+++ b/clangd/GlobalCompilationDatabase.cpp
@@ -1,43 +1,77 @@
 //===--- 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"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
+namespace {
+
+void adjustArguments(tooling::CompileCommand &Cmd,
+                     llvm::StringRef ResourceDir) {
+  // Strip plugin related command line arguments. Clangd does
+  // not support plugins currently. Therefore it breaks if
+  // compiler tries to load plugins.
+  Cmd.CommandLine =
+      tooling::getStripPluginsAdjuster()(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;
+  std::string ClangdExecutable =
+      llvm::sys::fs::getMainExecutable("clangd", (void *)&Dummy);
+  SmallString<128> ClangPath;
+  ClangPath = llvm::sys::path::parent_path(ClangdExecutable);
+  llvm::sys::path::append(ClangPath, "clang");
+  return ClangPath.str();
+}
 
 tooling::CompileCommand
 GlobalCompilationDatabase::getFallbackCommand(PathRef File) const {
-  std::vector<std::string> Argv = {"clang"};
+  std::vector<std::string> Argv = {getFallbackClangPath()};
   // Clang treats .h files as C by default, resulting in unhelpful diagnostics.
   // Parsing as Objective C++ is friendly to more cases.
-  if (sys::path::extension(File) == ".h")
+  if (llvm::sys::path::extension(File) == ".h")
     Argv.push_back("-xobjective-c++-header");
   Argv.push_back(File);
-  return tooling::CompileCommand(sys::path::parent_path(File),
-                                 sys::path::filename(File), std::move(Argv),
+  return tooling::CompileCommand(llvm::sys::path::parent_path(File),
+                                 llvm::sys::path::filename(File),
+                                 std::move(Argv),
                                  /*Output=*/"");
 }
 
 DirectoryBasedGlobalCompilationDatabase::
-    DirectoryBasedGlobalCompilationDatabase(Optional<Path> CompileCommandsDir)
+    DirectoryBasedGlobalCompilationDatabase(
+        llvm::Optional<Path> CompileCommandsDir)
     : CompileCommandsDir(std::move(CompileCommandsDir)) {}
 
 DirectoryBasedGlobalCompilationDatabase::
     ~DirectoryBasedGlobalCompilationDatabase() = default;
 
-Optional<tooling::CompileCommand>
+llvm::Optional<tooling::CompileCommand>
 DirectoryBasedGlobalCompilationDatabase::getCompileCommand(
     PathRef File, ProjectInfo *Project) const {
   if (auto CDB = getCDBForFile(File, Project)) {
@@ -67,7 +101,7 @@
 tooling::CompilationDatabase *
 DirectoryBasedGlobalCompilationDatabase::getCDBForFile(
     PathRef File, ProjectInfo *Project) const {
-  namespace path = sys::path;
+  namespace path = llvm::sys::path;
   assert((path::is_absolute(File, path::Style::posix) ||
           path::is_absolute(File, path::Style::windows)) &&
          "path must be absolute");
@@ -95,26 +129,35 @@
 }
 
 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);
     });
 }
 
-Optional<tooling::CompileCommand>
+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 c43d72c..a5759a4 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,7 +16,6 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "llvm/Support/Path.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -30,9 +28,10 @@
   // Record existing #includes - both written and resolved paths. Only #includes
   // in the main file are collected.
   void InclusionDirective(SourceLocation HashLoc, const Token & /*IncludeTok*/,
-                          StringRef FileName, bool IsAngled,
+                          llvm::StringRef FileName, bool IsAngled,
                           CharSourceRange FilenameRange, const FileEntry *File,
-                          StringRef /*SearchPath*/, StringRef /*RelativePath*/,
+                          llvm::StringRef /*SearchPath*/,
+                          llvm::StringRef /*RelativePath*/,
                           const Module * /*Imported*/,
                           SrcMgr::CharacteristicKind FileKind) override {
     if (SM.isWrittenInMainFile(HashLoc)) {
@@ -65,13 +64,48 @@
 
 } // namespace
 
-bool isLiteralInclude(StringRef Include) {
+bool isLiteralInclude(llvm::StringRef Include) {
   return Include.startswith("<") || Include.startswith("\"");
 }
 
 bool HeaderFile::valid() const {
   return (Verbatim && isLiteralInclude(File)) ||
-         (!Verbatim && sys::path::is_absolute(File));
+         (!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>
@@ -80,9 +114,9 @@
   return llvm::make_unique<RecordHeaders>(SM, Out);
 }
 
-void IncludeStructure::recordInclude(StringRef IncludingName,
-                                     StringRef IncludedName,
-                                     StringRef IncludedRealName) {
+void IncludeStructure::recordInclude(llvm::StringRef IncludingName,
+                                     llvm::StringRef IncludedName,
+                                     llvm::StringRef IncludedRealName) {
   auto Child = fileIndex(IncludedName);
   if (!IncludedRealName.empty() && RealPathNames[Child].empty())
     RealPathNames[Child] = IncludedRealName;
@@ -90,19 +124,20 @@
   IncludeChildren[Parent].push_back(Child);
 }
 
-unsigned IncludeStructure::fileIndex(StringRef Name) {
+unsigned IncludeStructure::fileIndex(llvm::StringRef Name) {
   auto R = NameToIndex.try_emplace(Name, RealPathNames.size());
   if (R.second)
     RealPathNames.emplace_back();
   return R.first->getValue();
 }
 
-StringMap<unsigned> IncludeStructure::includeDepth(StringRef Root) const {
+llvm::StringMap<unsigned>
+IncludeStructure::includeDepth(llvm::StringRef Root) const {
   // Include depth 0 is the main file only.
-  StringMap<unsigned> Result;
+  llvm::StringMap<unsigned> Result;
   Result[Root] = 0;
   std::vector<unsigned> CurrentLevel;
-  DenseSet<unsigned> Seen;
+  llvm::DenseSet<unsigned> Seen;
   auto It = NameToIndex.find(Root);
   if (It != NameToIndex.end()) {
     CurrentLevel.push_back(It->second);
@@ -142,7 +177,7 @@
   assert(DeclaringHeader.valid() && InsertedHeader.valid());
   if (FileName == DeclaringHeader.File || FileName == InsertedHeader.File)
     return false;
-  auto Included = [&](StringRef Header) {
+  auto Included = [&](llvm::StringRef Header) {
     return IncludedHeaders.find(Header) != IncludedHeaders.end();
   };
   return !Included(DeclaringHeader.File) && !Included(InsertedHeader.File);
@@ -164,8 +199,9 @@
   return Suggested;
 }
 
-Optional<TextEdit> IncludeInserter::insert(StringRef VerbatimHeader) const {
-  Optional<TextEdit> Edit = None;
+llvm::Optional<TextEdit>
+IncludeInserter::insert(llvm::StringRef VerbatimHeader) const {
+  llvm::Optional<TextEdit> Edit = None;
   if (auto Insertion = Inserter.insert(VerbatimHeader.trim("\"<>"),
                                        VerbatimHeader.startswith("<")))
     Edit = replacementToEdit(Code, *Insertion);
diff --git a/clangd/Headers.h b/clangd/Headers.h
index 6f0eb80..e29f7f6 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/Index.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.
diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp
new file mode 100644
index 0000000..177d577
--- /dev/null
+++ b/clangd/IncludeFixer.cpp
@@ -0,0 +1,304 @@
+//===--- 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 "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/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/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 {
+  if (IndexRequestCount >= IndexRequestLimit)
+    return {}; // Avoid querying index too many times in a single parse.
+  switch (Info.getID()) {
+  case diag::err_incomplete_type:
+  case diag::err_incomplete_member_access:
+  case diag::err_incomplete_base_class:
+    // 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 {};
+  ++IndexRequestCount;
+  // FIXME: consider batching the requests for all diagnostics.
+  // FIXME: consider caching the lookup results.
+  LookupRequest Req;
+  Req.IDs.insert(*ID);
+  llvm::Optional<Symbol> Matched;
+  Index.lookup(Req, [&](const Symbol &Sym) {
+    if (Matched)
+      return;
+    Matched = Sym;
+  });
+
+  if (!Matched || Matched->IncludeHeaders.empty() || !Matched->Definition ||
+      Matched->CanonicalDeclaration.FileURI != Matched->Definition.FileURI)
+    return {};
+  return fixesForSymbols({*Matched});
+}
+
+std::vector<Fix>
+IncludeFixer::fixesForSymbols(llvm::ArrayRef<Symbol> Syms) const {
+  auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header)
+      -> llvm::Expected<std::pair<std::string, bool>> {
+    auto ResolvedDeclaring =
+        toHeaderFile(Sym.CanonicalDeclaration.FileURI, File);
+    if (!ResolvedDeclaring)
+      return ResolvedDeclaring.takeError();
+    auto ResolvedInserted = toHeaderFile(Header, File);
+    if (!ResolvedInserted)
+      return ResolvedInserted.takeError();
+    return std::make_pair(
+        Inserter->calculateIncludePath(*ResolvedDeclaring, *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}",
+             File, Inc, ToInclude.takeError());
+      }
+    }
+  }
+  return Fixes;
+}
+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();
+
+    // FIXME: support invalid scope before a type name. In the following
+    // example, namespace "clang::tidy::" hasn't been declared/imported.
+    //    namespace clang {
+    //    void f() {
+    //      tidy::Check c;
+    //      ~~~~
+    //      // or
+    //      clang::tidy::Check c;
+    //             ~~~~
+    //    }
+    //    }
+    // For both cases, the typo and the diagnostic are both on "tidy", and no
+    // diagnostic is generated for "Check". However, what we want to fix is
+    // "clang::tidy::Check".
+
+    // Extract the typed scope. This is not done lazily because `SS` can get
+    // out of scope and it's relatively cheap.
+    llvm::Optional<std::string> SpecifiedScope;
+    if (SS && SS->isNotEmpty()) { // "::" or "ns::"
+      if (auto *Nested = SS->getScopeRep()) {
+        if (Nested->getKind() == NestedNameSpecifier::Global)
+          SpecifiedScope = "";
+        else if (const auto *NS = Nested->getAsNamespace())
+          SpecifiedScope = printNamespaceScope(*NS);
+        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 TypoCorrection();
+      }
+    }
+    if (!SpecifiedScope && !S) // Give up if no scope available.
+      return TypoCorrection();
+
+    UnresolvedName Unresolved;
+    Unresolved.Name = Typo.getAsString();
+    Unresolved.Loc = Typo.getBeginLoc();
+
+    auto *Sem = SemaPtr; // Avoid capturing `this`.
+    Unresolved.GetScopes = [Sem, SpecifiedScope, S, LookupKind]() {
+      std::vector<std::string> Scopes;
+      if (SpecifiedScope) {
+        Scopes.push_back(*SpecifiedScope);
+      } else {
+        assert(S);
+        // No scope qualifier 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));
+      }
+      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;
+
+  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();
+  return fixesForSymbols(std::vector<Symbol>(Syms.begin(), Syms.end()));
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h
new file mode 100644
index 0000000..da292b5
--- /dev/null
+++ b/clangd/IncludeFixer.h
@@ -0,0 +1,87 @@
+//===--- 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 "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/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(llvm::ArrayRef<Symbol> 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;
+};
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H
diff --git a/clangd/JSONTransport.cpp b/clangd/JSONTransport.cpp
index 83ef49b..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"
@@ -11,66 +10,68 @@
 #include "Transport.h"
 #include "llvm/Support/Errno.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
-json::Object encodeError(Error E) {
+llvm::json::Object encodeError(llvm::Error E) {
   std::string Message;
   ErrorCode Code = ErrorCode::UnknownErrorCode;
-  if (Error Unhandled =
-          handleErrors(std::move(E), [&](const LSPError &L) -> Error {
+  if (llvm::Error Unhandled = llvm::handleErrors(
+          std::move(E), [&](const LSPError &L) -> llvm::Error {
             Message = L.Message;
             Code = L.Code;
-            return Error::success();
+            return llvm::Error::success();
           }))
-    Message = toString(std::move(Unhandled));
+    Message = llvm::toString(std::move(Unhandled));
 
-  return json::Object{
+  return llvm::json::Object{
       {"message", std::move(Message)},
       {"code", int64_t(Code)},
   };
 }
 
-Error decodeError(const json::Object &O) {
+llvm::Error decodeError(const llvm::json::Object &O) {
   std::string Msg = O.getString("message").getValueOr("Unspecified error");
   if (auto Code = O.getInteger("code"))
-    return make_error<LSPError>(std::move(Msg), ErrorCode(*Code));
-  return make_error<StringError>(std::move(Msg), inconvertibleErrorCode());
+    return llvm::make_error<LSPError>(std::move(Msg), ErrorCode(*Code));
+  return llvm::make_error<llvm::StringError>(std::move(Msg),
+                                             llvm::inconvertibleErrorCode());
 }
 
 class JSONTransport : public Transport {
 public:
-  JSONTransport(std::FILE *In, raw_ostream &Out, raw_ostream *InMirror,
-                bool Pretty, JSONStreamStyle Style)
-      : In(In), Out(Out), InMirror(InMirror ? *InMirror : nulls()),
+  JSONTransport(std::FILE *In, llvm::raw_ostream &Out,
+                llvm::raw_ostream *InMirror, bool Pretty, JSONStreamStyle Style)
+      : In(In), Out(Out), InMirror(InMirror ? *InMirror : llvm::nulls()),
         Pretty(Pretty), Style(Style) {}
 
-  void notify(StringRef Method, json::Value Params) override {
-    sendMessage(json::Object{
+  void notify(llvm::StringRef Method, llvm::json::Value Params) override {
+    sendMessage(llvm::json::Object{
         {"jsonrpc", "2.0"},
         {"method", Method},
         {"params", std::move(Params)},
     });
   }
-  void call(StringRef Method, json::Value Params, json::Value ID) override {
-    sendMessage(json::Object{
+  void call(llvm::StringRef Method, llvm::json::Value Params,
+            llvm::json::Value ID) override {
+    sendMessage(llvm::json::Object{
         {"jsonrpc", "2.0"},
         {"id", std::move(ID)},
         {"method", Method},
         {"params", std::move(Params)},
     });
   }
-  void reply(json::Value ID, Expected<json::Value> Result) override {
+  void reply(llvm::json::Value ID,
+             llvm::Expected<llvm::json::Value> Result) override {
     if (Result) {
-      sendMessage(json::Object{
+      sendMessage(llvm::json::Object{
           {"jsonrpc", "2.0"},
           {"id", std::move(ID)},
           {"result", std::move(*Result)},
       });
     } else {
-      sendMessage(json::Object{
+      sendMessage(llvm::json::Object{
           {"jsonrpc", "2.0"},
           {"id", std::move(ID)},
           {"error", encodeError(Result.takeError())},
@@ -78,33 +79,34 @@
     }
   }
 
-  Error loop(MessageHandler &Handler) override {
+  llvm::Error loop(MessageHandler &Handler) override {
     while (!feof(In)) {
       if (ferror(In))
-        return errorCodeToError(std::error_code(errno, std::system_category()));
+        return llvm::errorCodeToError(
+            std::error_code(errno, std::system_category()));
       if (auto JSON = readRawMessage()) {
-        if (auto Doc = json::parse(*JSON)) {
+        if (auto Doc = llvm::json::parse(*JSON)) {
           vlog(Pretty ? "<<< {0:2}\n" : "<<< {0}\n", *Doc);
           if (!handleMessage(std::move(*Doc), Handler))
-            return Error::success(); // we saw the "exit" notification.
+            return llvm::Error::success(); // we saw the "exit" notification.
         } else {
           // Parse error. Log the raw message.
           vlog("<<< {0}\n", *JSON);
-          elog("JSON parse error: {0}", toString(Doc.takeError()));
+          elog("JSON parse error: {0}", llvm::toString(Doc.takeError()));
         }
       }
     }
-    return errorCodeToError(std::make_error_code(std::errc::io_error));
+    return llvm::errorCodeToError(std::make_error_code(std::errc::io_error));
   }
 
 private:
   // Dispatches incoming message to Handler onNotify/onCall/onReply.
-  bool handleMessage(json::Value Message, MessageHandler &Handler);
+  bool handleMessage(llvm::json::Value Message, MessageHandler &Handler);
   // Writes outgoing message to Out stream.
-  void sendMessage(json::Value Message) {
+  void sendMessage(llvm::json::Value Message) {
     std::string S;
-    raw_string_ostream OS(S);
-    OS << formatv(Pretty ? "{0:2}" : "{0}", Message);
+    llvm::raw_string_ostream OS(S);
+    OS << llvm::formatv(Pretty ? "{0:2}" : "{0}", Message);
     OS.flush();
     Out << "Content-Length: " << S.size() << "\r\n\r\n" << S;
     Out.flush();
@@ -112,30 +114,31 @@
   }
 
   // Read raw string messages from input stream.
-  Optional<std::string> readRawMessage() {
+  llvm::Optional<std::string> readRawMessage() {
     return Style == JSONStreamStyle::Delimited ? readDelimitedMessage()
                                                : readStandardMessage();
   }
-  Optional<std::string> readDelimitedMessage();
-  Optional<std::string> readStandardMessage();
+  llvm::Optional<std::string> readDelimitedMessage();
+  llvm::Optional<std::string> readStandardMessage();
 
   std::FILE *In;
-  raw_ostream &Out;
-  raw_ostream &InMirror;
+  llvm::raw_ostream &Out;
+  llvm::raw_ostream &InMirror;
   bool Pretty;
   JSONStreamStyle Style;
 };
 
-bool JSONTransport::handleMessage(json::Value Message,
+bool JSONTransport::handleMessage(llvm::json::Value Message,
                                   MessageHandler &Handler) {
   // Message must be an object with "jsonrpc":"2.0".
   auto *Object = Message.getAsObject();
-  if (!Object || Object->getString("jsonrpc") != Optional<StringRef>("2.0")) {
+  if (!Object ||
+      Object->getString("jsonrpc") != llvm::Optional<llvm::StringRef>("2.0")) {
     elog("Not a JSON-RPC 2.0 message: {0:2}", Message);
     return false;
   }
   // ID may be any JSON value. If absent, this is a notification.
-  Optional<json::Value> ID;
+  llvm::Optional<llvm::json::Value> ID;
   if (auto *I = Object->get("id"))
     ID = std::move(*I);
   auto Method = Object->getString("method");
@@ -147,13 +150,13 @@
     if (auto *Err = Object->getObject("error"))
       return Handler.onReply(std::move(*ID), decodeError(*Err));
     // Result should be given, use null if not.
-    json::Value Result = nullptr;
+    llvm::json::Value Result = nullptr;
     if (auto *R = Object->get("result"))
       Result = std::move(*R);
     return Handler.onReply(std::move(*ID), std::move(Result));
   }
   // Params should be given, use null if not.
-  json::Value Params = nullptr;
+  llvm::json::Value Params = nullptr;
   if (auto *P = Object->get("params"))
     Params = std::move(*P);
 
@@ -172,7 +175,7 @@
   for (;;) {
     Out.resize(Size + BufSize);
     // Handle EINTR which is sent when a debugger attaches on some platforms.
-    if (!sys::RetryAfterSignal(nullptr, ::fgets, &Out[Size], BufSize, In))
+    if (!llvm::sys::RetryAfterSignal(nullptr, ::fgets, &Out[Size], BufSize, In))
       return false;
     clearerr(In);
     // If the line contained null bytes, anything after it (including \n) will
@@ -189,17 +192,17 @@
 // Returns None when:
 //  - ferror() or feof() are set.
 //  - Content-Length is missing or empty (protocol error)
-Optional<std::string> JSONTransport::readStandardMessage() {
+llvm::Optional<std::string> JSONTransport::readStandardMessage() {
   // A Language Server Protocol message starts with a set of HTTP headers,
   // delimited  by \r\n, and terminated by an empty line (\r\n).
   unsigned long long ContentLength = 0;
   std::string Line;
   while (true) {
     if (feof(In) || ferror(In) || !readLine(In, Line))
-      return None;
+      return llvm::None;
     InMirror << Line;
 
-    StringRef LineRef(Line);
+    llvm::StringRef LineRef(Line);
 
     // We allow comments in headers. Technically this isn't part
 
@@ -214,7 +217,7 @@
              "The previous value for this message ({0}) was ignored.",
              ContentLength);
       }
-      getAsUnsignedInteger(LineRef.trim(), 0, ContentLength);
+      llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength);
       continue;
     } else if (!LineRef.trim().empty()) {
       // It's another header, ignore it.
@@ -231,24 +234,24 @@
     elog("Refusing to read message with long Content-Length: {0}. "
          "Expect protocol errors",
          ContentLength);
-    return None;
+    return llvm::None;
   }
   if (ContentLength == 0) {
     log("Warning: Missing Content-Length header, or zero-length message.");
-    return None;
+    return llvm::None;
   }
 
   std::string JSON(ContentLength, '\0');
   for (size_t Pos = 0, Read; Pos < ContentLength; Pos += Read) {
     // Handle EINTR which is sent when a debugger attaches on some platforms.
-    Read = sys::RetryAfterSignal(0u, ::fread, &JSON[Pos], 1,
-                                 ContentLength - Pos, In);
+    Read = llvm::sys::RetryAfterSignal(0u, ::fread, &JSON[Pos], 1,
+                                       ContentLength - Pos, In);
     if (Read == 0) {
       elog("Input was aborted. Read only {0} bytes of expected {1}.", Pos,
            ContentLength);
-      return None;
+      return llvm::None;
     }
-    InMirror << StringRef(&JSON[Pos], Read);
+    InMirror << llvm::StringRef(&JSON[Pos], Read);
     clearerr(In); // If we're done, the error was transient. If we're not done,
                   // either it was transient or we'll see it again on retry.
     Pos += Read;
@@ -261,12 +264,12 @@
 // - lines starting with # are ignored.
 // This is a testing path, so favor simplicity over performance here.
 // When returning None, feof() or ferror() will be set.
-Optional<std::string> JSONTransport::readDelimitedMessage() {
+llvm::Optional<std::string> JSONTransport::readDelimitedMessage() {
   std::string JSON;
   std::string Line;
   while (readLine(In, Line)) {
     InMirror << Line;
-    auto LineRef = StringRef(Line).trim();
+    auto LineRef = llvm::StringRef(Line).trim();
     if (LineRef.startswith("#")) // comment
       continue;
 
@@ -279,15 +282,17 @@
 
   if (ferror(In)) {
     elog("Input error while reading message!");
-    return None;
+    return llvm::None;
   }
   return std::move(JSON); // Including at EOF
 }
 
 } // namespace
 
-std::unique_ptr<Transport> newJSONTransport(std::FILE *In, raw_ostream &Out,
-                                            raw_ostream *InMirror, bool Pretty,
+std::unique_ptr<Transport> newJSONTransport(std::FILE *In,
+                                            llvm::raw_ostream &Out,
+                                            llvm::raw_ostream *InMirror,
+                                            bool Pretty,
                                             JSONStreamStyle Style) {
   return llvm::make_unique<JSONTransport>(In, Out, InMirror, Pretty, Style);
 }
diff --git a/clangd/Logger.cpp b/clangd/Logger.cpp
index 6adf45d..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,7 +13,6 @@
 #include "llvm/Support/raw_ostream.h"
 #include <mutex>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -29,13 +27,14 @@
 
 LoggingSession::~LoggingSession() { L = nullptr; }
 
-void detail::log(Logger::Level Level, const formatv_object_base &Message) {
+void detail::log(Logger::Level Level,
+                 const llvm::formatv_object_base &Message) {
   if (L)
     L->log(Level, Message);
   else {
     static std::mutex Mu;
     std::lock_guard<std::mutex> Guard(Mu);
-    errs() << Message << "\n";
+    llvm::errs() << Message << "\n";
   }
 }
 
@@ -48,14 +47,14 @@
 }
 
 void StreamLogger::log(Logger::Level Level,
-                       const formatv_object_base &Message) {
+                       const llvm::formatv_object_base &Message) {
   if (Level < MinLevel)
     return;
-  sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
+  llvm::sys::TimePoint<> Timestamp = std::chrono::system_clock::now();
   trace::log(Message);
   std::lock_guard<std::mutex> Guard(StreamMutex);
-  Logs << formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level), Timestamp,
-                  Message);
+  Logs << llvm::formatv("{0}[{1:%H:%M:%S.%L}] {2}\n", indicator(Level),
+                        Timestamp, Message);
   Logs.flush();
 }
 
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 5507895..ef6f491 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -24,14 +23,14 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
 char LSPError::ID;
 
-URIForFile URIForFile::canonicalize(StringRef AbsPath, StringRef TUPath) {
-  assert(sys::path::is_absolute(AbsPath) && "the path is relative");
+URIForFile URIForFile::canonicalize(llvm::StringRef AbsPath,
+                                    llvm::StringRef TUPath) {
+  assert(llvm::sys::path::is_absolute(AbsPath) && "the path is relative");
   auto Resolved = URI::resolvePath(AbsPath, TUPath);
   if (!Resolved) {
     elog("URIForFile: failed to resolve path {0} with TU path {1}: "
@@ -42,14 +41,15 @@
   return URIForFile(std::move(*Resolved));
 }
 
-Expected<URIForFile> URIForFile::fromURI(const URI &U, StringRef HintPath) {
+llvm::Expected<URIForFile> URIForFile::fromURI(const URI &U,
+                                               llvm::StringRef HintPath) {
   auto Resolved = URI::resolve(U, HintPath);
   if (!Resolved)
     return Resolved.takeError();
   return URIForFile(std::move(*Resolved));
 }
 
-bool fromJSON(const json::Value &E, URIForFile &R) {
+bool fromJSON(const llvm::json::Value &E, URIForFile &R) {
   if (auto S = E.getAsString()) {
     auto Parsed = URI::parse(*S);
     if (!Parsed) {
@@ -73,89 +73,89 @@
   return false;
 }
 
-json::Value toJSON(const URIForFile &U) { return U.uri(); }
+llvm::json::Value toJSON(const URIForFile &U) { return U.uri(); }
 
-raw_ostream &operator<<(raw_ostream &OS, const URIForFile &U) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const URIForFile &U) {
   return OS << U.uri();
 }
 
-json::Value toJSON(const TextDocumentIdentifier &R) {
-  return json::Object{{"uri", R.uri}};
+llvm::json::Value toJSON(const TextDocumentIdentifier &R) {
+  return llvm::json::Object{{"uri", R.uri}};
 }
 
-bool fromJSON(const json::Value &Params, TextDocumentIdentifier &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, TextDocumentIdentifier &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("uri", R.uri);
 }
 
-bool fromJSON(const json::Value &Params, Position &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, Position &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("line", R.line) && O.map("character", R.character);
 }
 
-json::Value toJSON(const Position &P) {
-  return json::Object{
+llvm::json::Value toJSON(const Position &P) {
+  return llvm::json::Object{
       {"line", P.line},
       {"character", P.character},
   };
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Position &P) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Position &P) {
   return OS << P.line << ':' << P.character;
 }
 
-bool fromJSON(const json::Value &Params, Range &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, Range &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("start", R.start) && O.map("end", R.end);
 }
 
-json::Value toJSON(const Range &P) {
-  return json::Object{
+llvm::json::Value toJSON(const Range &P) {
+  return llvm::json::Object{
       {"start", P.start},
       {"end", P.end},
   };
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Range &R) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Range &R) {
   return OS << R.start << '-' << R.end;
 }
 
-json::Value toJSON(const Location &P) {
-  return json::Object{
+llvm::json::Value toJSON(const Location &P) {
+  return llvm::json::Object{
       {"uri", P.uri},
       {"range", P.range},
   };
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Location &L) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Location &L) {
   return OS << L.range << '@' << L.uri;
 }
 
-bool fromJSON(const json::Value &Params, TextDocumentItem &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, TextDocumentItem &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("uri", R.uri) && O.map("languageId", R.languageId) &&
          O.map("version", R.version) && O.map("text", R.text);
 }
 
-bool fromJSON(const json::Value &Params, TextEdit &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, TextEdit &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("range", R.range) && O.map("newText", R.newText);
 }
 
-json::Value toJSON(const TextEdit &P) {
-  return json::Object{
+llvm::json::Value toJSON(const TextEdit &P) {
+  return llvm::json::Object{
       {"range", P.range},
       {"newText", P.newText},
   };
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const TextEdit &TE) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TextEdit &TE) {
   OS << TE.range << " => \"";
-  printEscapedString(TE.newText, OS);
+  llvm::printEscapedString(TE.newText, OS);
   return OS << '"';
 }
 
-bool fromJSON(const json::Value &E, TraceLevel &Out) {
+bool fromJSON(const llvm::json::Value &E, TraceLevel &Out) {
   if (auto S = E.getAsString()) {
     if (*S == "off") {
       Out = TraceLevel::Off;
@@ -171,7 +171,7 @@
   return false;
 }
 
-bool fromJSON(const json::Value &E, SymbolKind &Out) {
+bool fromJSON(const llvm::json::Value &E, SymbolKind &Out) {
   if (auto T = E.getAsInteger()) {
     if (*T < static_cast<int>(SymbolKind::File) ||
         *T > static_cast<int>(SymbolKind::TypeParameter))
@@ -182,7 +182,7 @@
   return false;
 }
 
-bool fromJSON(const json::Value &E, SymbolKindBitset &Out) {
+bool fromJSON(const llvm::json::Value &E, SymbolKindBitset &Out) {
   if (auto *A = E.getAsArray()) {
     for (size_t I = 0; I < A->size(); ++I) {
       SymbolKind KindOut;
@@ -212,8 +212,8 @@
   }
 }
 
-bool fromJSON(const json::Value &Params, ClientCapabilities &R) {
-  const json::Object *O = Params.getAsObject();
+bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) {
+  const llvm::json::Object *O = Params.getAsObject();
   if (!O)
     return false;
   if (auto *TextDocument = O->getObject("textDocument")) {
@@ -260,8 +260,8 @@
   return true;
 }
 
-bool fromJSON(const json::Value &Params, InitializeParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, InitializeParams &R) {
+  llvm::json::ObjectMapper O(Params);
   if (!O)
     return false;
   // We deliberately don't fail if we can't parse individual fields.
@@ -275,24 +275,24 @@
   return true;
 }
 
-bool fromJSON(const json::Value &Params, DidOpenTextDocumentParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DidOpenTextDocumentParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument);
 }
 
-bool fromJSON(const json::Value &Params, DidCloseTextDocumentParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DidCloseTextDocumentParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument);
 }
 
-bool fromJSON(const json::Value &Params, DidChangeTextDocumentParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DidChangeTextDocumentParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("contentChanges", R.contentChanges) &&
          O.map("wantDiagnostics", R.wantDiagnostics);
 }
 
-bool fromJSON(const json::Value &E, FileChangeType &Out) {
+bool fromJSON(const llvm::json::Value &E, FileChangeType &Out) {
   if (auto T = E.getAsInteger()) {
     if (*T < static_cast<int>(FileChangeType::Created) ||
         *T > static_cast<int>(FileChangeType::Deleted))
@@ -303,61 +303,64 @@
   return false;
 }
 
-bool fromJSON(const json::Value &Params, FileEvent &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, FileEvent &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("uri", R.uri) && O.map("type", R.type);
 }
 
-bool fromJSON(const json::Value &Params, DidChangeWatchedFilesParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DidChangeWatchedFilesParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("changes", R.changes);
 }
 
-bool fromJSON(const json::Value &Params, TextDocumentContentChangeEvent &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params,
+              TextDocumentContentChangeEvent &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("range", R.range) && O.map("rangeLength", R.rangeLength) &&
          O.map("text", R.text);
 }
 
-bool fromJSON(const json::Value &Params, FormattingOptions &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, FormattingOptions &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("tabSize", R.tabSize) &&
          O.map("insertSpaces", R.insertSpaces);
 }
 
-json::Value toJSON(const FormattingOptions &P) {
-  return json::Object{
+llvm::json::Value toJSON(const FormattingOptions &P) {
+  return llvm::json::Object{
       {"tabSize", P.tabSize},
       {"insertSpaces", P.insertSpaces},
   };
 }
 
-bool fromJSON(const json::Value &Params, DocumentRangeFormattingParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params,
+              DocumentRangeFormattingParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("range", R.range) && O.map("options", R.options);
 }
 
-bool fromJSON(const json::Value &Params, DocumentOnTypeFormattingParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params,
+              DocumentOnTypeFormattingParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("position", R.position) && O.map("ch", R.ch) &&
          O.map("options", R.options);
 }
 
-bool fromJSON(const json::Value &Params, DocumentFormattingParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DocumentFormattingParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("options", R.options);
 }
 
-bool fromJSON(const json::Value &Params, DocumentSymbolParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, DocumentSymbolParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument);
 }
 
-json::Value toJSON(const Diagnostic &D) {
-  json::Object Diag{
+llvm::json::Value toJSON(const Diagnostic &D) {
+  llvm::json::Object Diag{
       {"range", D.range},
       {"severity", D.severity},
       {"message", D.message},
@@ -369,8 +372,8 @@
   return std::move(Diag);
 }
 
-bool fromJSON(const json::Value &Params, Diagnostic &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, Diagnostic &R) {
+  llvm::json::ObjectMapper O(Params);
   if (!O || !O.map("range", R.range) || !O.map("message", R.message))
     return false;
   O.map("severity", R.severity);
@@ -378,48 +381,51 @@
   return true;
 }
 
-bool fromJSON(const json::Value &Params, CodeActionContext &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, CodeActionContext &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("diagnostics", R.diagnostics);
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Diagnostic &D) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diagnostic &D) {
   OS << D.range << " [";
   switch (D.severity) {
-    case 1:
-      OS << "error";
-      break;
-    case 2:
-      OS << "warning";
-      break;
-    case 3:
-      OS << "note";
-      break;
-    case 4:
-      OS << "remark";
-      break;
-    default:
-      OS << "diagnostic";
-      break;
+  case 1:
+    OS << "error";
+    break;
+  case 2:
+    OS << "warning";
+    break;
+  case 3:
+    OS << "note";
+    break;
+  case 4:
+    OS << "remark";
+    break;
+  default:
+    OS << "diagnostic";
+    break;
   }
   return OS << '(' << D.severity << "): " << D.message << "]";
 }
 
-bool fromJSON(const json::Value &Params, CodeActionParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, CodeActionParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("range", R.range) && O.map("context", R.context);
 }
 
-bool fromJSON(const json::Value &Params, WorkspaceEdit &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, WorkspaceEdit &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("changes", R.changes);
 }
 
-const StringLiteral ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND =
+const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND =
     "clangd.applyFix";
-bool fromJSON(const json::Value &Params, ExecuteCommandParams &R) {
-  json::ObjectMapper O(Params);
+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))
     return false;
 
@@ -428,11 +434,13 @@
     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.
 }
 
-json::Value toJSON(const SymbolInformation &P) {
-  return json::Object{
+llvm::json::Value toJSON(const SymbolInformation &P) {
+  return llvm::json::Object{
       {"name", P.name},
       {"kind", static_cast<int>(P.kind)},
       {"location", P.location},
@@ -440,7 +448,8 @@
   };
 }
 
-raw_ostream &operator<<(raw_ostream &O, const SymbolInformation &SI) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
+                              const SymbolInformation &SI) {
   O << SI.containerName << "::" << SI.name << " - " << toJSON(SI);
   return O;
 }
@@ -451,31 +460,31 @@
 }
 
 llvm::json::Value toJSON(const SymbolDetails &P) {
-  json::Object result{{"name", llvm::json::Value(nullptr)},
-                      {"containerName", llvm::json::Value(nullptr)},
-                      {"usr", llvm::json::Value(nullptr)},
-                      {"id", 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 json::Value(std::move(result));
+  return llvm::json::Value(std::move(Result));
 }
 
 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
   if (!S.containerName.empty()) {
     O << S.containerName;
-    StringRef ContNameRef;
+    llvm::StringRef ContNameRef;
     if (!ContNameRef.endswith("::")) {
       O << " ";
     }
@@ -484,26 +493,29 @@
   return O;
 }
 
-bool fromJSON(const json::Value &Params, WorkspaceSymbolParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, WorkspaceSymbolParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("query", R.query);
 }
 
-json::Value toJSON(const Command &C) {
-  auto Cmd = json::Object{{"title", C.title}, {"command", C.command}};
+llvm::json::Value toJSON(const Command &C) {
+  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 StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
+const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
+const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor";
 
-json::Value toJSON(const CodeAction &CA) {
-  auto CodeAction = json::Object{{"title", CA.title}};
+llvm::json::Value toJSON(const CodeAction &CA) {
+  auto CodeAction = llvm::json::Object{{"title", CA.title}};
   if (CA.kind)
     CodeAction["kind"] = *CA.kind;
   if (CA.diagnostics)
-    CodeAction["diagnostics"] = json::Array(*CA.diagnostics);
+    CodeAction["diagnostics"] = llvm::json::Array(*CA.diagnostics);
   if (CA.edit)
     CodeAction["edit"] = *CA.edit;
   if (CA.command)
@@ -511,15 +523,15 @@
   return std::move(CodeAction);
 }
 
-raw_ostream &operator<<(raw_ostream &O, const DocumentSymbol &S) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S) {
   return O << S.name << " - " << toJSON(S);
 }
 
-json::Value toJSON(const DocumentSymbol &S) {
-  json::Object Result{{"name", S.name},
-                      {"kind", static_cast<int>(S.kind)},
-                      {"range", S.range},
-                      {"selectionRange", S.selectionRange}};
+llvm::json::Value toJSON(const DocumentSymbol &S) {
+  llvm::json::Object Result{{"name", S.name},
+                            {"kind", static_cast<int>(S.kind)},
+                            {"range", S.range},
+                            {"selectionRange", S.selectionRange}};
 
   if (!S.detail.empty())
     Result["detail"] = S.detail;
@@ -528,29 +540,63 @@
   if (S.deprecated)
     Result["deprecated"] = true;
   // Older gcc cannot compile 'return Result', even though it is legal.
-  return json::Value(std::move(Result));
+  return llvm::json::Value(std::move(Result));
 }
 
-json::Value toJSON(const WorkspaceEdit &WE) {
+llvm::json::Value toJSON(const WorkspaceEdit &WE) {
   if (!WE.changes)
-    return json::Object{};
-  json::Object FileChanges;
+    return llvm::json::Object{};
+  llvm::json::Object FileChanges;
   for (auto &Change : *WE.changes)
-    FileChanges[Change.first] = json::Array(Change.second);
-  return json::Object{{"changes", std::move(FileChanges)}};
+    FileChanges[Change.first] = llvm::json::Array(Change.second);
+  return llvm::json::Object{{"changes", std::move(FileChanges)}};
 }
 
-json::Value toJSON(const ApplyWorkspaceEditParams &Params) {
-  return json::Object{{"edit", Params.edit}};
+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);
 }
 
-bool fromJSON(const json::Value &Params, TextDocumentPositionParams &R) {
-  json::ObjectMapper O(Params);
+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}};
+}
+
+bool fromJSON(const llvm::json::Value &Params, TextDocumentPositionParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("position", R.position);
 }
 
-static StringRef toTextKind(MarkupKind Kind) {
+bool fromJSON(const llvm::json::Value &Params, CompletionContext &R) {
+  llvm::json::ObjectMapper O(Params);
+  if (!O)
+    return false;
+
+  int TriggerKind;
+  if (!O.map("triggerKind", TriggerKind))
+    return false;
+  R.triggerKind = static_cast<CompletionTriggerKind>(TriggerKind);
+
+  if (auto *TC = Params.getAsObject()->get("triggerCharacter"))
+    return fromJSON(*TC, R.triggerCharacter);
+  return true;
+}
+
+bool fromJSON(const llvm::json::Value &Params, CompletionParams &R) {
+  if (!fromJSON(Params, static_cast<TextDocumentPositionParams &>(R)))
+    return false;
+  if (auto *Context = Params.getAsObject()->get("context"))
+    return fromJSON(*Context, R.context);
+  return true;
+}
+
+static llvm::StringRef toTextKind(MarkupKind Kind) {
   switch (Kind) {
   case MarkupKind::PlainText:
     return "plaintext";
@@ -560,18 +606,18 @@
   llvm_unreachable("Invalid MarkupKind");
 }
 
-json::Value toJSON(const MarkupContent &MC) {
+llvm::json::Value toJSON(const MarkupContent &MC) {
   if (MC.value.empty())
     return nullptr;
 
-  return json::Object{
+  return llvm::json::Object{
       {"kind", toTextKind(MC.kind)},
       {"value", MC.value},
   };
 }
 
-json::Value toJSON(const Hover &H) {
-  json::Object Result{{"contents", toJSON(H.contents)}};
+llvm::json::Value toJSON(const Hover &H) {
+  llvm::json::Object Result{{"contents", toJSON(H.contents)}};
 
   if (H.range.hasValue())
     Result["range"] = toJSON(*H.range);
@@ -579,7 +625,7 @@
   return std::move(Result);
 }
 
-bool fromJSON(const json::Value &E, CompletionItemKind &Out) {
+bool fromJSON(const llvm::json::Value &E, CompletionItemKind &Out) {
   if (auto T = E.getAsInteger()) {
     if (*T < static_cast<int>(CompletionItemKind::Text) ||
         *T > static_cast<int>(CompletionItemKind::TypeParameter))
@@ -592,11 +638,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) {
@@ -612,7 +658,7 @@
   }
 }
 
-bool fromJSON(const json::Value &E, CompletionItemKindBitset &Out) {
+bool fromJSON(const llvm::json::Value &E, CompletionItemKindBitset &Out) {
   if (auto *A = E.getAsArray()) {
     for (size_t I = 0; I < A->size(); ++I) {
       CompletionItemKind KindOut;
@@ -624,9 +670,9 @@
   return false;
 }
 
-json::Value toJSON(const CompletionItem &CI) {
+llvm::json::Value toJSON(const CompletionItem &CI) {
   assert(!CI.label.empty() && "completion item label is required");
-  json::Object Result{{"label", CI.label}};
+  llvm::json::Object Result{{"label", CI.label}};
   if (CI.kind != CompletionItemKind::Missing)
     Result["kind"] = static_cast<int>(CI.kind);
   if (!CI.detail.empty())
@@ -644,13 +690,13 @@
   if (CI.textEdit)
     Result["textEdit"] = *CI.textEdit;
   if (!CI.additionalTextEdits.empty())
-    Result["additionalTextEdits"] = json::Array(CI.additionalTextEdits);
+    Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits);
   if (CI.deprecated)
     Result["deprecated"] = CI.deprecated;
   return std::move(Result);
 }
 
-raw_ostream &operator<<(raw_ostream &O, const CompletionItem &I) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const CompletionItem &I) {
   O << I.label << " - " << toJSON(I);
   return O;
 }
@@ -660,63 +706,72 @@
          (R.sortText.empty() ? R.label : R.sortText);
 }
 
-json::Value toJSON(const CompletionList &L) {
-  return json::Object{
+llvm::json::Value toJSON(const CompletionList &L) {
+  return llvm::json::Object{
       {"isIncomplete", L.isIncomplete},
-      {"items", json::Array(L.items)},
+      {"items", llvm::json::Array(L.items)},
   };
 }
 
-json::Value toJSON(const ParameterInformation &PI) {
+llvm::json::Value toJSON(const ParameterInformation &PI) {
   assert(!PI.label.empty() && "parameter information label is required");
-  json::Object Result{{"label", PI.label}};
+  llvm::json::Object Result{{"label", PI.label}};
   if (!PI.documentation.empty())
     Result["documentation"] = PI.documentation;
   return std::move(Result);
 }
 
-json::Value toJSON(const SignatureInformation &SI) {
+llvm::json::Value toJSON(const SignatureInformation &SI) {
   assert(!SI.label.empty() && "signature information label is required");
-  json::Object Result{
+  llvm::json::Object Result{
       {"label", SI.label},
-      {"parameters", json::Array(SI.parameters)},
+      {"parameters", llvm::json::Array(SI.parameters)},
   };
   if (!SI.documentation.empty())
     Result["documentation"] = SI.documentation;
   return std::move(Result);
 }
 
-raw_ostream &operator<<(raw_ostream &O, const SignatureInformation &I) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
+                              const SignatureInformation &I) {
   O << I.label << " - " << toJSON(I);
   return O;
 }
 
-json::Value toJSON(const SignatureHelp &SH) {
+llvm::json::Value toJSON(const SignatureHelp &SH) {
   assert(SH.activeSignature >= 0 &&
          "Unexpected negative value for number of active signatures.");
   assert(SH.activeParameter >= 0 &&
          "Unexpected negative value for active parameter index");
-  return json::Object{
+  return llvm::json::Object{
       {"activeSignature", SH.activeSignature},
       {"activeParameter", SH.activeParameter},
-      {"signatures", json::Array(SH.signatures)},
+      {"signatures", llvm::json::Array(SH.signatures)},
   };
 }
 
-bool fromJSON(const json::Value &Params, RenameParams &R) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, RenameParams &R) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("textDocument", R.textDocument) &&
          O.map("position", R.position) && O.map("newName", R.newName);
 }
 
-json::Value toJSON(const DocumentHighlight &DH) {
-  return json::Object{
+llvm::json::Value toJSON(const DocumentHighlight &DH) {
+  return llvm::json::Object{
       {"range", toJSON(DH.range)},
       {"kind", static_cast<int>(DH.kind)},
   };
 }
 
-raw_ostream &operator<<(raw_ostream &O, const DocumentHighlight &V) {
+llvm::json::Value toJSON(const FileStatus &FStatus) {
+  return llvm::json::Object{
+      {"uri", FStatus.uri},
+      {"state", FStatus.state},
+  };
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
+                              const DocumentHighlight &V) {
   O << V.range;
   if (V.kind == DocumentHighlightKind::Read)
     O << "(r)";
@@ -725,37 +780,40 @@
   return O;
 }
 
-bool fromJSON(const json::Value &Params, DidChangeConfigurationParams &CCP) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params,
+              DidChangeConfigurationParams &CCP) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("settings", CCP.settings);
 }
 
-bool fromJSON(const json::Value &Params, ClangdCompileCommand &CDbUpdate) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params,
+              ClangdCompileCommand &CDbUpdate) {
+  llvm::json::ObjectMapper O(Params);
   return O && O.map("workingDirectory", CDbUpdate.workingDirectory) &&
          O.map("compilationCommand", CDbUpdate.compilationCommand);
 }
 
-bool fromJSON(const json::Value &Params, ConfigurationSettings &S) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, ConfigurationSettings &S) {
+  llvm::json::ObjectMapper O(Params);
   if (!O)
     return true; // 'any' type in LSP.
   O.map("compilationDatabaseChanges", S.compilationDatabaseChanges);
   return true;
 }
 
-bool fromJSON(const json::Value &Params, InitializationOptions &Opts) {
-  json::ObjectMapper O(Params);
+bool fromJSON(const llvm::json::Value &Params, InitializationOptions &Opts) {
+  llvm::json::ObjectMapper O(Params);
   if (!O)
     return true; // 'any' type in LSP.
 
   fromJSON(Params, Opts.ConfigSettings);
   O.map("compilationDatabasePath", Opts.compilationDatabasePath);
   O.map("fallbackFlags", Opts.fallbackFlags);
+  O.map("clangdFileStatus", Opts.FileStatus);
   return true;
 }
 
-bool fromJSON(const json::Value &Params, ReferenceParams &R) {
+bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R) {
   TextDocumentPositionParams &Base = R;
   return fromJSON(Params, Base);
 }
diff --git a/clangd/Protocol.h b/clangd/Protocol.h
index 76dcf52..95a6671 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -397,6 +396,9 @@
   // the compilation database doesn't describe an opened file.
   // The command used will be approximately `clang $FILE $fallbackFlags`.
   std::vector<std::string> fallbackFlags;
+
+  /// Clients supports show file status for textDocument/clangd.fileStatus.
+  bool FileStatus = false;
 };
 bool fromJSON(const llvm::json::Value &, InitializationOptions &);
 
@@ -629,6 +631,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
@@ -640,12 +657,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 &);
 
@@ -667,6 +687,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;
@@ -772,6 +793,31 @@
 };
 bool fromJSON(const llvm::json::Value &, TextDocumentPositionParams &);
 
+enum class CompletionTriggerKind {
+  /// Completion was triggered by typing an identifier (24x7 code
+  /// complete), manual invocation (e.g Ctrl+Space) or via API.
+  Invoked = 1,
+  /// Completion was triggered by a trigger character specified by
+  /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+  TriggerCharacter = 2,
+  /// Completion was re-triggered as the current completion list is incomplete.
+  TriggerTriggerForIncompleteCompletions = 3
+};
+
+struct CompletionContext {
+  /// How the completion was triggered.
+  CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
+  /// The trigger character (a single character) that has trigger code complete.
+  /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+  std::string triggerCharacter;
+};
+bool fromJSON(const llvm::json::Value &, CompletionContext &);
+
+struct CompletionParams : TextDocumentPositionParams {
+  CompletionContext context;
+};
+bool fromJSON(const llvm::json::Value &, CompletionParams &);
+
 enum class MarkupKind {
   PlainText,
   Markdown,
@@ -973,6 +1019,18 @@
 };
 bool fromJSON(const llvm::json::Value &, ReferenceParams &);
 
+/// Clangd extension: indicates the current state of the file in clangd,
+/// sent from server via the `textDocument/clangd.fileStatus` notification.
+struct FileStatus {
+  /// The text document's URI.
+  URIForFile uri;
+  /// The human-readable string presents the current state of the file, can be
+  /// shown in the UI (e.g. status bar).
+  std::string state;
+  // FIXME: add detail messages.
+};
+llvm::json::Value toJSON(const FileStatus &FStatus);
+
 } // namespace clangd
 } // namespace clang
 
diff --git a/clangd/Quality.cpp b/clangd/Quality.cpp
index fe7a969..50e3f7e 100644
--- a/clangd/Quality.cpp
+++ b/clangd/Quality.cpp
@@ -1,9 +1,8 @@
 //===--- 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"
@@ -31,10 +30,9 @@
 #include <algorithm>
 #include <cmath>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
-static bool isReserved(StringRef Name) {
+static bool isReserved(llvm::StringRef Name) {
   // FIXME: Should we exclude _Bool and others recognized by the standard?
   return Name.size() >= 2 && Name[0] == '_' &&
          (isUppercase(Name[1]) || Name[1] == '_');
@@ -249,12 +247,13 @@
   return Score;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const SymbolQualitySignals &S) {
-  OS << formatv("=== Symbol quality: {0}\n", S.evaluate());
-  OS << formatv("\tReferences: {0}\n", S.References);
-  OS << formatv("\tDeprecated: {0}\n", S.Deprecated);
-  OS << formatv("\tReserved name: {0}\n", S.ReservedName);
-  OS << formatv("\tCategory: {0}\n", static_cast<int>(S.Category));
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const SymbolQualitySignals &S) {
+  OS << llvm::formatv("=== Symbol quality: {0}\n", S.evaluate());
+  OS << llvm::formatv("\tReferences: {0}\n", S.References);
+  OS << llvm::formatv("\tDeprecated: {0}\n", S.Deprecated);
+  OS << llvm::formatv("\tReserved name: {0}\n", S.ReservedName);
+  OS << llvm::formatv("\tCategory: {0}\n", static_cast<int>(S.Category));
   return OS;
 }
 
@@ -283,12 +282,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) {
@@ -317,7 +316,7 @@
   NeedsFixIts = !SemaCCResult.FixIts.empty();
 }
 
-static std::pair<float, unsigned> uriProximity(StringRef SymbolURI,
+static std::pair<float, unsigned> uriProximity(llvm::StringRef SymbolURI,
                                                URIDistance *D) {
   if (!D || SymbolURI.empty())
     return {0.f, 0u};
@@ -327,7 +326,7 @@
 }
 
 static float scopeBoost(ScopeDistance &Distance,
-                        Optional<StringRef> SymbolScope) {
+                        llvm::Optional<llvm::StringRef> SymbolScope) {
   if (!SymbolScope)
     return 1;
   auto D = Distance.distance(*SymbolScope);
@@ -366,7 +365,7 @@
     case GlobalScope:
       break;
     case FileScope:
-      Score *= 1.5;
+      Score *= 1.5f;
       break;
     case ClassScope:
       Score *= 2;
@@ -375,6 +374,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)
@@ -397,33 +409,34 @@
   return Score;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const SymbolRelevanceSignals &S) {
-  OS << formatv("=== Symbol relevance: {0}\n", S.evaluate());
-  OS << formatv("\tName match: {0}\n", S.NameMatch);
-  OS << formatv("\tForbidden: {0}\n", S.Forbidden);
-  OS << formatv("\tNeedsFixIts: {0}\n", S.NeedsFixIts);
-  OS << formatv("\tIsInstanceMember: {0}\n", S.IsInstanceMember);
-  OS << formatv("\tContext: {0}\n", getCompletionKindString(S.Context));
-  OS << formatv("\tQuery type: {0}\n", static_cast<int>(S.Query));
-  OS << formatv("\tScope: {0}\n", static_cast<int>(S.Scope));
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const SymbolRelevanceSignals &S) {
+  OS << llvm::formatv("=== Symbol relevance: {0}\n", S.evaluate());
+  OS << llvm::formatv("\tName match: {0}\n", S.NameMatch);
+  OS << llvm::formatv("\tForbidden: {0}\n", S.Forbidden);
+  OS << llvm::formatv("\tNeedsFixIts: {0}\n", S.NeedsFixIts);
+  OS << llvm::formatv("\tIsInstanceMember: {0}\n", S.IsInstanceMember);
+  OS << llvm::formatv("\tContext: {0}\n", getCompletionKindString(S.Context));
+  OS << llvm::formatv("\tQuery type: {0}\n", static_cast<int>(S.Query));
+  OS << llvm::formatv("\tScope: {0}\n", static_cast<int>(S.Scope));
 
-  OS << formatv("\tSymbol URI: {0}\n", S.SymbolURI);
-  OS << formatv("\tSymbol scope: {0}\n",
-                S.SymbolScope ? *S.SymbolScope : "<None>");
+  OS << llvm::formatv("\tSymbol URI: {0}\n", S.SymbolURI);
+  OS << llvm::formatv("\tSymbol scope: {0}\n",
+                      S.SymbolScope ? *S.SymbolScope : "<None>");
 
   if (S.FileProximityMatch) {
     auto Score = uriProximity(S.SymbolURI, S.FileProximityMatch);
-    OS << formatv("\tIndex URI proximity: {0} (distance={1})\n", Score.first,
-                  Score.second);
+    OS << llvm::formatv("\tIndex URI proximity: {0} (distance={1})\n",
+                        Score.first, Score.second);
   }
-  OS << formatv("\tSema file proximity: {0}\n", S.SemaFileProximityScore);
+  OS << llvm::formatv("\tSema file proximity: {0}\n", S.SemaFileProximityScore);
 
-  OS << formatv("\tSema says in scope: {0}\n", S.SemaSaysInScope);
+  OS << llvm::formatv("\tSema says in scope: {0}\n", S.SemaSaysInScope);
   if (S.ScopeProximityMatch)
-    OS << formatv("\tIndex scope boost: {0}\n",
-                  scopeBoost(*S.ScopeProximityMatch, S.SymbolScope));
+    OS << llvm::formatv("\tIndex scope boost: {0}\n",
+                        scopeBoost(*S.ScopeProximityMatch, S.SymbolScope));
 
-  OS << formatv(
+  OS << llvm::formatv(
       "\tType matched preferred: {0} (Context type: {1}, Symbol type: {2}\n",
       S.TypeMatchesPreferred, S.HadContextType, S.HadSymbolType);
 
@@ -441,33 +454,34 @@
   constexpr uint32_t TopBit = ~(~uint32_t{0} >> 1);
 
   // Get the bits of the float. Endianness is the same as for integers.
-  uint32_t U = FloatToBits(F);
+  uint32_t U = llvm::FloatToBits(F);
   // IEEE 754 floats compare like sign-magnitude integers.
   if (U & TopBit)    // Negative float.
     return 0 - U;    // Map onto the low half of integers, order reversed.
   return U + TopBit; // Positive floats map onto the high half of integers.
 }
 
-std::string sortText(float Score, StringRef Name) {
+std::string sortText(float Score, llvm::StringRef Name) {
   // We convert -Score to an integer, and hex-encode for readability.
   // Example: [0.5, "foo"] -> "41000000foo"
   std::string S;
-  raw_string_ostream OS(S);
-  write_hex(OS, encodeFloat(-Score), HexPrintStyle::Lower,
-            /*Width=*/2 * sizeof(Score));
+  llvm::raw_string_ostream OS(S);
+  llvm::write_hex(OS, encodeFloat(-Score), llvm::HexPrintStyle::Lower,
+                  /*Width=*/2 * sizeof(Score));
   OS << Name;
   OS.flush();
   return S;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const SignatureQualitySignals &S) {
-  OS << formatv("=== Signature Quality:\n");
-  OS << formatv("\tNumber of parameters: {0}\n", S.NumberOfParameters);
-  OS << formatv("\tNumber of optional parameters: {0}\n",
-                S.NumberOfOptionalParameters);
-  OS << formatv("\tContains active parameter: {0}\n",
-                S.ContainsActiveParameter);
-  OS << formatv("\tKind: {0}\n", S.Kind);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const SignatureQualitySignals &S) {
+  OS << llvm::formatv("=== Signature Quality:\n");
+  OS << llvm::formatv("\tNumber of parameters: {0}\n", S.NumberOfParameters);
+  OS << llvm::formatv("\tNumber of optional parameters: {0}\n",
+                      S.NumberOfOptionalParameters);
+  OS << llvm::formatv("\tContains active parameter: {0}\n",
+                      S.ContainsActiveParameter);
+  OS << llvm::formatv("\tKind: {0}\n", S.Kind);
   return OS;
 }
 
diff --git a/clangd/Quality.h b/clangd/Quality.h
index 9cb0c2f..5eea7db 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
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/clangd/RIFF.cpp b/clangd/RIFF.cpp
index 19722b6..cdbae4f 100644
--- a/clangd/RIFF.cpp
+++ b/clangd/RIFF.cpp
@@ -1,31 +1,29 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
 #include "RIFF.h"
 #include "llvm/Support/Endian.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace riff {
 
-static Error makeError(const char *Msg) {
-  return createStringError(inconvertibleErrorCode(), Msg);
+static llvm::Error makeError(const char *Msg) {
+  return llvm::createStringError(llvm::inconvertibleErrorCode(), Msg);
 }
 
-Expected<Chunk> readChunk(StringRef &Stream) {
+llvm::Expected<Chunk> readChunk(llvm::StringRef &Stream) {
   if (Stream.size() < 8)
     return makeError("incomplete chunk header");
   Chunk C;
   std::copy(Stream.begin(), Stream.begin() + 4, C.ID.begin());
   Stream = Stream.drop_front(4);
-  uint32_t Len = support::endian::read32le(Stream.take_front(4).begin());
+  uint32_t Len = llvm::support::endian::read32le(Stream.take_front(4).begin());
   Stream = Stream.drop_front(4);
   if (Stream.size() < Len)
     return makeError("truncated chunk");
@@ -39,10 +37,10 @@
   return std::move(C);
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Chunk &C) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Chunk &C) {
   OS.write(C.ID.data(), C.ID.size());
   char Size[4];
-  support::endian::write32le(Size, C.Data.size());
+  llvm::support::endian::write32le(Size, C.Data.size());
   OS.write(Size, sizeof(Size));
   OS << C.Data;
   if (C.Data.size() % 2)
@@ -50,7 +48,7 @@
   return OS;
 }
 
-Expected<File> readFile(StringRef Stream) {
+llvm::Expected<File> readFile(llvm::StringRef Stream) {
   auto RIFF = readChunk(Stream);
   if (!RIFF)
     return RIFF.takeError();
@@ -60,7 +58,7 @@
     return makeError("RIFF chunk too short");
   File F;
   std::copy(RIFF->Data.begin(), RIFF->Data.begin() + 4, F.Type.begin());
-  for (StringRef Body = RIFF->Data.drop_front(4); !Body.empty();)
+  for (llvm::StringRef Body = RIFF->Data.drop_front(4); !Body.empty();)
     if (auto Chunk = readChunk(Body)) {
       F.Chunks.push_back(*Chunk);
     } else
@@ -68,14 +66,14 @@
   return std::move(F);
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const File &F) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const File &F) {
   // To avoid copies, we serialize the outer RIFF chunk "by hand".
   size_t DataLen = 4; // Predict length of RIFF chunk data.
   for (const auto &C : F.Chunks)
     DataLen += 4 + 4 + C.Data.size() + (C.Data.size() % 2);
   OS << "RIFF";
   char Size[4];
-  support::endian::write32le(Size, DataLen);
+  llvm::support::endian::write32le(Size, DataLen);
   OS.write(Size, sizeof(Size));
   OS.write(F.Type.data(), F.Type.size());
   for (const auto &C : F.Chunks)
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..d1ea30e
--- /dev/null
+++ b/clangd/Selection.cpp
@@ -0,0 +1,301 @@
+//===--- 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;
+      assert(R.isTokenRange());
+      // 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
+        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 4d276ef..8614675 100644
--- a/clangd/SourceCode.cpp
+++ b/clangd/SourceCode.cpp
@@ -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
 //
 //===----------------------------------------------------------------------===//
 #include "SourceCode.h"
@@ -12,11 +11,12 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -27,7 +27,7 @@
 // invokes CB(UTF-8 length, UTF-16 length), and breaks if it returns true.
 // Returns true if CB returned true, false if we hit the end of string.
 template <typename Callback>
-static bool iterateCodepoints(StringRef U8, const Callback &CB) {
+static bool iterateCodepoints(llvm::StringRef U8, const Callback &CB) {
   for (size_t I = 0; I < U8.size();) {
     unsigned char C = static_cast<unsigned char>(U8[I]);
     if (LLVM_LIKELY(!(C & 0x80))) { // ASCII character.
@@ -37,7 +37,7 @@
       continue;
     }
     // This convenient property of UTF-8 holds for all non-ASCII characters.
-    size_t UTF8Length = countLeadingOnes(C);
+    size_t UTF8Length = llvm::countLeadingOnes(C);
     // 0xxx is ASCII, handled above. 10xxx is a trailing byte, invalid here.
     // 11111xxx is not valid UTF-8 at all. Assert because it's probably our bug.
     assert((UTF8Length >= 2 && UTF8Length <= 4) &&
@@ -54,7 +54,7 @@
 // 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(StringRef U8, int U16Units, bool &Valid) {
+static size_t measureUTF16(llvm::StringRef U8, int U16Units, bool &Valid) {
   size_t Result = 0;
   Valid = U16Units == 0 || iterateCodepoints(U8, [&](int U8Len, int U16Len) {
             Result += U8Len;
@@ -68,7 +68,7 @@
 }
 
 // Like most strings in clangd, the input is UTF-8 encoded.
-size_t lspLength(StringRef Code) {
+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;
@@ -79,47 +79,47 @@
   return Count;
 }
 
-Expected<size_t> positionToOffset(StringRef Code, Position P,
-                                  bool AllowColumnsBeyondLineLength) {
+llvm::Expected<size_t> positionToOffset(llvm::StringRef Code, Position P,
+                                        bool AllowColumnsBeyondLineLength) {
   if (P.line < 0)
-    return make_error<StringError>(
-        formatv("Line value can't be negative ({0})", P.line),
-        errc::invalid_argument);
+    return llvm::make_error<llvm::StringError>(
+        llvm::formatv("Line value can't be negative ({0})", P.line),
+        llvm::errc::invalid_argument);
   if (P.character < 0)
-    return make_error<StringError>(
-        formatv("Character value can't be negative ({0})", P.character),
-        errc::invalid_argument);
+    return llvm::make_error<llvm::StringError>(
+        llvm::formatv("Character value can't be negative ({0})", P.character),
+        llvm::errc::invalid_argument);
   size_t StartOfLine = 0;
   for (int I = 0; I != P.line; ++I) {
     size_t NextNL = Code.find('\n', StartOfLine);
-    if (NextNL == StringRef::npos)
-      return make_error<StringError>(
-          formatv("Line value is out of range ({0})", P.line),
-          errc::invalid_argument);
+    if (NextNL == llvm::StringRef::npos)
+      return llvm::make_error<llvm::StringError>(
+          llvm::formatv("Line value is out of range ({0})", P.line),
+          llvm::errc::invalid_argument);
     StartOfLine = NextNL + 1;
   }
 
   size_t NextNL = Code.find('\n', StartOfLine);
-  if (NextNL == StringRef::npos)
+  if (NextNL == llvm::StringRef::npos)
     NextNL = Code.size();
 
   bool Valid;
   size_t ByteOffsetInLine = measureUTF16(
       Code.substr(StartOfLine, NextNL - StartOfLine), P.character, Valid);
   if (!Valid && !AllowColumnsBeyondLineLength)
-    return make_error<StringError>(
-        formatv("UTF-16 offset {0} is invalid for line {1}", P.character,
-                P.line),
-        errc::invalid_argument);
+    return llvm::make_error<llvm::StringError>(
+        llvm::formatv("UTF-16 offset {0} is invalid for line {1}", P.character,
+                      P.line),
+        llvm::errc::invalid_argument);
   return StartOfLine + ByteOffsetInLine;
 }
 
-Position offsetToPosition(StringRef Code, size_t Offset) {
+Position offsetToPosition(llvm::StringRef Code, size_t Offset) {
   Offset = std::min(Code.size(), Offset);
-  StringRef Before = Code.substr(0, Offset);
+  llvm::StringRef Before = Code.substr(0, Offset);
   int Lines = Before.count('\n');
   size_t PrevNL = Before.rfind('\n');
-  size_t StartOfLine = (PrevNL == StringRef::npos) ? 0 : (PrevNL + 1);
+  size_t StartOfLine = (PrevNL == llvm::StringRef::npos) ? 0 : (PrevNL + 1);
   Position Pos;
   Pos.line = Lines;
   Pos.character = lspLength(Before.substr(StartOfLine));
@@ -134,7 +134,7 @@
   Position P;
   P.line = static_cast<int>(SM.getLineNumber(FID, Offset)) - 1;
   bool Invalid = false;
-  StringRef Code = SM.getBufferData(FID, &Invalid);
+  llvm::StringRef Code = SM.getBufferData(FID, &Invalid);
   if (!Invalid) {
     auto ColumnInBytes = SM.getColumnNumber(FID, Offset) - 1;
     auto LineSoFar = Code.substr(Offset - ColumnInBytes, ColumnInBytes);
@@ -143,6 +143,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());
@@ -151,31 +224,32 @@
   return {Begin, End};
 }
 
-std::pair<size_t, size_t> offsetToClangLineColumn(StringRef Code,
+std::pair<size_t, size_t> offsetToClangLineColumn(llvm::StringRef Code,
                                                   size_t Offset) {
   Offset = std::min(Code.size(), Offset);
-  StringRef Before = Code.substr(0, Offset);
+  llvm::StringRef Before = Code.substr(0, Offset);
   int Lines = Before.count('\n');
   size_t PrevNL = Before.rfind('\n');
-  size_t StartOfLine = (PrevNL == StringRef::npos) ? 0 : (PrevNL + 1);
+  size_t StartOfLine = (PrevNL == llvm::StringRef::npos) ? 0 : (PrevNL + 1);
   return {Lines + 1, Offset - StartOfLine + 1};
 }
 
 std::pair<StringRef, StringRef> splitQualifiedName(StringRef QName) {
   size_t Pos = QName.rfind("::");
-  if (Pos == StringRef::npos)
-    return {StringRef(), QName};
+  if (Pos == llvm::StringRef::npos)
+    return {llvm::StringRef(), QName};
   return {QName.substr(0, Pos + 2), QName.substr(Pos + 2)};
 }
 
-TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R) {
+TextEdit replacementToEdit(llvm::StringRef Code,
+                           const tooling::Replacement &R) {
   Range ReplacementRange = {
       offsetToPosition(Code, R.getOffset()),
       offsetToPosition(Code, R.getOffset() + R.getLength())};
   return {ReplacementRange, R.getReplacementText()};
 }
 
-std::vector<TextEdit> replacementsToEdits(StringRef Code,
+std::vector<TextEdit> replacementsToEdits(llvm::StringRef Code,
                                           const tooling::Replacements &Repls) {
   std::vector<TextEdit> Edits;
   for (const auto &R : Repls)
@@ -183,34 +257,43 @@
   return Edits;
 }
 
-Optional<std::string> getRealPath(const FileEntry *F,
-                                  const SourceManager &SourceMgr) {
-  // Ideally, we get the real path from the FileEntry object.
-  SmallString<128> FilePath = F->tryGetRealPathName();
-  if (!FilePath.empty()) {
-    return FilePath.str().str();
-  }
+llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
+                                             const SourceManager &SourceMgr) {
+  if (!F)
+    return None;
 
-  // Otherwise, we try to compute ourselves.
-  vlog("FileEntry for {0} did not contain the real path.", F->getName());
-
-  SmallString<128> Path = F->getName();
-
-  if (!sys::path::is_absolute(Path)) {
-    if (!SourceMgr.getFileManager().makeAbsolutePath(Path)) {
-      log("Could not turn relative path to absolute: {0}", Path);
+  llvm::SmallString<128> FilePath = F->getName();
+  if (!llvm::sys::path::is_absolute(FilePath)) {
+    if (auto EC =
+            SourceMgr.getFileManager().getVirtualFileSystem()->makeAbsolute(
+                FilePath)) {
+      elog("Could not turn relative path '{0}' to absolute: {1}", FilePath,
+           EC.message());
       return None;
     }
   }
 
-  SmallString<128> RealPath;
-  if (SourceMgr.getFileManager().getVirtualFileSystem()->getRealPath(
-          Path, RealPath)) {
-    log("Could not compute real path: {0}", Path);
-    return Path.str().str();
+  // Handle the symbolic link path case where the current working directory
+  // (getCurrentWorkingDirectory) is a symlink./ We always want to the real
+  // file path (instead of the symlink path) for the  C++ symbols.
+  //
+  // Consider the following example:
+  //
+  //   src dir: /project/src/foo.h
+  //   current working directory (symlink): /tmp/build -> /project/src/
+  //
+  //  The file path of Symbol is "/project/src/foo.h" instead of
+  //  "/tmp/build/foo.h"
+  if (const DirectoryEntry *Dir = SourceMgr.getFileManager().getDirectory(
+          llvm::sys::path::parent_path(FilePath))) {
+    llvm::SmallString<128> RealPath;
+    llvm::StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
+    llvm::sys::path::append(RealPath, DirName,
+                            llvm::sys::path::filename(FilePath));
+    return RealPath.str().str();
   }
 
-  return RealPath.str().str();
+  return FilePath.str().str();
 }
 
 TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M,
@@ -222,22 +305,44 @@
   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;
 }
 
-FileDigest digest(StringRef Content) {
+FileDigest digest(llvm::StringRef Content) {
   return llvm::SHA1::hash({(const uint8_t *)Content.data(), Content.size()});
 }
 
-Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {
+llvm::Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {
   bool Invalid = false;
-  StringRef Content = SM.getBufferData(FID, &Invalid);
+  llvm::StringRef Content = SM.getBufferData(FID, &Invalid);
   if (Invalid)
     return None;
   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);
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h
index 769d0af..e6ce8c3 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -15,9 +14,12 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_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/StringRef.h"
 #include "llvm/Support/SHA1.h"
 
 namespace clang {
@@ -55,6 +57,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);
@@ -78,19 +125,30 @@
 TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M,
                     const LangOptions &L);
 
-/// Get the real/canonical path of \p F.  This means:
+/// Get the canonical path of \p F.  This means:
 ///
 ///   - Absolute path
 ///   - Symlinks resolved
 ///   - No "." or ".." component
 ///   - No duplicate or trailing directory separator
 ///
-/// This function should be used when sending paths to clients, so that paths
-/// are normalized as much as possible.
-llvm::Optional<std::string> getRealPath(const FileEntry *F,
-                                        const SourceManager &SourceMgr);
+/// This function should be used when paths needs to be used outside the
+/// component that generate it, so that paths are normalized as much as
+/// possible.
+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);
+
+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);
+
 } // namespace clangd
 } // namespace clang
 #endif
diff --git a/clangd/TUScheduler.cpp b/clangd/TUScheduler.cpp
index 764bc26..c773082 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
@@ -18,8 +17,8 @@
 // preamble. However, unlike AST, the same preamble can be read concurrently, so
 // we run each of async preamble reads on its own thread.
 //
-// To limit the concurrent load that clangd produces we maintain a semaphore that
-// keeps more than a fixed number of threads from running concurrently.
+// To limit the concurrent load that clangd produces we maintain a semaphore
+// that keeps more than a fixed number of threads from running concurrently.
 //
 // Rationale for cancelling updates.
 // LSP clients can send updates to clangd on each keystroke. Some files take
@@ -46,6 +45,7 @@
 #include "Cancellation.h"
 #include "Logger.h"
 #include "Trace.h"
+#include "index/CanonicalIncludes.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/PCHContainerOperations.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -56,20 +56,19 @@
 #include <queue>
 #include <thread>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 using std::chrono::steady_clock;
 
 namespace {
 class ASTWorker;
-}
+} // namespace
 
 static clang::clangd::Key<std::string> kFileBeingProcessed;
 
-Optional<StringRef> TUScheduler::getFileBeingProcessedInContext() {
+llvm::Optional<llvm::StringRef> TUScheduler::getFileBeingProcessedInContext() {
   if (auto *File = Context::current().get(kFileBeingProcessed))
-    return StringRef(*File);
+    return llvm::StringRef(*File);
   return None;
 }
 
@@ -113,7 +112,7 @@
   /// Returns the cached value for \p K, or llvm::None if the value is not in
   /// the cache anymore. If nullptr was cached for \p K, this function will
   /// return a null unique_ptr wrapped into an optional.
-  Optional<std::unique_ptr<ParsedAST>> take(Key K) {
+  llvm::Optional<std::unique_ptr<ParsedAST>> take(Key K) {
     std::unique_lock<std::mutex> Lock(Mut);
     auto Existing = findByKey(K);
     if (Existing == LRU.end())
@@ -123,7 +122,7 @@
     // GCC 4.8 fails to compile `return V;`, as it tries to call the copy
     // constructor of unique_ptr, so we call the move ctor explicitly to avoid
     // this miscompile.
-    return Optional<std::unique_ptr<ParsedAST>>(std::move(V));
+    return llvm::Optional<std::unique_ptr<ParsedAST>>(std::move(V));
   }
 
 private:
@@ -177,15 +176,16 @@
   ~ASTWorker();
 
   void update(ParseInputs Inputs, WantDiagnostics);
-  void runWithAST(StringRef Name,
-                  unique_function<void(Expected<InputsAndAST>)> Action);
+  void
+  runWithAST(llvm::StringRef Name,
+             llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action);
   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(
-      unique_function<void(std::shared_ptr<const PreambleData>)>);
+      llvm::unique_function<void(std::shared_ptr<const PreambleData>)>);
   /// 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
@@ -203,8 +203,8 @@
   /// Signal that run() should finish processing pending requests and exit.
   void stop();
   /// Adds a new task to the end of the request queue.
-  void startTask(StringRef Name, unique_function<void()> Task,
-                 Optional<WantDiagnostics> UpdateType);
+  void startTask(llvm::StringRef Name, llvm::unique_function<void()> Task,
+                 llvm::Optional<WantDiagnostics> UpdateType);
   /// Updates the TUStatus and emits it. Only called in the worker thread.
   void emitTUStatus(TUAction FAction,
                     const TUStatus::BuildDetails *Detail = nullptr);
@@ -218,11 +218,11 @@
   bool shouldSkipHeadLocked() const;
 
   struct Request {
-    unique_function<void()> Action;
+    llvm::unique_function<void()> Action;
     std::string Name;
     steady_clock::time_point AddTime;
     Context Ctx;
-    Optional<WantDiagnostics> UpdateType;
+    llvm::Optional<WantDiagnostics> UpdateType;
   };
 
   /// Handles retention of ASTs.
@@ -321,7 +321,7 @@
       FileName, IdleASTs, Barrier, /*RunSync=*/!Tasks, UpdateDebounce,
       std::move(PCHs), StorePreamblesInMemory, Callbacks));
   if (Tasks)
-    Tasks->runAsync("worker:" + sys::path::filename(FileName),
+    Tasks->runAsync("worker:" + llvm::sys::path::filename(FileName),
                     [Worker]() { Worker->run(); });
 
   return ASTWorkerHandle(std::move(Worker));
@@ -334,8 +334,9 @@
                      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()},
+      Callbacks(Callbacks),
+      PCHs(std::move(PCHs)), Status{TUAction(TUAction::Idle, ""),
+                                    TUStatus::BuildDetails()},
       Barrier(Barrier), Done(false) {}
 
 ASTWorker::~ASTWorker() {
@@ -349,7 +350,7 @@
 }
 
 void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
-  StringRef TaskName = "Update";
+  llvm::StringRef TaskName = "Update";
   auto Task = [=]() mutable {
     // Will be used to check if we can avoid rebuilding the AST.
     bool InputsAreTheSame =
@@ -363,7 +364,7 @@
     emitTUStatus({TUAction::BuildingPreamble, TaskName});
     log("Updating file {0} with command [{1}] {2}", FileName,
         Inputs.CompileCommand.Directory,
-        join(Inputs.CompileCommand.CommandLine, " "));
+        llvm::join(Inputs.CompileCommand.CommandLine, " "));
     // Rebuild the preamble and the AST.
     std::unique_ptr<CompilerInvocation> Invocation =
         buildCompilerInvocation(Inputs);
@@ -385,8 +386,9 @@
     std::shared_ptr<const PreambleData> NewPreamble = buildPreamble(
         FileName, *Invocation, OldPreamble, OldCommand, Inputs, PCHs,
         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);
@@ -436,9 +438,9 @@
     }
 
     // Get the AST for diagnostics.
-    Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
+    llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
     if (!AST) {
-      Optional<ParsedAST> NewAST =
+      llvm::Optional<ParsedAST> NewAST =
           buildAST(FileName, std::move(Invocation), Inputs, NewPreamble, PCHs);
       AST = NewAST ? llvm::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
       if (!(*AST)) { // buildAST fails.
@@ -473,16 +475,17 @@
 }
 
 void ASTWorker::runWithAST(
-    StringRef Name, unique_function<void(Expected<InputsAndAST>)> Action) {
+    llvm::StringRef Name,
+    llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action) {
   auto Task = [=](decltype(Action) Action) {
     if (isCancelled())
-      return Action(make_error<CancelledError>());
-    Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
+      return Action(llvm::make_error<CancelledError>());
+    llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
     if (!AST) {
       std::unique_ptr<CompilerInvocation> Invocation =
           buildCompilerInvocation(FileInputs);
       // Try rebuilding the AST.
-      Optional<ParsedAST> NewAST =
+      llvm::Optional<ParsedAST> NewAST =
           Invocation
               ? buildAST(FileName,
                          llvm::make_unique<CompilerInvocation>(*Invocation),
@@ -491,12 +494,12 @@
       AST = NewAST ? llvm::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
     }
     // Make sure we put the AST back into the LRU cache.
-    auto _ = make_scope_exit(
+    auto _ = llvm::make_scope_exit(
         [&AST, this]() { IdleASTs.put(this, std::move(*AST)); });
     // Run the user-provided action.
     if (!*AST)
-      return Action(
-          make_error<StringError>("invalid AST", errc::invalid_argument));
+      return Action(llvm::make_error<llvm::StringError>(
+          "invalid AST", llvm::errc::invalid_argument));
     Action(InputsAndAST{FileInputs, **AST});
   };
   startTask(Name, Bind(Task, std::move(Action)),
@@ -510,7 +513,7 @@
 }
 
 void ASTWorker::getCurrentPreamble(
-    unique_function<void(std::shared_ptr<const PreambleData>)> Callback) {
+    llvm::unique_function<void(std::shared_ptr<const PreambleData>)> Callback) {
   // We could just call startTask() to throw the read on the queue, knowing
   // it will run after any updates. But we know this task is cheap, so to
   // improve latency we cheat: insert it on the queue after the last update.
@@ -537,9 +540,7 @@
   RequestsCV.notify_all();
 }
 
-void ASTWorker::waitForFirstPreamble() const {
-  PreambleWasBuilt.wait();
-}
+void ASTWorker::waitForFirstPreamble() const { PreambleWasBuilt.wait(); }
 
 std::size_t ASTWorker::getUsedBytes() const {
   // Note that we don't report the size of ASTs currently used for processing
@@ -566,11 +567,12 @@
   RequestsCV.notify_all();
 }
 
-void ASTWorker::startTask(StringRef Name, unique_function<void()> Task,
-                          Optional<WantDiagnostics> UpdateType) {
+void ASTWorker::startTask(llvm::StringRef Name,
+                          llvm::unique_function<void()> Task,
+                          llvm::Optional<WantDiagnostics> UpdateType) {
   if (RunSync) {
     assert(!Done && "running a task after stop()");
-    trace::Span Tracer(Name + ":" + sys::path::filename(FileName));
+    trace::Span Tracer(Name + ":" + llvm::sys::path::filename(FileName));
     Task();
     return;
   }
@@ -612,8 +614,8 @@
         }
 
         // Tracing: we have a next request, attribute this sleep to it.
-        Optional<WithContext> Ctx;
-        Optional<trace::Span> Tracer;
+        llvm::Optional<WithContext> Ctx;
+        llvm::Optional<trace::Span> Tracer;
         if (!Requests.empty()) {
           Ctx.emplace(Requests.front().Ctx.clone());
           Tracer.emplace("Debounce");
@@ -729,6 +731,33 @@
   return wait(Lock, RequestsCV, Timeout, [&] { return Requests.empty(); });
 }
 
+// Render a TUAction to a user-facing string representation.
+// TUAction represents clangd-internal states, we don't intend to expose them
+// to users (say C++ programmers) directly to avoid confusion, we use terms that
+// are familiar by C++ programmers.
+std::string renderTUAction(const TUAction &Action) {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  switch (Action.S) {
+  case TUAction::Queued:
+    OS << "file is queued";
+    break;
+  case TUAction::RunningAction:
+    OS << "running " << Action.Name;
+    break;
+  case TUAction::BuildingPreamble:
+    OS << "parsing includes";
+    break;
+  case TUAction::BuildingFile:
+    OS << "parsing main file";
+    break;
+  case TUAction::Idle:
+    OS << "idle";
+    break;
+  }
+  return OS.str();
+}
+
 } // namespace
 
 unsigned getDefaultAsyncThreadsCount() {
@@ -741,6 +770,13 @@
   return HardwareConcurrency;
 }
 
+FileStatus TUStatus::render(PathRef File) const {
+  FileStatus FStatus;
+  FStatus.uri = URIForFile::canonicalize(File, /*TUPath=*/File);
+  FStatus.state = renderTUAction(Action);
+  return FStatus;
+}
+
 struct TUScheduler::FileData {
   /// Latest inputs, passed to TUScheduler::update().
   std::string Contents;
@@ -811,19 +847,20 @@
          File);
 }
 
-void TUScheduler::run(StringRef Name, unique_function<void()> Action) {
+void TUScheduler::run(llvm::StringRef Name,
+                      llvm::unique_function<void()> Action) {
   if (!PreambleTasks)
     return Action();
   PreambleTasks->runAsync(Name, std::move(Action));
 }
 
 void TUScheduler::runWithAST(
-    StringRef Name, PathRef File,
-    unique_function<void(Expected<InputsAndAST>)> Action) {
+    llvm::StringRef Name, PathRef File,
+    llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action) {
   auto It = Files.find(File);
   if (It == Files.end()) {
-    Action(make_error<LSPError>("trying to get AST for non-added document",
-                                ErrorCode::InvalidParams));
+    Action(llvm::make_error<LSPError>(
+        "trying to get AST for non-added document", ErrorCode::InvalidParams));
     return;
   }
 
@@ -831,12 +868,13 @@
 }
 
 void TUScheduler::runWithPreamble(
-    StringRef Name, PathRef File, PreambleConsistency Consistency,
-    unique_function<void(Expected<InputsAndPreamble>)> Action) {
+    llvm::StringRef Name, PathRef File, PreambleConsistency Consistency,
+    llvm::unique_function<void(llvm::Expected<InputsAndPreamble>)> Action) {
   auto It = Files.find(File);
   if (It == Files.end()) {
-    Action(make_error<LSPError>("trying to get preamble for non-added document",
-                                ErrorCode::InvalidParams));
+    Action(llvm::make_error<LSPError>(
+        "trying to get preamble for non-added document",
+        ErrorCode::InvalidParams));
     return;
   }
 
@@ -888,7 +926,7 @@
   };
 
   PreambleTasks->runAsync(
-      "task:" + sys::path::filename(File),
+      "task:" + llvm::sys::path::filename(File),
       Bind(Task, std::string(Name), std::string(File), It->second->Contents,
            It->second->Command,
            Context::current().derive(kFileBeingProcessed, File),
diff --git a/clangd/TUScheduler.h b/clangd/TUScheduler.h
index cf04c1f..abcf4aa 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,6 +12,7 @@
 #include "ClangdUnit.h"
 #include "Function.h"
 #include "Threading.h"
+#include "index/CanonicalIncludes.h"
 #include "llvm/ADT/StringMap.h"
 #include <future>
 
@@ -62,7 +62,7 @@
     Idle, // Indicates the worker thread is idle, and ready to run any upcoming
           // actions.
   };
-  TUAction(State S, llvm::StringRef Name) : S(S), Name(Name){};
+  TUAction(State S, llvm::StringRef Name) : S(S), Name(Name) {}
   State S;
   /// The name of the action currently running, e.g. Update, GoToDef, Hover.
   /// Empty if we are in the idle state.
@@ -77,6 +77,8 @@
     /// Indicates whether we reused the prebuilt AST.
     bool ReuseAST = false;
   };
+  /// Serialize this to an LSP file status item.
+  FileStatus render(PathRef File) const;
 
   TUAction Action;
   BuildDetails Details;
@@ -90,7 +92,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.
@@ -224,12 +227,13 @@
 /// propagated.
 template <typename T>
 std::future<T> runAsync(llvm::unique_function<T()> Action) {
-  return std::async(std::launch::async,
-                    [](llvm::unique_function<T()> &&Action, Context Ctx) {
-                      WithContext WithCtx(std::move(Ctx));
-                      return Action();
-                    },
-                    std::move(Action), Context::current().clone());
+  return std::async(
+      std::launch::async,
+      [](llvm::unique_function<T()> &&Action, Context Ctx) {
+        WithContext WithCtx(std::move(Ctx));
+        return Action();
+      },
+      std::move(Action), Context::current().clone());
 }
 
 } // namespace clangd
diff --git a/clangd/Threading.cpp b/clangd/Threading.cpp
index abfe0f4..139fcc2 100644
--- a/clangd/Threading.cpp
+++ b/clangd/Threading.cpp
@@ -9,7 +9,6 @@
 #include <pthread.h>
 #endif
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -64,14 +63,14 @@
                       [&] { return InFlightTasks == 0; });
 }
 
-void AsyncTaskRunner::runAsync(const Twine &Name,
-                               unique_function<void()> Action) {
+void AsyncTaskRunner::runAsync(const llvm::Twine &Name,
+                               llvm::unique_function<void()> Action) {
   {
     std::lock_guard<std::mutex> Lock(Mutex);
     ++InFlightTasks;
   }
 
-  auto CleanupTask = make_scope_exit([this]() {
+  auto CleanupTask = llvm::make_scope_exit([this]() {
     std::lock_guard<std::mutex> Lock(Mutex);
     int NewTasksCnt = --InFlightTasks;
     if (NewTasksCnt == 0) {
@@ -83,7 +82,7 @@
 
   std::thread(
       [](std::string Name, decltype(Action) Action, decltype(CleanupTask)) {
-        set_thread_name(Name);
+        llvm::set_thread_name(Name);
         Action();
         // Make sure function stored by Action is destroyed before CleanupTask
         // is run.
@@ -93,7 +92,7 @@
       .detach();
 }
 
-Deadline timeoutSeconds(Optional<double> Seconds) {
+Deadline timeoutSeconds(llvm::Optional<double> Seconds) {
   using namespace std::chrono;
   if (!Seconds)
     return Deadline::infinity();
diff --git a/clangd/Threading.h b/clangd/Threading.h
index 4c55328..3c1f891 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/Trace.cpp b/clangd/Trace.cpp
index 8fb19cc..d650013 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,7 +18,6 @@
 #include <atomic>
 #include <mutex>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace trace {
@@ -29,16 +27,16 @@
 // Perhaps we should replace this by something that disturbs performance less.
 class JSONTracer : public EventTracer {
 public:
-  JSONTracer(raw_ostream &Out, bool Pretty)
+  JSONTracer(llvm::raw_ostream &Out, bool Pretty)
       : Out(Out), Sep(""), Start(std::chrono::system_clock::now()),
         JSONFormat(Pretty ? "{0:2}" : "{0}") {
     // The displayTimeUnit must be ns to avoid low-precision overlap
     // calculations!
     Out << R"({"displayTimeUnit":"ns","traceEvents":[)"
         << "\n";
-    rawEvent("M", json::Object{
+    rawEvent("M", llvm::json::Object{
                       {"name", "process_name"},
-                      {"args", json::Object{{"name", "clangd"}}},
+                      {"args", llvm::json::Object{{"name", "clangd"}}},
                   });
   }
 
@@ -49,7 +47,7 @@
 
   // We stash a Span object in the context. It will record the start/end,
   // and this also allows us to look up the parent Span's information.
-  Context beginSpan(StringRef Name, json::Object *Args) override {
+  Context beginSpan(llvm::StringRef Name, llvm::json::Object *Args) override {
     return Context::current().derive(
         SpanKey, llvm::make_unique<JSONSpan>(this, Name, Args));
   }
@@ -62,15 +60,16 @@
     Context::current().getExisting(SpanKey)->markEnded();
   }
 
-  void instant(StringRef Name, json::Object &&Args) override {
+  void instant(llvm::StringRef Name, llvm::json::Object &&Args) override {
     captureThreadMetadata();
-    jsonEvent("i", json::Object{{"name", Name}, {"args", std::move(Args)}});
+    jsonEvent("i",
+              llvm::json::Object{{"name", Name}, {"args", std::move(Args)}});
   }
 
   // Record an event on the current thread. ph, pid, tid, ts are set.
   // Contents must be a list of the other JSON key/values.
-  void jsonEvent(StringRef Phase, json::Object &&Contents,
-                 uint64_t TID = get_threadid(), double Timestamp = 0) {
+  void jsonEvent(llvm::StringRef Phase, llvm::json::Object &&Contents,
+                 uint64_t TID = llvm::get_threadid(), double Timestamp = 0) {
     Contents["ts"] = Timestamp ? Timestamp : timestamp();
     Contents["tid"] = int64_t(TID);
     std::lock_guard<std::mutex> Lock(Mu);
@@ -80,9 +79,9 @@
 private:
   class JSONSpan {
   public:
-    JSONSpan(JSONTracer *Tracer, StringRef Name, json::Object *Args)
+    JSONSpan(JSONTracer *Tracer, llvm::StringRef Name, llvm::json::Object *Args)
         : StartTime(Tracer->timestamp()), EndTime(0), Name(Name),
-          TID(get_threadid()), Tracer(Tracer), Args(Args) {
+          TID(llvm::get_threadid()), Tracer(Tracer), Args(Args) {
       // ~JSONSpan() may run in a different thread, so we need to capture now.
       Tracer->captureThreadMetadata();
 
@@ -100,33 +99,33 @@
           OriginTime = (*Parent)->StartTime;
 
         auto FlowID = nextID();
-        Tracer->jsonEvent("s",
-                          json::Object{{"id", FlowID},
-                                       {"name", "Context crosses threads"},
-                                       {"cat", "dummy"}},
-                          (*Parent)->TID, (*Parent)->StartTime);
-        Tracer->jsonEvent("f",
-                          json::Object{{"id", FlowID},
-                                       {"bp", "e"},
-                                       {"name", "Context crosses threads"},
-                                       {"cat", "dummy"}},
-                          TID);
+        Tracer->jsonEvent(
+            "s",
+            llvm::json::Object{{"id", FlowID},
+                               {"name", "Context crosses threads"},
+                               {"cat", "dummy"}},
+            (*Parent)->TID, (*Parent)->StartTime);
+        Tracer->jsonEvent(
+            "f",
+            llvm::json::Object{{"id", FlowID},
+                               {"bp", "e"},
+                               {"name", "Context crosses threads"},
+                               {"cat", "dummy"}},
+            TID);
       }
     }
 
     ~JSONSpan() {
       // Finally, record the event (ending at EndTime, not timestamp())!
       Tracer->jsonEvent("X",
-                        json::Object{{"name", std::move(Name)},
-                                     {"args", std::move(*Args)},
-                                     {"dur", EndTime - StartTime}},
+                        llvm::json::Object{{"name", std::move(Name)},
+                                           {"args", std::move(*Args)},
+                                           {"dur", EndTime - StartTime}},
                         TID, StartTime);
     }
 
     // May be called by any thread.
-    void markEnded() {
-      EndTime = Tracer->timestamp();
-    }
+    void markEnded() { EndTime = Tracer->timestamp(); }
 
   private:
     static int64_t nextID() {
@@ -139,32 +138,34 @@
     std::string Name;
     uint64_t TID;
     JSONTracer *Tracer;
-    json::Object *Args;
+    llvm::json::Object *Args;
   };
   static Key<std::unique_ptr<JSONSpan>> SpanKey;
 
   // Record an event. ph and pid are set.
   // Contents must be a list of the other JSON key/values.
-  void rawEvent(StringRef Phase, json::Object &&Event) /*REQUIRES(Mu)*/ {
+  void rawEvent(llvm::StringRef Phase,
+                llvm::json::Object &&Event) /*REQUIRES(Mu)*/ {
     // PID 0 represents the clangd process.
     Event["pid"] = 0;
     Event["ph"] = Phase;
-    Out << Sep << formatv(JSONFormat, json::Value(std::move(Event)));
+    Out << Sep
+        << llvm::formatv(JSONFormat, llvm::json::Value(std::move(Event)));
     Sep = ",\n";
   }
 
   // If we haven't already, emit metadata describing this thread.
   void captureThreadMetadata() {
-    uint64_t TID = get_threadid();
+    uint64_t TID = llvm::get_threadid();
     std::lock_guard<std::mutex> Lock(Mu);
     if (ThreadsWithMD.insert(TID).second) {
-      SmallString<32> Name;
-      get_thread_name(Name);
+      llvm::SmallString<32> Name;
+      llvm::get_thread_name(Name);
       if (!Name.empty()) {
-        rawEvent("M", json::Object{
+        rawEvent("M", llvm::json::Object{
                           {"tid", int64_t(TID)},
                           {"name", "thread_name"},
-                          {"args", json::Object{{"name", Name}}},
+                          {"args", llvm::json::Object{{"name", Name}}},
                       });
       }
     }
@@ -176,10 +177,10 @@
   }
 
   std::mutex Mu;
-  raw_ostream &Out /*GUARDED_BY(Mu)*/;
+  llvm::raw_ostream &Out /*GUARDED_BY(Mu)*/;
   const char *Sep /*GUARDED_BY(Mu)*/;
-  DenseSet<uint64_t> ThreadsWithMD /*GUARDED_BY(Mu)*/;
-  const sys::TimePoint<> Start;
+  llvm::DenseSet<uint64_t> ThreadsWithMD /*GUARDED_BY(Mu)*/;
+  const llvm::sys::TimePoint<> Start;
   const char *JSONFormat;
 };
 
@@ -195,31 +196,32 @@
 
 Session::~Session() { T = nullptr; }
 
-std::unique_ptr<EventTracer> createJSONTracer(raw_ostream &OS, bool Pretty) {
+std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
+                                              bool Pretty) {
   return llvm::make_unique<JSONTracer>(OS, Pretty);
 }
 
-void log(const Twine &Message) {
+void log(const llvm::Twine &Message) {
   if (!T)
     return;
-  T->instant("Log", json::Object{{"Message", Message.str()}});
+  T->instant("Log", llvm::json::Object{{"Message", Message.str()}});
 }
 
 // Returned context owns Args.
-static Context makeSpanContext(Twine Name, json::Object *Args) {
+static Context makeSpanContext(llvm::Twine Name, llvm::json::Object *Args) {
   if (!T)
     return Context::current().clone();
-  WithContextValue WithArgs{std::unique_ptr<json::Object>(Args)};
+  WithContextValue WithArgs{std::unique_ptr<llvm::json::Object>(Args)};
   return T->beginSpan(Name.isSingleStringRef() ? Name.getSingleStringRef()
-                                               : StringRef(Name.str()),
+                                               : llvm::StringRef(Name.str()),
                       Args);
 }
 
 // Span keeps a non-owning pointer to the args, which is how users access them.
 // The args are owned by the context though. They stick around until the
 // beginSpan() context is destroyed, when the tracing engine will consume them.
-Span::Span(Twine Name)
-    : Args(T ? new json::Object() : nullptr),
+Span::Span(llvm::Twine Name)
+    : Args(T ? new llvm::json::Object() : nullptr),
       RestoreCtx(makeSpanContext(Name, Args)) {}
 
 Span::~Span() {
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 2de9565..fab51d1 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,6 +85,12 @@
                  llvm::raw_ostream *InMirror, bool Pretty,
                  JSONStreamStyle = JSONStreamStyle::Standard);
 
+#ifdef 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();
+#endif
+
 } // namespace clangd
 } // namespace clang
 
diff --git a/clangd/URI.cpp b/clangd/URI.cpp
index 2a83862..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,13 +19,13 @@
 
 LLVM_INSTANTIATE_REGISTRY(clang::clangd::URISchemeRegistry)
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
-inline Error make_string_error(const Twine &Message) {
-  return make_error<StringError>(Message, inconvertibleErrorCode());
+inline llvm::Error make_string_error(const llvm::Twine &Message) {
+  return llvm::make_error<llvm::StringError>(Message,
+                                             llvm::inconvertibleErrorCode());
 }
 
 /// \brief This manages file paths in the file system. All paths in the scheme
@@ -35,8 +34,9 @@
 /// registry.
 class FileSystemScheme : public URIScheme {
 public:
-  Expected<std::string> getAbsolutePath(StringRef /*Authority*/, StringRef Body,
-                                        StringRef /*HintPath*/) const override {
+  llvm::Expected<std::string>
+  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+                  llvm::StringRef /*HintPath*/) const override {
     if (!Body.startswith("/"))
       return make_string_error("File scheme: expect body to be an absolute "
                                "path starting with '/': " +
@@ -44,26 +44,26 @@
     // For Windows paths e.g. /X:
     if (Body.size() > 2 && Body[0] == '/' && Body[2] == ':')
       Body.consume_front("/");
-    SmallVector<char, 16> Path(Body.begin(), Body.end());
-    sys::path::native(Path);
+    llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
+    llvm::sys::path::native(Path);
     return std::string(Path.begin(), Path.end());
   }
 
-  Expected<URI> uriFromAbsolutePath(StringRef AbsolutePath) const override {
-    using namespace llvm::sys;
-
+  llvm::Expected<URI>
+  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
     std::string Body;
     // For Windows paths e.g. X:
     if (AbsolutePath.size() > 1 && AbsolutePath[1] == ':')
       Body = "/";
-    Body += path::convert_to_slash(AbsolutePath);
+    Body += llvm::sys::path::convert_to_slash(AbsolutePath);
     return URI("file", /*Authority=*/"", Body);
   }
 };
 
-Expected<std::unique_ptr<URIScheme>> findSchemeByName(StringRef Scheme) {
+llvm::Expected<std::unique_ptr<URIScheme>>
+findSchemeByName(llvm::StringRef Scheme) {
   if (Scheme == "file")
-    return make_unique<FileSystemScheme>();
+    return llvm::make_unique<FileSystemScheme>();
 
   for (auto I = URISchemeRegistry::begin(), E = URISchemeRegistry::end();
        I != E; ++I) {
@@ -96,12 +96,12 @@
 /// - Unreserved characters are not escaped.
 /// - Reserved characters always escaped with exceptions like '/'.
 /// - All other characters are escaped.
-std::string percentEncode(StringRef Content) {
+std::string percentEncode(llvm::StringRef Content) {
   std::string Result;
-  raw_string_ostream OS(Result);
+  llvm::raw_string_ostream OS(Result);
   for (unsigned char C : Content)
     if (shouldEscape(C))
-      OS << '%' << format_hex_no_prefix(C, 2, /*Upper = */ true);
+      OS << '%' << llvm::format_hex_no_prefix(C, 2, /*Upper = */ true);
     else
       OS << C;
 
@@ -110,16 +110,16 @@
 }
 
 /// Decodes a string according to percent-encoding.
-std::string percentDecode(StringRef Content) {
+std::string percentDecode(llvm::StringRef Content) {
   std::string Result;
   for (auto I = Content.begin(), E = Content.end(); I != E; ++I) {
     if (*I != '%') {
       Result += *I;
       continue;
     }
-    if (*I == '%' && I + 2 < Content.end() && isHexDigit(*(I + 1)) &&
-        isHexDigit(*(I + 2))) {
-      Result.push_back(hexFromNibbles(*(I + 1), *(I + 2)));
+    if (*I == '%' && I + 2 < Content.end() && llvm::isHexDigit(*(I + 1)) &&
+        llvm::isHexDigit(*(I + 2))) {
+      Result.push_back(llvm::hexFromNibbles(*(I + 1), *(I + 2)));
       I += 2;
     } else
       Result.push_back(*I);
@@ -127,19 +127,20 @@
   return Result;
 }
 
-bool isValidScheme(StringRef Scheme) {
+bool isValidScheme(llvm::StringRef Scheme) {
   if (Scheme.empty())
     return false;
-  if (!isAlpha(Scheme[0]))
+  if (!llvm::isAlpha(Scheme[0]))
     return false;
   return std::all_of(Scheme.begin() + 1, Scheme.end(), [](char C) {
-    return isAlnum(C) || C == '+' || C == '.' || C == '-';
+    return llvm::isAlnum(C) || C == '+' || C == '.' || C == '-';
   });
 }
 
 } // namespace
 
-URI::URI(StringRef Scheme, StringRef Authority, StringRef Body)
+URI::URI(llvm::StringRef Scheme, llvm::StringRef Authority,
+         llvm::StringRef Body)
     : Scheme(Scheme), Authority(Authority), Body(Body) {
   assert(!Scheme.empty());
   assert((Authority.empty() || Body.startswith("/")) &&
@@ -148,31 +149,31 @@
 
 std::string URI::toString() const {
   std::string Result;
-  raw_string_ostream OS(Result);
+  llvm::raw_string_ostream OS(Result);
   OS << percentEncode(Scheme) << ":";
   if (Authority.empty() && Body.empty())
     return OS.str();
   // If authority if empty, we only print body if it starts with "/"; otherwise,
   // the URI is invalid.
-  if (!Authority.empty() || StringRef(Body).startswith("/"))
+  if (!Authority.empty() || llvm::StringRef(Body).startswith("/"))
     OS << "//" << percentEncode(Authority);
   OS << percentEncode(Body);
   OS.flush();
   return Result;
 }
 
-Expected<URI> URI::parse(StringRef OrigUri) {
+llvm::Expected<URI> URI::parse(llvm::StringRef OrigUri) {
   URI U;
-  StringRef Uri = OrigUri;
+  llvm::StringRef Uri = OrigUri;
 
   auto Pos = Uri.find(':');
-  if (Pos == StringRef::npos)
+  if (Pos == llvm::StringRef::npos)
     return make_string_error("Scheme must be provided in URI: " + OrigUri);
   auto SchemeStr = Uri.substr(0, Pos);
   U.Scheme = percentDecode(SchemeStr);
   if (!isValidScheme(U.Scheme))
-    return make_string_error(
-        formatv("Invalid scheme: {0} (decoded: {1})", SchemeStr, U.Scheme));
+    return make_string_error(llvm::formatv("Invalid scheme: {0} (decoded: {1})",
+                                           SchemeStr, U.Scheme));
   Uri = Uri.substr(Pos + 1);
   if (Uri.consume_front("//")) {
     Pos = Uri.find('/');
@@ -183,8 +184,9 @@
   return U;
 }
 
-Expected<URI> URI::create(StringRef AbsolutePath, StringRef Scheme) {
-  if (!sys::path::is_absolute(AbsolutePath))
+llvm::Expected<URI> URI::create(llvm::StringRef AbsolutePath,
+                                llvm::StringRef Scheme) {
+  if (!llvm::sys::path::is_absolute(AbsolutePath))
     return make_string_error("Not a valid absolute path: " + AbsolutePath);
   auto S = findSchemeByName(Scheme);
   if (!S)
@@ -192,8 +194,8 @@
   return S->get()->uriFromAbsolutePath(AbsolutePath);
 }
 
-URI URI::create(StringRef AbsolutePath) {
-  if (!sys::path::is_absolute(AbsolutePath))
+URI URI::create(llvm::StringRef AbsolutePath) {
+  if (!llvm::sys::path::is_absolute(AbsolutePath))
     llvm_unreachable(
         ("Not a valid absolute path: " + AbsolutePath).str().c_str());
   for (auto &Entry : URISchemeRegistry::entries()) {
@@ -202,7 +204,7 @@
     // should be just skipped.
     if (!URI) {
       // Ignore the error.
-      consumeError(URI.takeError());
+      llvm::consumeError(URI.takeError());
       continue;
     }
     return std::move(*URI);
@@ -211,31 +213,33 @@
   return URI::createFile(AbsolutePath);
 }
 
-URI URI::createFile(StringRef AbsolutePath) {
+URI URI::createFile(llvm::StringRef AbsolutePath) {
   auto U = FileSystemScheme().uriFromAbsolutePath(AbsolutePath);
   if (!U)
     llvm_unreachable(llvm::toString(U.takeError()).c_str());
   return std::move(*U);
 }
 
-Expected<std::string> URI::resolve(const URI &Uri, StringRef HintPath) {
+llvm::Expected<std::string> URI::resolve(const URI &Uri,
+                                         llvm::StringRef HintPath) {
   auto S = findSchemeByName(Uri.Scheme);
   if (!S)
     return S.takeError();
   return S->get()->getAbsolutePath(Uri.Authority, Uri.Body, HintPath);
 }
 
-Expected<std::string> URI::resolvePath(StringRef AbsPath, StringRef HintPath) {
-  if (!sys::path::is_absolute(AbsPath))
+llvm::Expected<std::string> URI::resolvePath(llvm::StringRef AbsPath,
+                                             llvm::StringRef HintPath) {
+  if (!llvm::sys::path::is_absolute(AbsPath))
     llvm_unreachable(("Not a valid absolute path: " + AbsPath).str().c_str());
   for (auto &Entry : URISchemeRegistry::entries()) {
-    auto S =  Entry.instantiate();
+    auto S = Entry.instantiate();
     auto U = S->uriFromAbsolutePath(AbsPath);
     // For some paths, conversion to different URI schemes is impossible. These
     // should be just skipped.
     if (!U) {
       // Ignore the error.
-      consumeError(U.takeError());
+      llvm::consumeError(U.takeError());
       continue;
     }
     return S->getAbsolutePath(U->Authority, U->Body, HintPath);
@@ -244,7 +248,7 @@
   return AbsPath;
 }
 
-Expected<std::string> URI::includeSpelling(const URI &Uri) {
+llvm::Expected<std::string> URI::includeSpelling(const URI &Uri) {
   auto S = findSchemeByName(Uri.Scheme);
   if (!S)
     return S.takeError();
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 bdae8a3..b296a05 100644
--- a/clangd/XRefs.cpp
+++ b/clangd/XRefs.cpp
@@ -1,9 +1,8 @@
 //===--- 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"
@@ -11,6 +10,8 @@
 #include "Logger.h"
 #include "SourceCode.h"
 #include "URI.h"
+#include "index/Index.h"
+#include "index/Merge.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Index/IndexDataConsumer.h"
@@ -18,23 +19,30 @@
 #include "clang/Index/USRGeneration.h"
 #include "llvm/Support/Path.h"
 
-using namespace llvm;
 namespace clang {
 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)) // except cases above
+    return D;
+  // Multiple definitions are allowed.
+  return nullptr; // except cases above
 }
 
 void logIfOverflow(const SymbolLocation &Loc) {
@@ -46,8 +54,8 @@
 // TUPath is used to resolve the path of URI.
 // FIXME: figure out a good home for it, and share the implementation with
 // FindSymbols.
-Optional<Location> toLSPLocation(const SymbolLocation &Loc,
-                                 StringRef TUPath) {
+llvm::Optional<Location> toLSPLocation(const SymbolLocation &Loc,
+                                       llvm::StringRef TUPath) {
   if (!Loc)
     return None;
   auto Uri = URI::parse(Loc.FileURI);
@@ -71,8 +79,33 @@
   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 {
-  StringRef Name;
+  llvm::StringRef Name;
   const MacroInfo *Info;
 };
 
@@ -89,7 +122,7 @@
   // explicitly in the code.
   // True means the declaration is explicitly referenced at least once; false
   // otherwise.
-  DenseMap<const Decl *, bool> Decls;
+  llvm::DenseMap<const Decl *, bool> Decls;
   const SourceLocation &SearchedLocation;
   const ASTContext &AST;
   Preprocessor &PP;
@@ -135,11 +168,11 @@
 
   bool
   handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
-                      ArrayRef<index::SymbolRelation> Relations,
+                      llvm::ArrayRef<index::SymbolRelation> Relations,
                       SourceLocation Loc,
                       index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
     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
@@ -151,7 +184,7 @@
         return isa<ImplicitCastExpr>(E);
       };
 
-      bool IsExplicit = !isImplicitExpr(ASTNode.OrigE);
+      bool IsExplicit = !IsImplicitExpr(ASTNode.OrigE);
       // 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
@@ -209,6 +242,7 @@
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
   IndexOpts.IndexFunctionLocals = true;
+  IndexOpts.IndexParametersInDeclarations = true;
   indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(),
                      AST.getLocalTopLevelDecls(), DeclMacrosFinder, IndexOpts);
 
@@ -223,13 +257,13 @@
           sourceLocToPosition(SourceMgr, LocEnd)};
 }
 
-Optional<Location> makeLocation(ParsedAST &AST, SourceLocation TokLoc,
-                                StringRef TUPath) {
+llvm::Optional<Location> makeLocation(ParsedAST &AST, SourceLocation TokLoc,
+                                      llvm::StringRef TUPath) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *F = SourceMgr.getFileEntryForID(SourceMgr.getFileID(TokLoc));
   if (!F)
     return None;
-  auto FilePath = getRealPath(F, SourceMgr);
+  auto FilePath = getCanonicalPath(F, SourceMgr);
   if (!FilePath) {
     log("failed to get path!");
     return None;
@@ -242,126 +276,107 @@
 
 } // 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 = getRealPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
+  auto MainFilePath =
+      getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!MainFilePath) {
     elog("Failed to get a path for the main file, so no references");
     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 {
-    Optional<Location> Def;
-    Optional<Location> Decl;
-  };
-  // We respect the order in Symbols.Decls.
-  SmallVector<CandidateLocation, 8> ResultCandidates;
-  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("");
+    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 = getRealPath(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);
+      // Special case: if the AST yielded a definition, then it may not be
+      // the right *declaration*. Prefer the one from the index.
+      if (R.Definition) { // from AST
+        if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, *MainFilePath))
+          R.PreferredDeclaration = *Loc;
+      } else {
+        R.Definition = toLSPLocation(Sym.Definition, *MainFilePath);
+
+        if (Sym.CanonicalDeclaration) {
+          // Use merge logic to choose AST or index declaration.
+          // We only do this for declarations as definitions from AST
+          // is generally preferred (e.g. definitions in main file).
+          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;
 }
 
@@ -401,7 +416,7 @@
 
   bool
   handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
-                      ArrayRef<index::SymbolRelation> Relations,
+                      llvm::ArrayRef<index::SymbolRelation> Relations,
                       SourceLocation Loc,
                       index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
     assert(D->isCanonicalDecl() && "expect D to be a canonical declaration");
@@ -413,7 +428,7 @@
   }
 
 private:
-  SmallSet<const Decl *, 4> CanonicalTargets;
+  llvm::SmallSet<const Decl *, 4> CanonicalTargets;
   std::vector<Reference> References;
   const ASTContext &AST;
 };
@@ -425,6 +440,7 @@
   IndexOpts.SystemSymbolFilter =
       index::IndexingOptions::SystemSymbolFilterKind::All;
   IndexOpts.IndexFunctionLocals = true;
+  IndexOpts.IndexParametersInDeclarations = true;
   indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(),
                      AST.getLocalTopLevelDecls(), RefFinder, IndexOpts);
   return std::move(RefFinder).take();
@@ -479,7 +495,7 @@
       printingPolicyForDecls(TD->getASTContext().getPrintingPolicy());
 
   std::string Name;
-  raw_string_ostream Stream(Name);
+  llvm::raw_string_ostream Stream(Name);
   Type.print(Stream, Policy);
 
   return Stream.str();
@@ -488,12 +504,12 @@
 /// Return a string representation (e.g. "namespace ns1::ns2") of
 /// the named declaration \p ND.
 static std::string namedDeclQualifiedName(const NamedDecl *ND,
-                                          StringRef Prefix) {
+                                          llvm::StringRef Prefix) {
   PrintingPolicy Policy =
       printingPolicyForDecls(ND->getASTContext().getPrintingPolicy());
 
   std::string Name;
-  raw_string_ostream Stream(Name);
+  llvm::raw_string_ostream Stream(Name);
   Stream << Prefix << ' ';
   ND->printQualifiedName(Stream, Policy);
 
@@ -503,7 +519,7 @@
 /// Given a declaration \p D, return a human-readable string representing the
 /// scope in which it is declared.  If the declaration is in the global scope,
 /// return the string "global namespace".
-static Optional<std::string> getScopeName(const Decl *D) {
+static llvm::Optional<std::string> getScopeName(const Decl *D) {
   const DeclContext *DC = D->getDeclContext();
 
   if (isa<TranslationUnitDecl>(DC))
@@ -521,7 +537,7 @@
 /// Generate a \p Hover object given the declaration \p D.
 static Hover getHoverContents(const Decl *D) {
   Hover H;
-  Optional<std::string> NamedScope = getScopeName(D);
+  llvm::Optional<std::string> NamedScope = getScopeName(D);
 
   // Generate the "Declared in" section.
   if (NamedScope) {
@@ -537,7 +553,7 @@
     D = TD;
 
   std::string DeclText;
-  raw_string_ostream OS(DeclText);
+  llvm::raw_string_ostream OS(DeclText);
 
   PrintingPolicy Policy =
       printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
@@ -554,7 +570,7 @@
 static Hover getHoverContents(QualType T, ASTContext &ASTCtx) {
   Hover H;
   std::string TypeText;
-  raw_string_ostream OS(TypeText);
+  llvm::raw_string_ostream OS(TypeText);
   PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
   T.print(OS, Policy);
   OS.flush();
@@ -563,7 +579,7 @@
 }
 
 /// Generate a \p Hover object given the macro \p MacroInf.
-static Hover getHoverContents(StringRef MacroName) {
+static Hover getHoverContents(llvm::StringRef MacroName) {
   Hover H;
 
   H.contents.value = "#define ";
@@ -583,13 +599,13 @@
 /// a deduced type set. The AST should be improved to simplify this scenario.
 class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
   SourceLocation SearchedLocation;
-  Optional<QualType> DeducedType;
+  llvm::Optional<QualType> DeducedType;
 
 public:
   DeducedTypeVisitor(SourceLocation SearchedLocation)
       : SearchedLocation(SearchedLocation) {}
 
-  Optional<QualType> getDeducedType() { return DeducedType; }
+  llvm::Optional<QualType> getDeducedType() { return DeducedType; }
 
   // Handle auto initializers:
   //- auto i = 1;
@@ -664,8 +680,8 @@
 } // namespace
 
 /// Retrieves the deduced type at a given location (auto, decltype).
-Optional<QualType> getDeducedType(ParsedAST &AST,
-                                  SourceLocation SourceLocationBeg) {
+llvm::Optional<QualType> getDeducedType(ParsedAST &AST,
+                                        SourceLocation SourceLocationBeg) {
   Token Tok;
   auto &ASTCtx = AST.getASTContext();
   // Only try to find a deduced type if the token is auto or decltype.
@@ -684,7 +700,7 @@
   return V.getDeducedType();
 }
 
-Optional<Hover> getHover(ParsedAST &AST, Position Pos) {
+llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   SourceLocation SourceLocationBeg =
       getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID());
@@ -705,10 +721,13 @@
 }
 
 std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
-                                     const SymbolIndex *Index) {
+                                     uint32_t Limit, const SymbolIndex *Index) {
+  if (!Limit)
+    Limit = std::numeric_limits<uint32_t>::max();
   std::vector<Location> Results;
   const SourceManager &SM = AST.getASTContext().getSourceManager();
-  auto MainFilePath = getRealPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
+  auto MainFilePath =
+      getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!MainFilePath) {
     elog("Failed to get a path for the main file, so no references");
     return Results;
@@ -733,26 +752,30 @@
   }
 
   // Now query the index for references from other files.
-  if (!Index)
-    return Results;
-  RefsRequest Req;
-  for (const Decl *D : TargetDecls) {
-    // 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.
-    if (D->getParentFunctionOrMethod())
-      continue;
-    if (auto ID = getSymbolID(D))
-      Req.IDs.insert(*ID);
+  if (Index && Results.size() < Limit) {
+    RefsRequest Req;
+    Req.Limit = Limit;
+
+    for (const Decl *D : TargetDecls) {
+      // 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.
+      if (D->getParentFunctionOrMethod())
+        continue;
+      if (auto ID = getSymbolID(D))
+        Req.IDs.insert(*ID);
+    }
+    if (Req.IDs.empty())
+      return Results;
+    Index->refs(Req, [&](const Ref &R) {
+      auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
+      // Avoid indexed results for the main file - the AST is authoritative.
+      if (LSPLoc && LSPLoc->uri.file() != *MainFilePath)
+        Results.push_back(std::move(*LSPLoc));
+    });
   }
-  if (Req.IDs.empty())
-    return Results;
-  Index->refs(Req, [&](const Ref &R) {
-    auto LSPLoc = toLSPLocation(R.Location, *MainFilePath);
-    // Avoid indexed results for the main file - the AST is authoritative.
-    if (LSPLoc && LSPLoc->uri.file() != *MainFilePath)
-      Results.push_back(std::move(*LSPLoc));
-  });
+  if (Results.size() > Limit)
+    Results.resize(Limit);
   return Results;
 }
 
@@ -789,7 +812,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);
     }
@@ -799,5 +823,12 @@
   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;
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/clangd/XRefs.h b/clangd/XRefs.h
index 77d6024..25e5d86 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,
@@ -35,7 +50,9 @@
 llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos);
 
 /// Returns reference locations of the symbol at a specified \p Pos.
+/// \p Limit limits the number of results returned (0 means no limit).
 std::vector<Location> findReferences(ParsedAST &AST, Position Pos,
+                                     uint32_t Limit,
                                      const SymbolIndex *Index = nullptr);
 
 /// Get info about symbols at \p Pos.
diff --git a/clangd/benchmarks/IndexBenchmark.cpp b/clangd/benchmarks/IndexBenchmark.cpp
index baedca2..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,7 +20,6 @@
 const char *IndexFilename;
 const char *RequestsFilename;
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -41,16 +39,17 @@
                   std::istreambuf_iterator<char>());
 
   std::vector<FuzzyFindRequest> Requests;
-  auto JSONArray = json::parse(Log);
+  auto JSONArray = llvm::json::parse(Log);
 
   // Panic if the provided file couldn't be parsed.
   if (!JSONArray) {
-    errs() << "Error when parsing JSON requests file: "
-           << toString(JSONArray.takeError());
+    llvm::errs() << "Error when parsing JSON requests file: "
+                 << llvm::toString(JSONArray.takeError());
     exit(1);
   }
   if (!JSONArray->getAsArray()) {
-    errs() << "Error: top-level value is not a JSON array: " << Log << '\n';
+    llvm::errs() << "Error: top-level value is not a JSON array: " << Log
+                 << '\n';
     exit(1);
   }
 
@@ -58,7 +57,7 @@
     FuzzyFindRequest Request;
     // Panic if the provided file couldn't be parsed.
     if (!fromJSON(Item, Request)) {
-      errs() << "Error when deserializing request: " << Item << '\n';
+      llvm::errs() << "Error when deserializing request: " << Item << '\n';
       exit(1);
     }
     Requests.push_back(Request);
@@ -94,9 +93,9 @@
 // FIXME(kbobyrev): Create a logger wrapper to suppress debugging info printer.
 int main(int argc, char *argv[]) {
   if (argc < 3) {
-    errs() << "Usage: " << argv[0]
-           << " global-symbol-index.yaml requests.json "
-              "BENCHMARK_OPTIONS...\n";
+    llvm::errs() << "Usage: " << argv[0]
+                 << " global-symbol-index.yaml requests.json "
+                    "BENCHMARK_OPTIONS...\n";
     return -1;
   }
   IndexFilename = argv[1];
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/LICENSE b/clangd/clients/clangd-vscode/LICENSE
index c558158..6a18483 100644
--- a/clangd/clients/clangd-vscode/LICENSE
+++ b/clangd/clients/clangd-vscode/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2017 The LLVM Developers
+Copyright (c) 2019 The LLVM Developers
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
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 f1dcb6e..f9ac922 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.8",
+    "version": "0.0.11",
     "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,10 @@
         "LLVM"
     ],
     "activationEvents": [
+        "onLanguage:c",
         "onLanguage:cpp",
-        "onLanguage:c"
+        "onLanguage:objective-c",
+        "onLanguage:objective-cpp"
     ],
     "main": "./out/src/extension",
     "scripts": {
@@ -32,15 +34,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",
diff --git a/clangd/clients/clangd-vscode/src/extension.ts b/clangd/clients/clangd-vscode/src/extension.ts
index 1191bb4..d4ab678 100644
--- a/clangd/clients/clangd-vscode/src/extension.ts
+++ b/clangd/clients/clangd-vscode/src/extension.ts
@@ -18,6 +18,38 @@
                              void, void>('textDocument/switchSourceHeader');
 }
 
+class FileStatus {
+    private statuses = new Map<string, any>();
+    private readonly statusBarItem =
+        vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10);
+
+    onFileUpdated(fileStatus: any) {
+        const filePath = vscode.Uri.parse(fileStatus.uri);
+        this.statuses.set(filePath.fsPath, fileStatus);
+        this.updateStatus();
+    }
+
+    updateStatus() {
+        const path = vscode.window.activeTextEditor.document.fileName;
+        const status = this.statuses.get(path);
+        if (!status) {
+          this.statusBarItem.hide();
+          return;
+        }
+        this.statusBarItem.text = `clangd: ` + status.state;
+        this.statusBarItem.show();
+    }
+
+    clear() {
+        this.statuses.clear();
+        this.statusBarItem.hide();
+    }
+
+    dispose() {
+        this.statusBarItem.dispose();
+    }
+}
+
 /**
  *  this method is called when your extension is activate
  *  your extension is activated the very first time the command is executed
@@ -44,6 +76,7 @@
         synchronize: !syncFileEvents ? undefined : {
             fileEvents: vscode.workspace.createFileSystemWatcher(filePattern)
         },
+        initializationOptions: { clangdFileStatus: true },
         // Resolve symlinks for all files provided by clangd.
         // This is a workaround for a bazel + clangd issue - bazel produces a symlink tree to build in,
         // and when navigating to the included file, clangd passes its path inside the symlink tree
@@ -80,4 +113,20 @@
             vscode.Uri.parse(sourceUri));
         vscode.window.showTextDocument(doc);
       }));
+    const status = new FileStatus();
+    context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(() => {
+        status.updateStatus();
+    }));
+    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();
+            }
+        })
 }
diff --git a/clangd/fuzzer/ClangdFuzzer.cpp b/clangd/fuzzer/ClangdFuzzer.cpp
index 8c9c7bd..eba9826 100644
--- a/clangd/fuzzer/ClangdFuzzer.cpp
+++ b/clangd/fuzzer/ClangdFuzzer.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,8 +15,9 @@
 #include "ClangdLSPServer.h"
 #include "ClangdServer.h"
 #include "CodeComplete.h"
+#include "FSProvider.h"
+#include <cstdio>
 #include <sstream>
-#include <stdio.h>
 
 using namespace clang::clangd;
 
@@ -29,13 +29,14 @@
   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, Opts);
   LSPServer.run();
   return 0;
 }
diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp
index 1d67819..ddb0ec4 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -35,7 +34,6 @@
 #include <string>
 #include <thread>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -92,46 +90,48 @@
 
 // Creates a filter to not collect index results from files with unchanged
 // digests.
-// \p FileDigests contains file digests for the current indexed files, and all
-// changed files will be added to \p FilesToUpdate.
+// \p FileDigests contains file digests for the current indexed files.
 decltype(SymbolCollector::Options::FileFilter)
-createFileFilter(const llvm::StringMap<FileDigest> &FileDigests,
-                 llvm::StringMap<FileDigest> &FilesToUpdate) {
-  return [&FileDigests, &FilesToUpdate](const SourceManager &SM, FileID FID) {
-    StringRef Path;
-    if (const auto *F = SM.getFileEntryForID(FID))
-      Path = F->getName();
-    if (Path.empty())
+createFileFilter(const llvm::StringMap<FileDigest> &FileDigests) {
+  return [&FileDigests](const SourceManager &SM, FileID FID) {
+    const auto *F = SM.getFileEntryForID(FID);
+    if (!F)
       return false; // Skip invalid files.
-    SmallString<128> AbsPath(Path);
-    if (std::error_code EC =
-            SM.getFileManager().getVirtualFileSystem()->makeAbsolute(AbsPath)) {
-      elog("Warning: could not make absolute file: {0}", EC.message());
+    auto AbsPath = getCanonicalPath(F, SM);
+    if (!AbsPath)
       return false; // Skip files without absolute path.
-    }
-    sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
     auto Digest = digestFile(SM, FID);
     if (!Digest)
       return false;
-    auto D = FileDigests.find(AbsPath);
+    auto D = FileDigests.find(*AbsPath);
     if (D != FileDigests.end() && D->second == Digest)
       return false; // Skip files that haven't changed.
-
-    FilesToUpdate[AbsPath] = *Digest;
     return true;
   };
 }
 
+// We cannot use vfs->makeAbsolute because Cmd.FileName is either absolute or
+// relative to Cmd.Directory, which might not be the same as current working
+// directory.
+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
+  llvm::SmallString<128> AbsolutePath;
+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {
+    AbsolutePath = Cmd.Filename;
+  } else {
+    AbsolutePath = Cmd.Directory;
+    llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+  }
+  return AbsolutePath;
+}
 } // namespace
 
 BackgroundIndex::BackgroundIndex(
-    Context BackgroundContext, 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(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)),
@@ -169,7 +169,7 @@
 void BackgroundIndex::run() {
   WithContext Background(BackgroundContext.clone());
   while (true) {
-    Optional<Task> Task;
+    llvm::Optional<Task> Task;
     ThreadPriority Priority;
     {
       std::unique_lock<std::mutex> Lock(QueueMu);
@@ -211,40 +211,32 @@
       [this, ChangedFiles] {
         trace::Span Tracer("BackgroundIndexEnqueue");
         // We're doing this asynchronously, because we'll read shards here too.
-        // FIXME: read shards here too.
-
         log("Enqueueing {0} commands for indexing", ChangedFiles.size());
         SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));
 
-        // We shuffle the files because processing them in a random order should
-        // quickly give us good coverage of headers in the project.
-        std::vector<unsigned> Permutation(ChangedFiles.size());
-        std::iota(Permutation.begin(), Permutation.end(), 0);
-        std::mt19937 Generator(std::random_device{}());
-        std::shuffle(Permutation.begin(), Permutation.end(), Generator);
-
-        for (const unsigned I : Permutation)
-          enqueue(ChangedFiles[I]);
+        auto NeedsReIndexing = loadShards(std::move(ChangedFiles));
+        // Run indexing for files that need to be updated.
+        std::shuffle(NeedsReIndexing.begin(), NeedsReIndexing.end(),
+                     std::mt19937(std::random_device{}()));
+        for (auto &Elem : NeedsReIndexing)
+          enqueue(std::move(Elem.first), Elem.second);
       },
       ThreadPriority::Normal);
 }
 
-void BackgroundIndex::enqueue(const std::string &File) {
-  ProjectInfo Project;
-  if (auto Cmd = CDB.getCompileCommand(File, &Project)) {
-    auto *Storage = IndexStorageFactory(Project.SourceRoot);
-    // Set priority to low, since background indexing is a long running
-    // task we do not want to eat up cpu when there are any other high
-    // priority threads.
-    enqueueTask(Bind(
-                    [this, File, Storage](tooling::CompileCommand Cmd) {
-                      Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);
-                      if (auto Error = index(std::move(Cmd), Storage))
-                        log("Indexing {0} failed: {1}", File, std::move(Error));
-                    },
-                    std::move(*Cmd)),
-                ThreadPriority::Low);
-  }
+void BackgroundIndex::enqueue(tooling::CompileCommand Cmd,
+                              BackgroundIndexStorage *Storage) {
+  enqueueTask(Bind(
+                  [this, Storage](tooling::CompileCommand Cmd) {
+                    // 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;
+                    if (auto Error = index(std::move(Cmd), Storage))
+                      elog("Indexing {0} failed: {1}", FileName,
+                           std::move(Error));
+                  },
+                  std::move(Cmd)),
+              ThreadPriority::Low);
 }
 
 void BackgroundIndex::enqueueTask(Task T, ThreadPriority Priority) {
@@ -265,22 +257,34 @@
   QueueCV.notify_all();
 }
 
-/// Given index results from a TU, only update files in \p FilesToUpdate.
-void BackgroundIndex::update(StringRef MainFile, IndexFileIn Index,
-                             const StringMap<FileDigest> &FilesToUpdate,
+/// Given index results from a TU, only update symbols coming from files that
+/// are different or missing from than \p DigestsSnapshot. Also stores new index
+/// information on IndexStorage.
+void BackgroundIndex::update(llvm::StringRef MainFile, IndexFileIn Index,
+                             const llvm::StringMap<FileDigest> &DigestsSnapshot,
                              BackgroundIndexStorage *IndexStorage) {
   // Partition symbols/references into files.
   struct File {
-    DenseSet<const Symbol *> Symbols;
-    DenseSet<const Ref *> Refs;
+    llvm::DenseSet<const Symbol *> Symbols;
+    llvm::DenseSet<const Ref *> Refs;
+    FileDigest Digest;
   };
-  StringMap<File> Files;
+  llvm::StringMap<File> Files;
   URIToFileCache URICache(MainFile);
+  for (const auto &IndexIt : *Index.Sources) {
+    const auto &IGN = IndexIt.getValue();
+    const auto AbsPath = URICache.resolve(IGN.URI);
+    const auto DigestIt = DigestsSnapshot.find(AbsPath);
+    // File has different contents.
+    if (DigestIt == DigestsSnapshot.end() || DigestIt->getValue() != IGN.Digest)
+      Files.try_emplace(AbsPath).first->getValue().Digest = IGN.Digest;
+  }
   for (const auto &Sym : *Index.Symbols) {
     if (Sym.CanonicalDeclaration) {
       auto DeclPath = URICache.resolve(Sym.CanonicalDeclaration.FileURI);
-      if (FilesToUpdate.count(DeclPath) != 0)
-        Files[DeclPath].Symbols.insert(&Sym);
+      const auto FileIt = Files.find(DeclPath);
+      if (FileIt != Files.end())
+        FileIt->second.Symbols.insert(&Sym);
     }
     // For symbols with different declaration and definition locations, we store
     // the full symbol in both the header file and the implementation file, so
@@ -289,16 +293,18 @@
     if (Sym.Definition &&
         Sym.Definition.FileURI != Sym.CanonicalDeclaration.FileURI) {
       auto DefPath = URICache.resolve(Sym.Definition.FileURI);
-      if (FilesToUpdate.count(DefPath) != 0)
-        Files[DefPath].Symbols.insert(&Sym);
+      const auto FileIt = Files.find(DefPath);
+      if (FileIt != Files.end())
+        FileIt->second.Symbols.insert(&Sym);
     }
   }
-  DenseMap<const Ref *, SymbolID> RefToIDs;
+  llvm::DenseMap<const Ref *, SymbolID> RefToIDs;
   for (const auto &SymRefs : *Index.Refs) {
     for (const auto &R : SymRefs.second) {
       auto Path = URICache.resolve(R.Location.FileURI);
-      if (FilesToUpdate.count(Path) != 0) {
-        auto &F = Files[Path];
+      const auto FileIt = Files.find(Path);
+      if (FileIt != Files.end()) {
+        auto &F = FileIt->getValue();
         RefToIDs[&R] = SymRefs.first;
         F.Refs.insert(&R);
       }
@@ -306,22 +312,18 @@
   }
 
   // Build and store new slabs for each updated file.
-  for (const auto &F : Files) {
-    StringRef Path = F.first();
-    vlog("Update symbols in {0}", Path);
+  for (const auto &FileIt : Files) {
+    llvm::StringRef Path = FileIt.getKey();
     SymbolSlab::Builder Syms;
     RefSlab::Builder Refs;
-    for (const auto *S : F.second.Symbols)
+    for (const auto *S : FileIt.second.Symbols)
       Syms.insert(*S);
-    for (const auto *R : F.second.Refs)
+    for (const auto *R : FileIt.second.Refs)
       Refs.insert(RefToIDs[R], *R);
-
     auto SS = llvm::make_unique<SymbolSlab>(std::move(Syms).build());
     auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build());
     auto IG = llvm::make_unique<IncludeGraph>(
         getSubGraph(URI::create(Path), Index.Sources.getValue()));
-
-    auto Hash = FilesToUpdate.lookup(Path);
     // We need to store shards before updating the index, since the latter
     // consumes slabs.
     if (IndexStorage) {
@@ -334,13 +336,19 @@
         elog("Failed to write background-index shard for file {0}: {1}", Path,
              std::move(Error));
     }
-
-    std::lock_guard<std::mutex> Lock(DigestsMu);
-    // This can override a newer version that is added in another thread,
-    // if this thread sees the older version but finishes later. This should be
-    // rare in practice.
-    IndexedFileDigests[Path] = Hash;
-    IndexedSymbols.update(Path, std::move(SS), std::move(RS));
+    {
+      std::lock_guard<std::mutex> Lock(DigestsMu);
+      auto Hash = FileIt.second.Digest;
+      // Skip if file is already up to date.
+      auto DigestIt = IndexedFileDigests.try_emplace(Path);
+      if (!DigestIt.second && DigestIt.first->second == Hash)
+        continue;
+      DigestIt.first->second = Hash;
+      // This can override a newer version that is added in another thread, if
+      // this thread sees the older version but finishes later. This should be
+      // rare in practice.
+      IndexedSymbols.update(Path, std::move(SS), std::move(RS));
+    }
   }
 }
 
@@ -349,11 +357,11 @@
   while (true) {
     {
       std::unique_lock<std::mutex> Lock(IndexMu);
-      if (ShouldStop)  // Avoid waiting if stopped.
+      if (ShouldStop) // Avoid waiting if stopped.
         break;
       // Wait until this is notified to stop or `BuildIndexPeriodMs` has past.
       IndexCV.wait_for(Lock, std::chrono::milliseconds(BuildIndexPeriodMs));
-      if (ShouldStop)  // Avoid rebuilding index if stopped.
+      if (ShouldStop) // Avoid rebuilding index if stopped.
         break;
     }
     if (!SymbolsUpdatedSinceLastIndex.exchange(false))
@@ -368,56 +376,44 @@
   }
 }
 
-Error BackgroundIndex::index(tooling::CompileCommand Cmd,
-                             BackgroundIndexStorage *IndexStorage) {
+llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd,
+                                   BackgroundIndexStorage *IndexStorage) {
   trace::Span Tracer("BackgroundIndex");
   SPAN_ATTACH(Tracer, "file", Cmd.Filename);
-  SmallString<128> AbsolutePath;
-  if (sys::path::is_absolute(Cmd.Filename)) {
-    AbsolutePath = Cmd.Filename;
-  } else {
-    AbsolutePath = Cmd.Directory;
-    sys::path::append(AbsolutePath, Cmd.Filename);
-  }
+  auto AbsolutePath = getAbsolutePath(Cmd);
 
   auto FS = FSProvider.getFileSystem();
   auto Buf = FS->getBufferForFile(AbsolutePath);
   if (!Buf)
-    return errorCodeToError(Buf.getError());
+    return llvm::errorCodeToError(Buf.getError());
   auto Hash = digest(Buf->get()->getBuffer());
 
   // Take a snapshot of the digests to avoid locking for each file in the TU.
   llvm::StringMap<FileDigest> DigestsSnapshot;
   {
     std::lock_guard<std::mutex> Lock(DigestsMu);
-    if (IndexedFileDigests.lookup(AbsolutePath) == Hash) {
-      vlog("No need to index {0}, already up to date", AbsolutePath);
-      return Error::success();
-    }
-
     DigestsSnapshot = IndexedFileDigests;
   }
 
-  log("Indexing {0} (digest:={1})", Cmd.Filename, toHex(Hash));
+  vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
   ParseInputs Inputs;
   Inputs.FS = std::move(FS);
   Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory);
   Inputs.CompileCommand = std::move(Cmd);
   auto CI = buildCompilerInvocation(Inputs);
   if (!CI)
-    return createStringError(inconvertibleErrorCode(),
-                             "Couldn't build compiler invocation");
+    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);
   if (!Clang)
-    return createStringError(inconvertibleErrorCode(),
-                             "Couldn't build compiler instance");
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Couldn't build compiler instance");
 
   SymbolCollector::Options IndexOpts;
-  StringMap<FileDigest> FilesToUpdate;
-  IndexOpts.FileFilter = createFileFilter(DigestsSnapshot, FilesToUpdate);
+  IndexOpts.FileFilter = createFileFilter(DigestsSnapshot);
   IndexFileIn Index;
   auto Action = createStaticIndexingAction(
       IndexOpts, [&](SymbolSlab S) { Index.Symbols = std::move(S); },
@@ -431,19 +427,21 @@
 
   const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front();
   if (!Action->BeginSourceFile(*Clang, Input))
-    return createStringError(inconvertibleErrorCode(),
-                             "BeginSourceFile() failed");
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "BeginSourceFile() failed");
   if (!Action->Execute())
-    return createStringError(inconvertibleErrorCode(), "Execute() failed");
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Execute() failed");
   Action->EndSourceFile();
   if (Clang->hasDiagnostics() &&
       Clang->getDiagnostics().hasUncompilableErrorOccurred()) {
-    return createStringError(inconvertibleErrorCode(),
-                             "IndexingAction failed: has uncompilable errors");
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "IndexingAction failed: has uncompilable errors");
   }
 
-  assert(Index.Symbols && Index.Refs && Index.Sources
-     && "Symbols, Refs and Sources must be set.");
+  assert(Index.Symbols && Index.Refs && Index.Sources &&
+         "Symbols, Refs and Sources must be set.");
 
   log("Indexed {0} ({1} symbols, {2} refs, {3} files)",
       Inputs.CompileCommand.Filename, Index.Symbols->size(),
@@ -452,13 +450,7 @@
   SPAN_ATTACH(Tracer, "refs", int(Index.Refs->numRefs()));
   SPAN_ATTACH(Tracer, "sources", int(Index.Sources->size()));
 
-  update(AbsolutePath, std::move(Index), FilesToUpdate, IndexStorage);
-  {
-    // Make sure hash for the main file is always updated even if there is no
-    // index data in it.
-    std::lock_guard<std::mutex> Lock(DigestsMu);
-    IndexedFileDigests[AbsolutePath] = Hash;
-  }
+  update(AbsolutePath, std::move(Index), DigestsSnapshot, IndexStorage);
 
   if (BuildIndexPeriodMs > 0)
     SymbolsUpdatedSinceLastIndex = true;
@@ -466,7 +458,152 @@
     reset(
         IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge));
 
-  return Error::success();
+  return llvm::Error::success();
+}
+
+std::vector<BackgroundIndex::Source>
+BackgroundIndex::loadShard(const tooling::CompileCommand &Cmd,
+                           BackgroundIndexStorage *IndexStorage,
+                           llvm::StringSet<> &LoadedShards) {
+  struct ShardInfo {
+    std::string AbsolutePath;
+    std::unique_ptr<IndexFileIn> Shard;
+    FileDigest Digest;
+  };
+  std::vector<ShardInfo> IntermediateSymbols;
+  // Make sure we don't have duplicate elements in the queue. Keys are absolute
+  // paths.
+  llvm::StringSet<> InQueue;
+  auto FS = FSProvider.getFileSystem();
+  // Dependencies of this TU, paired with the information about whether they
+  // need to be re-indexed or not.
+  std::vector<Source> Dependencies;
+  std::queue<Source> ToVisit;
+  std::string AbsolutePath = getAbsolutePath(Cmd).str();
+  // Up until we load the shard related to a dependency it needs to be
+  // re-indexed.
+  ToVisit.emplace(AbsolutePath, true);
+  InQueue.insert(AbsolutePath);
+  // Goes over each dependency.
+  while (!ToVisit.empty()) {
+    Dependencies.push_back(std::move(ToVisit.front()));
+    // Dependencies is not modified during the rest of the loop, so it is safe
+    // to keep the reference.
+    auto &CurDependency = Dependencies.back();
+    ToVisit.pop();
+    // If we have already seen this shard before(either loaded or failed) don't
+    // re-try again. Since the information in the shard won't change from one TU
+    // to another.
+    if (!LoadedShards.try_emplace(CurDependency.Path).second) {
+      // If the dependency needs to be re-indexed, first occurence would already
+      // have detected that, so we don't need to issue it again.
+      CurDependency.NeedsReIndexing = false;
+      continue;
+    }
+
+    auto Shard = IndexStorage->loadShard(CurDependency.Path);
+    if (!Shard || !Shard->Sources) {
+      // File will be returned as requiring re-indexing to caller.
+      vlog("Failed to load shard: {0}", CurDependency.Path);
+      continue;
+    }
+    // These are the edges in the include graph for current dependency.
+    for (const auto &I : *Shard->Sources) {
+      auto U = URI::parse(I.getKey());
+      if (!U)
+        continue;
+      auto AbsolutePath = URI::resolve(*U, CurDependency.Path);
+      if (!AbsolutePath)
+        continue;
+      // Add file as dependency if haven't seen before.
+      if (InQueue.try_emplace(*AbsolutePath).second)
+        ToVisit.emplace(*AbsolutePath, true);
+      // The node contains symbol information only for current file, the rest is
+      // just edges.
+      if (*AbsolutePath != CurDependency.Path)
+        continue;
+
+      // We found source file info for current dependency.
+      assert(I.getValue().Digest != FileDigest{{0}} && "Digest is empty?");
+      ShardInfo SI;
+      SI.AbsolutePath = CurDependency.Path;
+      SI.Shard = std::move(Shard);
+      SI.Digest = I.getValue().Digest;
+      IntermediateSymbols.push_back(std::move(SI));
+      // Check if the source needs re-indexing.
+      // Get the digest, skip it if file doesn't exist.
+      auto Buf = FS->getBufferForFile(CurDependency.Path);
+      if (!Buf) {
+        elog("Couldn't get buffer for file: {0}: {1}", CurDependency.Path,
+             Buf.getError().message());
+        continue;
+      }
+      // If digests match then dependency doesn't need re-indexing.
+      CurDependency.NeedsReIndexing =
+          digest(Buf->get()->getBuffer()) != I.getValue().Digest;
+    }
+  }
+  // Load shard information into background-index.
+  {
+    std::lock_guard<std::mutex> Lock(DigestsMu);
+    // This can override a newer version that is added in another thread,
+    // if this thread sees the older version but finishes later. This
+    // should be rare in practice.
+    for (const ShardInfo &SI : IntermediateSymbols) {
+      auto SS =
+          SI.Shard->Symbols
+              ? llvm::make_unique<SymbolSlab>(std::move(*SI.Shard->Symbols))
+              : nullptr;
+      auto RS = SI.Shard->Refs
+                    ? llvm::make_unique<RefSlab>(std::move(*SI.Shard->Refs))
+                    : nullptr;
+      IndexedFileDigests[SI.AbsolutePath] = SI.Digest;
+      IndexedSymbols.update(SI.AbsolutePath, std::move(SS), std::move(RS));
+    }
+  }
+
+  return Dependencies;
+}
+
+// Goes over each changed file and loads them from index. Returns the list of
+// TUs that had out-of-date/no shards.
+std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>>
+BackgroundIndex::loadShards(std::vector<std::string> ChangedFiles) {
+  std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>>
+      NeedsReIndexing;
+  // Keeps track of the files that will be reindexed, to make sure we won't
+  // re-index same dependencies more than once. Keys are AbsolutePaths.
+  llvm::StringSet<> FilesToIndex;
+  // Keeps track of the loaded shards to make sure we don't perform redundant
+  // disk IO. Keys are absolute paths.
+  llvm::StringSet<> LoadedShards;
+  for (const auto &File : ChangedFiles) {
+    ProjectInfo PI;
+    auto Cmd = CDB.getCompileCommand(File, &PI);
+    if (!Cmd)
+      continue;
+    BackgroundIndexStorage *IndexStorage = IndexStorageFactory(PI.SourceRoot);
+    auto Dependencies = loadShard(*Cmd, IndexStorage, LoadedShards);
+    for (const auto &Dependency : Dependencies) {
+      if (!Dependency.NeedsReIndexing || FilesToIndex.count(Dependency.Path))
+        continue;
+      // FIXME: Currently, we simply schedule indexing on a TU whenever any of
+      // its dependencies needs re-indexing. We might do it smarter by figuring
+      // out a minimal set of TUs that will cover all the stale dependencies.
+      vlog("Enqueueing TU {0} because its dependency {1} needs re-indexing.",
+           Cmd->Filename, Dependency.Path);
+      NeedsReIndexing.push_back({std::move(*Cmd), IndexStorage});
+      // Mark all of this TU's dependencies as to-be-indexed so that we won't
+      // try to re-index those.
+      for (const auto &Dependency : Dependencies)
+        FilesToIndex.insert(Dependency.Path);
+      break;
+    }
+  }
+  vlog("Loaded all shards");
+  reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge));
+
+  return NeedsReIndexing;
 }
 
 } // namespace clangd
diff --git a/clangd/index/Background.h b/clangd/index/Background.h
index 3318f4f..808c03a 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -68,20 +67,18 @@
   /// 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.
   // The indexing happens in a background thread, so the symbols will be
   // available sometime later.
   void enqueue(const std::vector<std::string> &ChangedFiles);
-  void enqueue(const std::string &File);
 
   // Cause background threads to stop after ther current task, any remaining
   // tasks will be discarded.
@@ -92,14 +89,14 @@
   blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
 
 private:
-  /// Given index results from a TU, only update files in \p FilesToUpdate.
-  /// Also stores new index information on IndexStorage.
+  /// Given index results from a TU, only update symbols coming from files with
+  /// different digests than \p DigestsSnapshot. Also stores new index
+  /// information on IndexStorage.
   void update(llvm::StringRef MainFile, IndexFileIn Index,
-              const llvm::StringMap<FileDigest> &FilesToUpdate,
+              const llvm::StringMap<FileDigest> &DigestsSnapshot,
               BackgroundIndexStorage *IndexStorage);
 
   // configuration
-  std::string ResourceDir;
   const FileSystemProvider &FSProvider;
   const GlobalCompilationDatabase &CDB;
   Context BackgroundContext;
@@ -118,6 +115,21 @@
   std::mutex DigestsMu;
 
   BackgroundIndexStorage::Factory IndexStorageFactory;
+  struct Source {
+    std::string Path;
+    bool NeedsReIndexing;
+    Source(llvm::StringRef Path, bool NeedsReIndexing)
+        : Path(Path), NeedsReIndexing(NeedsReIndexing) {}
+  };
+  // Loads the shards for a single TU and all of its dependencies. Returns the
+  // list of sources and whether they need to be re-indexed.
+  std::vector<Source> loadShard(const tooling::CompileCommand &Cmd,
+                                BackgroundIndexStorage *IndexStorage,
+                                llvm::StringSet<> &LoadedShards);
+  // Tries to load shards for the ChangedFiles.
+  std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>>
+  loadShards(std::vector<std::string> ChangedFiles);
+  void enqueue(tooling::CompileCommand Cmd, BackgroundIndexStorage *Storage);
 
   // queue management
   using Task = std::function<void()>;
diff --git a/clangd/index/BackgroundIndexStorage.cpp b/clangd/index/BackgroundIndexStorage.cpp
index a83bec6..266b18c 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/CanonicalIncludes.cpp b/clangd/index/CanonicalIncludes.cpp
index 0cc44fe..6fa366d 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,49 +12,50 @@
 #include "llvm/Support/Path.h"
 #include <algorithm>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 const char IWYUPragma[] = "// IWYU pragma: private, include ";
 } // namespace
 
-void CanonicalIncludes::addPathSuffixMapping(StringRef Suffix,
-                                             StringRef CanonicalPath) {
-  int Components =
-      std::distance(sys::path::begin(Suffix), sys::path::end(Suffix));
+void CanonicalIncludes::addPathSuffixMapping(llvm::StringRef Suffix,
+                                             llvm::StringRef CanonicalPath) {
+  int Components = std::distance(llvm::sys::path::begin(Suffix),
+                                 llvm::sys::path::end(Suffix));
   MaxSuffixComponents = std::max(MaxSuffixComponents, Components);
   SuffixHeaderMapping[Suffix] = CanonicalPath;
 }
 
-void CanonicalIncludes::addMapping(StringRef Path, StringRef CanonicalPath) {
+void CanonicalIncludes::addMapping(llvm::StringRef Path,
+                                   llvm::StringRef CanonicalPath) {
   FullPathMapping[Path] = CanonicalPath;
 }
 
-void CanonicalIncludes::addSymbolMapping(StringRef QualifiedName,
-                                         StringRef CanonicalPath) {
+void CanonicalIncludes::addSymbolMapping(llvm::StringRef QualifiedName,
+                                         llvm::StringRef CanonicalPath) {
   this->SymbolMapping[QualifiedName] = CanonicalPath;
 }
 
-StringRef CanonicalIncludes::mapHeader(ArrayRef<std::string> Headers,
-                                       StringRef QualifiedName) const {
+llvm::StringRef
+CanonicalIncludes::mapHeader(llvm::ArrayRef<std::string> Headers,
+                             llvm::StringRef QualifiedName) const {
   assert(!Headers.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, [](StringRef Include) {
+  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.
-  StringRef Header = *I;
+  llvm::StringRef Header = *I;
   // If Header is not expected be included (e.g. .cc file), we fall back to
   // the declaring header.
-  StringRef Ext = sys::path::extension(Header).trim('.');
+  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);
@@ -68,7 +68,8 @@
     return MapIt->second;
 
   int Components = 1;
-  for (auto It = sys::path::rbegin(Header), End = sys::path::rend(Header);
+  for (auto It = llvm::sys::path::rbegin(Header),
+            End = llvm::sys::path::rend(Header);
        It != End && Components <= MaxSuffixComponents; ++It, ++Components) {
     auto SubPath = Header.substr(It->data() - Header.begin());
     auto MappingIt = SuffixHeaderMapping.find(SubPath);
@@ -85,7 +86,7 @@
     PragmaCommentHandler(CanonicalIncludes *Includes) : Includes(Includes) {}
 
     bool HandleComment(Preprocessor &PP, SourceRange Range) override {
-      StringRef Text =
+      llvm::StringRef Text =
           Lexer::getSourceText(CharSourceRange::getCharRange(Range),
                                PP.getSourceManager(), PP.getLangOpts());
       if (!Text.consume_front(IWYUPragma))
diff --git a/clangd/index/CanonicalIncludes.h b/clangd/index/CanonicalIncludes.h
index 3751b00..c9baf0a 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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp
index b944c72..bc102d2 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,6 +10,7 @@
 #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"
@@ -24,20 +24,16 @@
 #include "llvm/ADT/StringRef.h"
 #include <memory>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
 static std::pair<SymbolSlab, RefSlab>
 indexSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
-             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;
 
@@ -49,7 +45,7 @@
   if (IsIndexMainAST) {
     // We only collect refs when indexing main AST.
     CollectorOpts.RefFilter = RefKind::All;
-  }else {
+  } else {
     IndexOpts.IndexMacrosInPreprocessor = true;
     CollectorOpts.CollectMacro = true;
   }
@@ -74,16 +70,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;
 }
@@ -116,7 +112,7 @@
   std::vector<Symbol> SymsStorage;
   switch (DuplicateHandle) {
   case DuplicateHandling::Merge: {
-    DenseMap<SymbolID, Symbol> Merged;
+    llvm::DenseMap<SymbolID, Symbol> Merged;
     for (const auto &Slab : SymbolSlabs) {
       for (const auto &Sym : *Slab) {
         auto I = Merged.try_emplace(Sym.ID, Sym);
@@ -143,9 +139,9 @@
   }
 
   std::vector<Ref> RefsStorage; // Contiguous ranges for each SymbolID.
-  DenseMap<SymbolID, ArrayRef<Ref>> AllRefs;
+  llvm::DenseMap<SymbolID, llvm::ArrayRef<Ref>> AllRefs;
   {
-    DenseMap<SymbolID, SmallVector<Ref, 4>> MergedRefs;
+    llvm::DenseMap<SymbolID, llvm::SmallVector<Ref, 4>> MergedRefs;
     size_t Count = 0;
     for (const auto &RefSlab : RefSlabs)
       for (const auto &Sym : *RefSlab) {
@@ -161,8 +157,8 @@
       llvm::copy(SymRefs, back_inserter(RefsStorage));
       AllRefs.try_emplace(
           Sym.first,
-          ArrayRef<Ref>(&RefsStorage[RefsStorage.size() - SymRefs.size()],
-                        SymRefs.size()));
+          llvm::ArrayRef<Ref>(&RefsStorage[RefsStorage.size() - SymRefs.size()],
+                              SymRefs.size()));
     }
   }
 
@@ -177,13 +173,13 @@
   switch (Type) {
   case IndexType::Light:
     return llvm::make_unique<MemIndex>(
-        make_pointee_range(AllSymbols), std::move(AllRefs),
+        llvm::make_pointee_range(AllSymbols), std::move(AllRefs),
         std::make_tuple(std::move(SymbolSlabs), std::move(RefSlabs),
                         std::move(RefsStorage), std::move(SymsStorage)),
         StorageSize);
   case IndexType::Heavy:
     return llvm::make_unique<dex::Dex>(
-        make_pointee_range(AllSymbols), std::move(AllRefs),
+        llvm::make_pointee_range(AllSymbols), std::move(AllRefs),
         std::make_tuple(std::move(SymbolSlabs), std::move(RefSlabs),
                         std::move(RefsStorage), std::move(SymsStorage)),
         StorageSize);
@@ -197,8 +193,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..f1e37c3 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,7 @@
 #include "Index.h"
 #include "MemIndex.h"
 #include "Merge.h"
+#include "index/CanonicalIncludes.h"
 #include "clang/Lex/Preprocessor.h"
 #include <memory>
 
@@ -85,7 +85,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 +126,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 dd4b5eb..36c591d 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,7 +13,6 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/raw_ostream.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -35,14 +33,14 @@
   Column = Col;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const SymbolLocation &L) {
+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() << ")";
 }
 
-raw_ostream &operator<<(raw_ostream &OS, SymbolOrigin O) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) {
   if (O == SymbolOrigin::Unknown)
     return OS << "unknown";
   constexpr static char Sigils[] = "ADSM4567";
@@ -52,18 +50,18 @@
   return OS;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, Symbol::SymbolFlag F) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) {
   if (F == Symbol::None)
     return OS << "None";
-  std::string s;
+  std::string S;
   if (F & Symbol::Deprecated)
-    s += "deprecated|";
+    S += "deprecated|";
   if (F & Symbol::IndexedForCodeCompletion)
-    s += "completion|";
-  return OS << StringRef(s).rtrim('|');
+    S += "completion|";
+  return OS << llvm::StringRef(S).rtrim('|');
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Symbol &S) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
   return OS << S.Scope << S.Name;
 }
 
@@ -85,8 +83,8 @@
 }
 
 // Copy the underlying data of the symbol into the owned arena.
-static void own(Symbol &S, UniqueStringSaver &Strings) {
-  visitStrings(S, [&](StringRef &V) { V = Strings.save(V); });
+static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
+  visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); });
 }
 
 void SymbolSlab::Builder::insert(const Symbol &S) {
@@ -106,14 +104,14 @@
   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.
-  BumpPtrAllocator NewArena;
-  UniqueStringSaver Strings(NewArena);
+  llvm::BumpPtrAllocator NewArena;
+  llvm::UniqueStringSaver Strings(NewArena);
   for (auto &S : Symbols)
     own(S, Strings);
   return SymbolSlab(std::move(NewArena), std::move(Symbols));
 }
 
-raw_ostream &operator<<(raw_ostream &OS, RefKind K) {
+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"};
@@ -129,7 +127,7 @@
   return OS;
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const Ref &R) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) {
   return OS << R.Location << ":" << R.Kind;
 }
 
@@ -143,7 +141,7 @@
 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, ArrayRef<Ref>>> Result;
+  std::vector<std::pair<SymbolID, llvm::ArrayRef<Ref>>> Result;
   Result.reserve(Refs.size());
   size_t NumRefs = 0;
   for (auto &Sym : Refs) {
@@ -155,7 +153,7 @@
     NumRefs += SymRefs.size();
     auto *Array = Arena.Allocate<Ref>(SymRefs.size());
     std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array);
-    Result.emplace_back(Sym.first, ArrayRef<Ref>(Array, SymRefs.size()));
+    Result.emplace_back(Sym.first, llvm::ArrayRef<Ref>(Array, SymRefs.size()));
   }
   return RefSlab(std::move(Result), std::move(Arena), NumRefs);
 }
@@ -174,40 +172,42 @@
   return Index;
 }
 
-bool fromJSON(const json::Value &Parameters, FuzzyFindRequest &Request) {
-  json::ObjectMapper O(Parameters);
+bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request) {
+  llvm::json::ObjectMapper O(Parameters);
   int64_t Limit;
   bool OK =
       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;
 }
 
-json::Value toJSON(const FuzzyFindRequest &Request) {
-  return json::Object{
+llvm::json::Value toJSON(const FuzzyFindRequest &Request) {
+  return llvm::json::Object{
       {"Query", Request.Query},
-      {"Scopes", json::Array{Request.Scopes}},
+      {"Scopes", llvm::json::Array{Request.Scopes}},
       {"AnyScope", Request.AnyScope},
       {"Limit", Request.Limit},
       {"RestrictForCodeCompletion", Request.RestrictForCodeCompletion},
-      {"ProximityPaths", json::Array{Request.ProximityPaths}},
+      {"ProximityPaths", llvm::json::Array{Request.ProximityPaths}},
+      {"PreferredTypes", llvm::json::Array{Request.PreferredTypes}},
   };
 }
 
 bool SwapIndex::fuzzyFind(const FuzzyFindRequest &R,
-                          function_ref<void(const Symbol &)> CB) const {
+                          llvm::function_ref<void(const Symbol &)> CB) const {
   return snapshot()->fuzzyFind(R, CB);
 }
 void SwapIndex::lookup(const LookupRequest &R,
-                       function_ref<void(const Symbol &)> CB) const {
+                       llvm::function_ref<void(const Symbol &)> CB) const {
   return snapshot()->lookup(R, CB);
 }
 void SwapIndex::refs(const RefsRequest &R,
-                     function_ref<void(const Ref &)> CB) const {
+                     llvm::function_ref<void(const Ref &)> CB) const {
   return snapshot()->refs(R, CB);
 }
 size_t SwapIndex::estimateMemoryUsage() const {
diff --git a/clangd/index/Index.h b/clangd/index/Index.h
index a5552d4..4f6feb9 100644
--- a/clangd/index/Index.h
+++ b/clangd/index/Index.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -185,19 +184,23 @@
   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 {
@@ -223,17 +226,22 @@
   ///   - 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;
@@ -446,14 +454,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); }
 };
@@ -467,6 +476,10 @@
 struct RefsRequest {
   llvm::DenseSet<SymbolID> IDs;
   RefKind Filter = RefKind::All;
+  /// If set, limit the number of refers returned from the index. The index may
+  /// choose to return less than this, e.g. it tries to avoid returning stale
+  /// results.
+  llvm::Optional<uint32_t> Limit;
 };
 
 /// Interface for symbol indexes that can be used for searching or
diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp
index 63e1155..a6df64b 100644
--- a/clangd/index/IndexAction.cpp
+++ b/clangd/index/IndexAction.cpp
@@ -4,7 +4,6 @@
 #include "clang/Index/IndexingAction.h"
 #include "clang/Tooling/Tooling.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -63,10 +62,10 @@
 
   // Add edges from including files to includes.
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
-                          StringRef FileName, bool IsAngled,
+                          llvm::StringRef FileName, bool IsAngled,
                           CharSourceRange FilenameRange, const FileEntry *File,
-                          StringRef SearchPath, StringRef RelativePath,
-                          const Module *Imported,
+                          llvm::StringRef SearchPath,
+                          llvm::StringRef RelativePath, const Module *Imported,
                           SrcMgr::CharacteristicKind FileType) override {
     auto IncludeURI = toURI(File);
     if (!IncludeURI)
@@ -116,8 +115,8 @@
         Includes(std::move(Includes)),
         PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {}
 
-  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
-                                                 StringRef InFile) override {
+  std::unique_ptr<ASTConsumer>
+  CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
     CI.getPreprocessor().addCommentHandler(PragmaHandler.get());
     if (IncludeGraphCallback != nullptr)
       CI.getPreprocessor().addPPCallbacks(
@@ -137,7 +136,7 @@
     const auto &CI = getCompilerInstance();
     if (CI.hasDiagnostics() &&
         CI.getDiagnostics().hasUncompilableErrorOccurred()) {
-      errs() << "Skipping TU due to uncompilable errors\n";
+      llvm::errs() << "Skipping TU due to uncompilable errors\n";
       return;
     }
     SymbolsCallback(Collector->takeSymbols());
diff --git a/clangd/index/IndexAction.h b/clangd/index/IndexAction.h
index f2c5298..748b26e 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/MemIndex.cpp b/clangd/index/MemIndex.cpp
index 42340e8..531d1f6 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
 //
 //===-------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "Quality.h"
 #include "Trace.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -25,8 +23,9 @@
                                      BackingDataSize);
 }
 
-bool MemIndex::fuzzyFind(const FuzzyFindRequest &Req,
-                         function_ref<void(const Symbol &)> Callback) const {
+bool MemIndex::fuzzyFind(
+    const FuzzyFindRequest &Req,
+    llvm::function_ref<void(const Symbol &)> Callback) const {
   assert(!StringRef(Req.Query).contains("::") &&
          "There must be no :: in query.");
   trace::Span Tracer("MemIndex fuzzyFind");
@@ -39,7 +38,7 @@
     const Symbol *Sym = Pair.second;
 
     // Exact match against all possible scopes.
-    if (!Req.AnyScope && !is_contained(Req.Scopes, Sym->Scope))
+    if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope))
       continue;
     if (Req.RestrictForCodeCompletion &&
         !(Sym->Flags & Symbol::IndexedForCodeCompletion))
@@ -57,7 +56,7 @@
 }
 
 void MemIndex::lookup(const LookupRequest &Req,
-                      function_ref<void(const Symbol &)> Callback) const {
+                      llvm::function_ref<void(const Symbol &)> Callback) const {
   trace::Span Tracer("MemIndex lookup");
   for (const auto &ID : Req.IDs) {
     auto I = Index.find(ID);
@@ -67,15 +66,20 @@
 }
 
 void MemIndex::refs(const RefsRequest &Req,
-                    function_ref<void(const Ref &)> Callback) const {
+                    llvm::function_ref<void(const Ref &)> Callback) const {
   trace::Span Tracer("MemIndex refs");
+  uint32_t Remaining =
+      Req.Limit.getValueOr(std::numeric_limits<uint32_t>::max());
   for (const auto &ReqID : Req.IDs) {
     auto SymRefs = Refs.find(ReqID);
     if (SymRefs == Refs.end())
       continue;
-    for (const auto &O : SymRefs->second)
-      if (static_cast<int>(Req.Filter & O.Kind))
+    for (const auto &O : SymRefs->second) {
+      if (Remaining > 0 && static_cast<int>(Req.Filter & O.Kind)) {
+        --Remaining;
         Callback(O);
+      }
+    }
   }
 }
 
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 42616f0..65e9b86 100644
--- a/clangd/index/Merge.cpp
+++ b/clangd/index/Merge.cpp
@@ -1,20 +1,22 @@
 //===--- 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/Index.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>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -23,8 +25,9 @@
 //          - find the generating file from each Symbol which is Static-only
 //          - ask Dynamic if it has that file (needs new SymbolIndex method)
 //          - if so, drop the Symbol.
-bool MergedIndex::fuzzyFind(const FuzzyFindRequest &Req,
-                            function_ref<void(const Symbol &)> Callback) const {
+bool MergedIndex::fuzzyFind(
+    const FuzzyFindRequest &Req,
+    llvm::function_ref<void(const Symbol &)> Callback) const {
   // We can't step through both sources in parallel. So:
   //  1) query all dynamic symbols, slurping results into a slab
   //  2) query the static symbols, for each one:
@@ -43,7 +46,7 @@
   });
   SymbolSlab Dyn = std::move(DynB).build();
 
-  DenseSet<SymbolID> SeenDynamicSymbols;
+  llvm::DenseSet<SymbolID> SeenDynamicSymbols;
   More |= Static->fuzzyFind(Req, [&](const Symbol &S) {
     auto DynS = Dyn.find(S.ID);
     ++StaticCount;
@@ -62,8 +65,9 @@
   return More;
 }
 
-void MergedIndex::lookup(const LookupRequest &Req,
-                         function_ref<void(const Symbol &)> Callback) const {
+void MergedIndex::lookup(
+    const LookupRequest &Req,
+    llvm::function_ref<void(const Symbol &)> Callback) const {
   trace::Span Tracer("MergedIndex lookup");
   SymbolSlab::Builder B;
 
@@ -84,8 +88,10 @@
 }
 
 void MergedIndex::refs(const RefsRequest &Req,
-                       function_ref<void(const Ref &)> Callback) const {
+                       llvm::function_ref<void(const Ref &)> Callback) const {
   trace::Span Tracer("MergedIndex refs");
+  uint32_t Remaining =
+      Req.Limit.getValueOr(std::numeric_limits<uint32_t>::max());
   // We don't want duplicated refs from the static/dynamic indexes,
   // and we can't reliably duplicate them because offsets may differ slightly.
   // We consider the dynamic index authoritative and report all its refs,
@@ -94,17 +100,41 @@
   // FIXME: The heuristic fails if the dynamic index contains a file, but all
   // refs were removed (we will report stale ones from the static index).
   // Ultimately we should explicit check which index has the file instead.
-  StringSet<> DynamicIndexFileURIs;
+  llvm::StringSet<> DynamicIndexFileURIs;
   Dynamic->refs(Req, [&](const Ref &O) {
     DynamicIndexFileURIs.insert(O.Location.FileURI);
     Callback(O);
+    --Remaining;
   });
+  if (Remaining == 0)
+    return;
+  // We return less than Req.Limit if static index returns more refs for dirty
+  // files.
   Static->refs(Req, [&](const Ref &O) {
-    if (!DynamicIndexFileURIs.count(O.Location.FileURI))
+    if (Remaining > 0 && !DynamicIndexFileURIs.count(O.Location.FileURI)) {
+      --Remaining;
       Callback(O);
+    }
   });
 }
 
+// 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.
@@ -119,12 +149,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;
@@ -134,6 +163,8 @@
     S.Documentation = O.Documentation;
   if (S.ReturnType == "")
     S.ReturnType = O.ReturnType;
+  if (S.Type == "")
+    S.Type = O.Type;
   for (const auto &OI : O.IncludeHeaders) {
     bool Found = false;
     for (auto &SI : S.IncludeHeaders) {
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/Serialization.cpp b/clangd/index/Serialization.cpp
index 1d17a42..20c43ab 100644
--- a/clangd/index/Serialization.cpp
+++ b/clangd/index/Serialization.cpp
@@ -1,9 +1,8 @@
 //===-- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,12 +16,12 @@
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
-Error makeError(const Twine &Msg) {
-  return make_error<StringError>(Msg, inconvertibleErrorCode());
+llvm::Error makeError(const llvm::Twine &Msg) {
+  return llvm::make_error<llvm::StringError>(Msg,
+                                             llvm::inconvertibleErrorCode());
 }
 
 // IO PRIMITIVES
@@ -40,14 +39,14 @@
   bool Err = false;
 
 public:
-  Reader(StringRef Data) : Begin(Data.begin()), End(Data.end()) {}
+  Reader(llvm::StringRef Data) : Begin(Data.begin()), End(Data.end()) {}
   // The "error" bit is set by reading past EOF or reading invalid data.
   // When in an error state, reads may return zero values: callers should check.
   bool err() const { return Err; }
   // Did we read all the data, or encounter an error?
   bool eof() const { return Begin == End || Err; }
   // All the data we didn't read yet.
-  StringRef rest() const { return StringRef(Begin, End - Begin); }
+  llvm::StringRef rest() const { return llvm::StringRef(Begin, End - Begin); }
 
   uint8_t consume8() {
     if (LLVM_UNLIKELY(Begin == End)) {
@@ -62,17 +61,17 @@
       Err = true;
       return 0;
     }
-    auto Ret = support::endian::read32le(Begin);
+    auto Ret = llvm::support::endian::read32le(Begin);
     Begin += 4;
     return Ret;
   }
 
-  StringRef consume(int N) {
+  llvm::StringRef consume(int N) {
     if (LLVM_UNLIKELY(Begin + N > End)) {
       Err = true;
-      return StringRef();
+      return llvm::StringRef();
     }
-    StringRef Ret(Begin, N);
+    llvm::StringRef Ret(Begin, N);
     Begin += N;
     return Ret;
   }
@@ -90,28 +89,28 @@
     return Val;
   }
 
-  StringRef consumeString(ArrayRef<StringRef> Strings) {
+  llvm::StringRef consumeString(llvm::ArrayRef<llvm::StringRef> Strings) {
     auto StringIndex = consumeVar();
     if (LLVM_UNLIKELY(StringIndex >= Strings.size())) {
       Err = true;
-      return StringRef();
+      return llvm::StringRef();
     }
     return Strings[StringIndex];
   }
 
   SymbolID consumeID() {
-    StringRef Raw = consume(SymbolID::RawSize); // short if truncated.
+    llvm::StringRef Raw = consume(SymbolID::RawSize); // short if truncated.
     return LLVM_UNLIKELY(err()) ? SymbolID() : SymbolID::fromRaw(Raw);
   }
 };
 
-void write32(uint32_t I, raw_ostream &OS) {
-  char buf[4];
-  support::endian::write32le(buf, I);
-  OS.write(buf, sizeof(buf));
+void write32(uint32_t I, llvm::raw_ostream &OS) {
+  char Buf[4];
+  llvm::support::endian::write32le(Buf, I);
+  OS.write(Buf, sizeof(Buf));
 }
 
-void writeVar(uint32_t I, raw_ostream &OS) {
+void writeVar(uint32_t I, llvm::raw_ostream &OS) {
   constexpr static uint8_t More = 1 << 7;
   if (LLVM_LIKELY(I < 1 << 7)) {
     OS.write(I);
@@ -142,10 +141,10 @@
 // Maps each string to a canonical representation.
 // Strings remain owned externally (e.g. by SymbolSlab).
 class StringTableOut {
-  DenseSet<StringRef> Unique;
-  std::vector<StringRef> Sorted;
+  llvm::DenseSet<llvm::StringRef> Unique;
+  std::vector<llvm::StringRef> Sorted;
   // Since strings are interned, look up can be by pointer.
-  DenseMap<std::pair<const char *, size_t>, unsigned> Index;
+  llvm::DenseMap<std::pair<const char *, size_t>, unsigned> Index;
 
 public:
   StringTableOut() {
@@ -154,22 +153,22 @@
     Unique.insert("");
   }
   // Add a string to the table. Overwrites S if an identical string exists.
-  void intern(StringRef &S) { S = *Unique.insert(S).first; };
+  void intern(llvm::StringRef &S) { S = *Unique.insert(S).first; };
   // Finalize the table and write it to OS. No more strings may be added.
-  void finalize(raw_ostream &OS) {
+  void finalize(llvm::raw_ostream &OS) {
     Sorted = {Unique.begin(), Unique.end()};
     llvm::sort(Sorted);
     for (unsigned I = 0; I < Sorted.size(); ++I)
       Index.try_emplace({Sorted[I].data(), Sorted[I].size()}, I);
 
     std::string RawTable;
-    for (StringRef S : Sorted) {
+    for (llvm::StringRef S : Sorted) {
       RawTable.append(S);
       RawTable.push_back(0);
     }
-    if (zlib::isAvailable()) {
-      SmallString<1> Compressed;
-      cantFail(zlib::compress(RawTable, Compressed));
+    if (llvm::zlib::isAvailable()) {
+      llvm::SmallString<1> Compressed;
+      llvm::cantFail(llvm::zlib::compress(RawTable, Compressed));
       write32(RawTable.size(), OS);
       OS << Compressed;
     } else {
@@ -178,7 +177,7 @@
     }
   }
   // Get the ID of an string, which must be interned. Table must be finalized.
-  unsigned index(StringRef S) const {
+  unsigned index(llvm::StringRef S) const {
     assert(!Sorted.empty() && "table not finalized");
     assert(Index.count({S.data(), S.size()}) && "string not interned");
     return Index.find({S.data(), S.size()})->second;
@@ -186,33 +185,33 @@
 };
 
 struct StringTableIn {
-  BumpPtrAllocator Arena;
-  std::vector<StringRef> Strings;
+  llvm::BumpPtrAllocator Arena;
+  std::vector<llvm::StringRef> Strings;
 };
 
-Expected<StringTableIn> readStringTable(StringRef Data) {
+llvm::Expected<StringTableIn> readStringTable(llvm::StringRef Data) {
   Reader R(Data);
   size_t UncompressedSize = R.consume32();
   if (R.err())
     return makeError("Truncated string table");
 
-  StringRef Uncompressed;
-  SmallString<1> UncompressedStorage;
+  llvm::StringRef Uncompressed;
+  llvm::SmallString<1> UncompressedStorage;
   if (UncompressedSize == 0) // No compression
     Uncompressed = R.rest();
   else {
-    if (Error E = llvm::zlib::uncompress(R.rest(), UncompressedStorage,
-                                         UncompressedSize))
+    if (llvm::Error E = llvm::zlib::uncompress(R.rest(), UncompressedStorage,
+                                               UncompressedSize))
       return std::move(E);
     Uncompressed = UncompressedStorage;
   }
 
   StringTableIn Table;
-  StringSaver Saver(Table.Arena);
+  llvm::StringSaver Saver(Table.Arena);
   R = Reader(Uncompressed);
   for (Reader R(Uncompressed); !R.eof();) {
     auto Len = R.rest().find(0);
-    if (Len == StringRef::npos)
+    if (Len == llvm::StringRef::npos)
       return makeError("Bad string table: not null terminated");
     Table.Strings.push_back(Saver.save(R.consume(Len)));
     R.consume8();
@@ -229,7 +228,7 @@
 //  - most numbers encode as varint
 
 void writeLocation(const SymbolLocation &Loc, const StringTableOut &Strings,
-                   raw_ostream &OS) {
+                   llvm::raw_ostream &OS) {
   writeVar(Strings.index(Loc.FileURI), OS);
   for (const auto &Endpoint : {Loc.Start, Loc.End}) {
     writeVar(Endpoint.line(), OS);
@@ -237,7 +236,8 @@
   }
 }
 
-SymbolLocation readLocation(Reader &Data, ArrayRef<StringRef> Strings) {
+SymbolLocation readLocation(Reader &Data,
+                            llvm::ArrayRef<llvm::StringRef> Strings) {
   SymbolLocation Loc;
   Loc.FileURI = Data.consumeString(Strings).data();
   for (auto *Endpoint : {&Loc.Start, &Loc.End}) {
@@ -261,7 +261,8 @@
 }
 
 void writeIncludeGraphNode(const IncludeGraphNode &IGN,
-                           const StringTableOut &Strings, raw_ostream &OS) {
+                           const StringTableOut &Strings,
+                           llvm::raw_ostream &OS) {
   OS.write(IGN.IsTU);
   writeVar(Strings.index(IGN.URI), OS);
   llvm::StringRef Hash(reinterpret_cast<const char *>(IGN.Digest.data()),
@@ -273,7 +274,7 @@
 }
 
 void writeSymbol(const Symbol &Sym, const StringTableOut &Strings,
-                 raw_ostream &OS) {
+                 llvm::raw_ostream &OS) {
   OS << Sym.ID.raw(); // TODO: once we start writing xrefs and posting lists,
                       // symbol IDs should probably be in a string table.
   OS.write(static_cast<uint8_t>(Sym.SymInfo.Kind));
@@ -300,7 +301,7 @@
     WriteInclude(Include);
 }
 
-Symbol readSymbol(Reader &Data, ArrayRef<StringRef> Strings) {
+Symbol readSymbol(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
   Symbol Sym;
   Sym.ID = Data.consumeID();
   Sym.SymInfo.Kind = static_cast<index::SymbolKind>(Data.consume8());
@@ -332,8 +333,8 @@
 //  - Ref[NumRefs]
 // Fields of Ref are encoded in turn, see implementation.
 
-void writeRefs(const SymbolID &ID, ArrayRef<Ref> Refs,
-               const StringTableOut &Strings, raw_ostream &OS) {
+void writeRefs(const SymbolID &ID, llvm::ArrayRef<Ref> Refs,
+               const StringTableOut &Strings, llvm::raw_ostream &OS) {
   OS << ID.raw();
   writeVar(Refs.size(), OS);
   for (const auto &Ref : Refs) {
@@ -342,8 +343,8 @@
   }
 }
 
-std::pair<SymbolID, std::vector<Ref>> readRefs(Reader &Data,
-                                               ArrayRef<StringRef> Strings) {
+std::pair<SymbolID, std::vector<Ref>>
+readRefs(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
   std::pair<SymbolID, std::vector<Ref>> Result;
   Result.first = Data.consumeID();
   Result.second.resize(Data.consumeVar());
@@ -368,17 +369,18 @@
 // data. Later we may want to support some backward compatibility.
 constexpr static uint32_t Version = 8;
 
-Expected<IndexFileIn> readRIFF(StringRef Data) {
+llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data) {
   auto RIFF = riff::readFile(Data);
   if (!RIFF)
     return RIFF.takeError();
   if (RIFF->Type != riff::fourCC("CdIx"))
     return makeError("wrong RIFF type");
-  StringMap<StringRef> Chunks;
+  llvm::StringMap<llvm::StringRef> Chunks;
   for (const auto &Chunk : RIFF->Chunks)
-    Chunks.try_emplace(StringRef(Chunk.ID.data(), Chunk.ID.size()), Chunk.Data);
+    Chunks.try_emplace(llvm::StringRef(Chunk.ID.data(), Chunk.ID.size()),
+                       Chunk.Data);
 
-  for (StringRef RequiredChunk : {"meta", "stri"})
+  for (llvm::StringRef RequiredChunk : {"meta", "stri"})
     if (!Chunks.count(RequiredChunk))
       return makeError("missing required chunk " + RequiredChunk);
 
@@ -439,14 +441,14 @@
     CB(Include);
 }
 
-void writeRIFF(const IndexFileOut &Data, raw_ostream &OS) {
+void writeRIFF(const IndexFileOut &Data, llvm::raw_ostream &OS) {
   assert(Data.Symbols && "An index file without symbols makes no sense!");
   riff::File RIFF;
   RIFF.Type = riff::fourCC("CdIx");
 
-  SmallString<4> Meta;
+  llvm::SmallString<4> Meta;
   {
-    raw_svector_ostream MetaOS(Meta);
+    llvm::raw_svector_ostream MetaOS(Meta);
     write32(Version, MetaOS);
   }
   RIFF.Chunks.push_back({riff::fourCC("meta"), Meta});
@@ -455,13 +457,15 @@
   std::vector<Symbol> Symbols;
   for (const auto &Sym : *Data.Symbols) {
     Symbols.emplace_back(Sym);
-    visitStrings(Symbols.back(), [&](StringRef &S) { Strings.intern(S); });
+    visitStrings(Symbols.back(),
+                 [&](llvm::StringRef &S) { Strings.intern(S); });
   }
   std::vector<IncludeGraphNode> Sources;
   if (Data.Sources)
     for (const auto &Source : *Data.Sources) {
       Sources.push_back(Source.getValue());
-      visitStrings(Sources.back(), [&](StringRef &S) { Strings.intern(S); });
+      visitStrings(Sources.back(),
+                   [&](llvm::StringRef &S) { Strings.intern(S); });
     }
 
   std::vector<std::pair<SymbolID, std::vector<Ref>>> Refs;
@@ -469,7 +473,7 @@
     for (const auto &Sym : *Data.Refs) {
       Refs.emplace_back(Sym);
       for (auto &Ref : Refs.back().second) {
-        StringRef File = Ref.Location.FileURI;
+        llvm::StringRef File = Ref.Location.FileURI;
         Strings.intern(File);
         Ref.Location.FileURI = File.data();
       }
@@ -478,14 +482,14 @@
 
   std::string StringSection;
   {
-    raw_string_ostream StringOS(StringSection);
+    llvm::raw_string_ostream StringOS(StringSection);
     Strings.finalize(StringOS);
   }
   RIFF.Chunks.push_back({riff::fourCC("stri"), StringSection});
 
   std::string SymbolSection;
   {
-    raw_string_ostream SymbolOS(SymbolSection);
+    llvm::raw_string_ostream SymbolOS(SymbolSection);
     for (const auto &Sym : Symbols)
       writeSymbol(Sym, Strings, SymbolOS);
   }
@@ -494,7 +498,7 @@
   std::string RefsSection;
   if (Data.Refs) {
     {
-      raw_string_ostream RefsOS(RefsSection);
+      llvm::raw_string_ostream RefsOS(RefsSection);
       for (const auto &Sym : Refs)
         writeRefs(Sym.first, Sym.second, Strings, RefsOS);
     }
@@ -504,7 +508,7 @@
   std::string SrcsSection;
   {
     {
-      raw_string_ostream SrcsOS(SrcsSection);
+      llvm::raw_string_ostream SrcsOS(SrcsSection);
       for (const auto &SF : Sources)
         writeIncludeGraphNode(SF, Strings, SrcsOS);
     }
@@ -517,10 +521,10 @@
 } // namespace
 
 // Defined in YAMLSerialization.cpp.
-void writeYAML(const IndexFileOut &, raw_ostream &);
-Expected<IndexFileIn> readYAML(StringRef);
+void writeYAML(const IndexFileOut &, llvm::raw_ostream &);
+llvm::Expected<IndexFileIn> readYAML(llvm::StringRef);
 
-raw_ostream &operator<<(raw_ostream &OS, const IndexFileOut &O) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IndexFileOut &O) {
   switch (O.Format) {
   case IndexFileFormat::RIFF:
     writeRIFF(O, OS);
@@ -532,22 +536,23 @@
   return OS;
 }
 
-Expected<IndexFileIn> readIndexFile(StringRef Data) {
+llvm::Expected<IndexFileIn> readIndexFile(llvm::StringRef Data) {
   if (Data.startswith("RIFF")) {
     return readRIFF(Data);
   } else if (auto YAMLContents = readYAML(Data)) {
     return std::move(*YAMLContents);
   } else {
     return makeError("Not a RIFF file and failed to parse as YAML: " +
-                     toString(YAMLContents.takeError()));
+                     llvm::toString(YAMLContents.takeError()));
   }
 }
 
-std::unique_ptr<SymbolIndex> loadIndex(StringRef SymbolFilename, bool UseDex) {
+std::unique_ptr<SymbolIndex> loadIndex(llvm::StringRef SymbolFilename,
+                                       bool UseDex) {
   trace::Span OverallTracer("LoadIndex");
-  auto Buffer = MemoryBuffer::getFile(SymbolFilename);
+  auto Buffer = llvm::MemoryBuffer::getFile(SymbolFilename);
   if (!Buffer) {
-    errs() << "Can't open " << SymbolFilename << "\n";
+    llvm::errs() << "Can't open " << SymbolFilename << "\n";
     return nullptr;
   }
 
@@ -561,7 +566,7 @@
       if (I->Refs)
         Refs = std::move(*I->Refs);
     } else {
-      errs() << "Bad Index: " << toString(I.takeError()) << "\n";
+      llvm::errs() << "Bad Index: " << llvm::toString(I.takeError()) << "\n";
       return nullptr;
     }
   }
diff --git a/clangd/index/Serialization.h b/clangd/index/Serialization.h
index c403b95..d81b896 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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp
index b78bc5f..cbbbd50 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -29,7 +28,6 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -51,38 +49,18 @@
 //
 // The Path can be a path relative to the build directory, or retrieved from
 // the SourceManager.
-Optional<std::string> toURI(const SourceManager &SM, StringRef Path,
-                            const SymbolCollector::Options &Opts) {
-  SmallString<128> AbsolutePath(Path);
-  if (std::error_code EC =
-          SM.getFileManager().getVirtualFileSystem()->makeAbsolute(
-              AbsolutePath))
-    log("Warning: could not make absolute file: {0}", EC.message());
-  if (sys::path::is_absolute(AbsolutePath)) {
-    // Handle the symbolic link path case where the current working directory
-    // (getCurrentWorkingDirectory) is a symlink./ We always want to the real
-    // file path (instead of the symlink path) for the  C++ symbols.
-    //
-    // Consider the following example:
-    //
-    //   src dir: /project/src/foo.h
-    //   current working directory (symlink): /tmp/build -> /project/src/
-    //
-    // The file path of Symbol is "/project/src/foo.h" instead of
-    // "/tmp/build/foo.h"
-    if (const DirectoryEntry *Dir = SM.getFileManager().getDirectory(
-            sys::path::parent_path(AbsolutePath.str()))) {
-      StringRef DirName = SM.getFileManager().getCanonicalName(Dir);
-      SmallString<128> AbsoluteFilename;
-      sys::path::append(AbsoluteFilename, DirName,
-                        sys::path::filename(AbsolutePath.str()));
-      AbsolutePath = AbsoluteFilename;
-    }
-  } else if (!Opts.FallbackDir.empty()) {
-    sys::fs::make_absolute(Opts.FallbackDir, AbsolutePath);
+std::string toURI(const SourceManager &SM, llvm::StringRef Path,
+                  const SymbolCollector::Options &Opts) {
+  llvm::SmallString<128> AbsolutePath(Path);
+  if (auto CanonPath =
+          getCanonicalPath(SM.getFileManager().getFile(Path), SM)) {
+    AbsolutePath = *CanonPath;
   }
-
-  sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true);
+  // We don't perform is_absolute check in an else branch because makeAbsolute
+  // might return a relative path on some InMemoryFileSystems.
+  if (!llvm::sys::path::is_absolute(AbsolutePath) && !Opts.FallbackDir.empty())
+    llvm::sys::fs::make_absolute(Opts.FallbackDir, AbsolutePath);
+  llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true);
   return URI::create(AbsolutePath).toString();
 }
 
@@ -122,7 +100,7 @@
   // will include OUTER_INNER and exclude some_enum_constant.
   // FIXME: the heuristic relies on naming style (i.e. no underscore in
   // user-defined names) and can be improved.
-  return (ND.getKind() != Decl::EnumConstant) || any_of(Name, islower);
+  return (ND.getKind() != Decl::EnumConstant) || llvm::any_of(Name, islower);
 }
 
 // We only collect #include paths for symbols that are suitable for global code
@@ -150,9 +128,9 @@
 /// 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.
-Optional<std::string> getIncludeHeader(StringRef QName, const SourceManager &SM,
-                                       SourceLocation Loc,
-                                       const SymbolCollector::Options &Opts) {
+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) {
@@ -168,7 +146,7 @@
   }
   if (Headers.empty())
     return None;
-  StringRef Header = Headers[0];
+  llvm::StringRef Header = Headers[0];
   if (Opts.Includes) {
     Header = Opts.Includes->mapHeader(Headers, QName);
     if (Header.startswith("<") || Header.startswith("\""))
@@ -206,22 +184,22 @@
 }
 
 // Return the symbol location of the token at \p TokLoc.
-Optional<SymbolLocation> getTokenLocation(SourceLocation TokLoc,
-                                          const SourceManager &SM,
-                                          const SymbolCollector::Options &Opts,
-                                          const clang::LangOptions &LangOpts,
-                                          std::string &FileURIStorage) {
-  auto U = toURI(SM, SM.getFilename(TokLoc), Opts);
-  if (!U)
+llvm::Optional<SymbolLocation>
+getTokenLocation(SourceLocation TokLoc, const SourceManager &SM,
+                 const SymbolCollector::Options &Opts,
+                 const clang::LangOptions &LangOpts,
+                 std::string &FileURIStorage) {
+  auto Path = SM.getFilename(TokLoc);
+  if (Path.empty())
     return None;
-  FileURIStorage = std::move(*U);
+  FileURIStorage = toURI(SM, Path, Opts);
   SymbolLocation Result;
   Result.FileURI = FileURIStorage.c_str();
   auto Range = getTokenRange(TokLoc, SM, LangOpts);
   Result.Start = Range.first;
   Result.End = Range.second;
 
-  return std::move(Result);
+  return Result;
 }
 
 // Checks whether \p ND is a definition of a TagDecl (class/struct/enum/union)
@@ -261,22 +239,20 @@
 
 bool SymbolCollector::shouldCollectSymbol(const NamedDecl &ND,
                                           const ASTContext &ASTCtx,
-                                          const Options &Opts) {
+                                          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;
 
-  // FIXME: figure out a way to handle internal linkage symbols (e.g. static
-  // variables, function) defined in the .cc files. Also we skip the symbols
-  // in anonymous namespace as the qualifier names of these symbols are like
-  // `foo::<anonymous>::bar`, which need a special handling.
-  // In real world projects, we have a relatively large set of header files
-  // that define static variables (like "static const int A = 1;"), we still
-  // want to collect these symbols, although they cause potential ODR
-  // violations.
-  if (ND.isInAnonymousNamespace())
+  // Skip main-file symbols if we are not collecting them.
+  if (IsMainFileOnly && !Opts.CollectMainFileSymbols)
+    return false;
+
+  // Skip symbols in anonymous namespaces in header files.
+  if (!IsMainFileOnly && ND.isInAnonymousNamespace())
     return false;
 
   // We want most things but not "local" symbols such as symbols inside
@@ -306,10 +282,6 @@
       explicitTemplateSpecialization<VarDecl>(ND))
     return false;
 
-  const auto &SM = ASTCtx.getSourceManager();
-  // Skip decls in the main file.
-  if (SM.isInMainFile(SM.getExpansionLoc(ND.getBeginLoc())))
-    return false;
   // Avoid indexing internal symbols in protobuf generated headers.
   if (isPrivateProtoDecl(ND))
     return false;
@@ -319,7 +291,7 @@
 // Always return true to continue indexing.
 bool SymbolCollector::handleDeclOccurence(
     const Decl *D, index::SymbolRoleSet Roles,
-    ArrayRef<index::SymbolRelation> Relations, SourceLocation Loc,
+    llvm::ArrayRef<index::SymbolRelation> Relations, SourceLocation Loc,
     index::IndexDataConsumer::ASTNodeInfo ASTNode) {
   assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set.");
   assert(CompletionAllocator && CompletionTUInfo);
@@ -356,9 +328,15 @@
 
   if (IsOnlyRef && !CollectRef)
     return true;
-  if (!shouldCollectSymbol(*ND, *ASTCtx, Opts))
+
+  // 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))
     return true;
-  if (CollectRef && !isa<NamespaceDecl>(ND) &&
+  // Do not store references to main-file symbols.
+  if (CollectRef && !IsMainFileOnly && !isa<NamespaceDecl>(ND) &&
       (Opts.RefsInHeaders || SM.getFileID(SpellingLoc) == SM.getMainFileID()))
     DeclRefs[ND].emplace_back(SpellingLoc, Roles);
   // Don't continue indexing if this is a mere reference.
@@ -369,19 +347,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));
-  else if (isPreferredDeclaration(OriginalDecl, Roles))
+    BasicSymbol = addDeclaration(*ND, std::move(*ID), IsMainFileOnly);
+  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));
+    BasicSymbol = addDeclaration(*OriginalDecl, std::move(*ID), IsMainFileOnly);
 
   if (Roles & static_cast<unsigned>(index::SymbolRole::Definition))
-    addDefinition(OriginalDecl, *BasicSymbol);
+    addDefinition(*OriginalDecl, *BasicSymbol);
   return true;
 }
 
@@ -395,13 +379,21 @@
 
   const auto &SM = PP->getSourceManager();
   auto DefLoc = MI->getDefinitionLoc();
-  if (SM.isInMainFile(SM.getExpansionLoc(DefLoc)))
-    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())
     return true;
 
+  // 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
   // file. The macro may not be an interesting symbol, but it's cheaper to check
   // at the end.
@@ -426,7 +418,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.
@@ -481,17 +476,13 @@
   }
 
   const auto &SM = ASTCtx->getSourceManager();
-  DenseMap<FileID, std::string> URICache;
-  auto GetURI = [&](FileID FID) -> Optional<std::string> {
+  llvm::DenseMap<FileID, std::string> URICache;
+  auto GetURI = [&](FileID FID) -> llvm::Optional<std::string> {
     auto Found = URICache.find(FID);
     if (Found == URICache.end()) {
       if (auto *FileEntry = SM.getFileEntryForID(FID)) {
         auto FileURI = toURI(SM, FileEntry->getName(), Opts);
-        if (!FileURI) {
-          log("Failed to create URI for file: {0}\n", FileEntry);
-          FileURI = ""; // reset to empty as we also want to cache this case.
-        }
-        Found = URICache.insert({FID, *FileURI}).first;
+        Found = URICache.insert({FID, FileURI}).first;
       } else {
         // Ignore cases where we can not find a corresponding file entry
         // for the loc, thoses are not interesting, e.g. symbols formed
@@ -531,7 +522,8 @@
 }
 
 const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND,
-                                              SymbolID ID) {
+                                              SymbolID ID,
+                                              bool IsMainFileOnly) {
   auto &Ctx = ND.getASTContext();
   auto &SM = Ctx.getSourceManager();
 
@@ -542,10 +534,13 @@
   // FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
   // for consistency with CodeCompletionString and a clean name/signature split.
 
-  if (isIndexedForCodeCompletion(ND, Ctx))
+  // We collect main-file symbols, but do not use them for code completion.
+  if (!IsMainFileOnly && isIndexedForCodeCompletion(ND, Ctx))
     S.Flags |= Symbol::IndexedForCodeCompletion;
   if (isImplementationDetail(&ND))
     S.Flags |= Symbol::ImplementationDetail;
+  if (!IsMainFileOnly)
+    S.Flags |= Symbol::VisibleOutsideFile;
   S.SymInfo = index::getSymbolInfo(&ND);
   std::string FileURI;
   auto Loc = findNameLoc(&ND);
@@ -555,6 +550,10 @@
           getTokenLocation(Loc, SM, Opts, ASTCtx->getLangOpts(), FileURI))
     S.CanonicalDeclaration = *DeclLoc;
 
+  S.Origin = Opts.Origin;
+  if (ND.getAvailability() == AR_Deprecated)
+    S.Flags |= Symbol::Deprecated;
+
   // Add completion info.
   // FIXME: we may want to choose a different redecl, or combine from several.
   assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set.");
@@ -564,13 +563,28 @@
       *ASTCtx, *PP, CodeCompletionContext::CCC_Symbol, *CompletionAllocator,
       *CompletionTUInfo,
       /*IncludeBriefComments*/ false);
-  std::string Signature;
-  std::string SnippetSuffix;
-  getSignature(*CCS, &Signature, &SnippetSuffix);
   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)) {
+    Symbols.insert(S);
+    return Symbols.find(S.ID);
+  }
+
+  std::string Signature;
+  std::string SnippetSuffix;
+  getSignature(*CCS, &Signature, &SnippetSuffix);
+  S.Signature = Signature;
+  S.CompletionSnippetSuffix = SnippetSuffix;
   std::string ReturnType = getReturnType(*CCS);
+  S.ReturnType = ReturnType;
 
   std::string Include;
   if (Opts.CollectIncludePath && shouldCollectIncludePath(S.SymInfo.Kind)) {
@@ -580,10 +594,6 @@
             QName, SM, SM.getExpansionLoc(ND.getLocation()), Opts))
       Include = std::move(*Header);
   }
-  S.Signature = Signature;
-  S.CompletionSnippetSuffix = SnippetSuffix;
-  S.Documentation = Documentation;
-  S.ReturnType = ReturnType;
   if (!Include.empty())
     S.IncludeHeaders.emplace_back(Include, 1);
 
@@ -594,9 +604,6 @@
       S.Type = TypeStorage->raw();
   }
 
-  S.Origin = Opts.Origin;
-  if (ND.getAvailability() == AR_Deprecated)
-    S.Flags |= Symbol::Deprecated;
   Symbols.insert(S);
   return Symbols.find(S.ID);
 }
diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h
index 01f2b0a..1b10df4 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
@@ -28,13 +27,14 @@
 /// It collects most declarations except:
 /// - Implicit declarations
 /// - Anonymous declarations (anonymous enum/class/struct, etc)
-/// - Declarations in anonymous namespaces
+/// - Declarations in anonymous namespaces in headers
 /// - Local declarations (in function bodies, blocks, etc)
-/// - Declarations in main files
 /// - Template specializations
 /// - Library-specific private declarations (e.g. private declaration generated
 /// by protobuf compiler)
 ///
+/// References to main-file symbols are not collected.
+///
 /// See also shouldCollectSymbol(...).
 ///
 /// Clients (e.g. clangd) can use SymbolCollector together with
@@ -72,6 +72,9 @@
     /// collect macros. For example, `indexTopLevelDecls` will not index any
     /// macro even if this is true.
     bool CollectMacro = false;
+    /// Collect symbols local to main-files, such as static functions
+    /// and symbols inside an anonymous namespace.
+    bool CollectMainFileSymbols = true;
     /// 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;
@@ -81,7 +84,7 @@
 
   /// Returns true is \p ND should be collected.
   static bool shouldCollectSymbol(const NamedDecl &ND, const ASTContext &ASTCtx,
-                                  const Options &Opts);
+                                  const Options &Opts, bool IsMainFileSymbol);
 
   void initialize(ASTContext &Ctx) override;
 
@@ -105,7 +108,7 @@
   void finish() override;
 
 private:
-  const Symbol *addDeclaration(const NamedDecl &, SymbolID);
+  const Symbol *addDeclaration(const NamedDecl &, SymbolID, bool IsMainFileSymbol);
   void addDefinition(const NamedDecl &, const Symbol &DeclSymbol);
 
   // All Symbols collected from the AST.
diff --git a/clangd/index/SymbolID.cpp b/clangd/index/SymbolID.cpp
index 0ab7481..b97103d 100644
--- a/clangd/index/SymbolID.cpp
+++ b/clangd/index/SymbolID.cpp
@@ -1,54 +1,56 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
 #include "SymbolID.h"
 #include "llvm/Support/SHA1.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
-SymbolID::SymbolID(StringRef USR) {
-  auto Hash = llvm::SHA1::hash(arrayRefFromStringRef(USR));
+SymbolID::SymbolID(llvm::StringRef USR) {
+  auto Hash = llvm::SHA1::hash(llvm::arrayRefFromStringRef(USR));
   static_assert(sizeof(Hash) >= RawSize, "RawSize larger than SHA1");
   memcpy(HashValue.data(), Hash.data(), RawSize);
 }
 
 llvm::StringRef SymbolID::raw() const {
-  return StringRef(reinterpret_cast<const char *>(HashValue.data()), RawSize);
+  return llvm::StringRef(reinterpret_cast<const char *>(HashValue.data()),
+                         RawSize);
 }
 
-SymbolID SymbolID::fromRaw(StringRef Raw) {
+SymbolID SymbolID::fromRaw(llvm::StringRef Raw) {
   SymbolID ID;
   assert(Raw.size() == RawSize);
   memcpy(ID.HashValue.data(), Raw.data(), RawSize);
   return ID;
 }
 
-std::string SymbolID::str() const { return toHex(raw()); }
+std::string SymbolID::str() const { return llvm::toHex(raw()); }
 
-Expected<SymbolID> SymbolID::fromStr(StringRef Str) {
+llvm::Expected<SymbolID> SymbolID::fromStr(llvm::StringRef Str) {
   if (Str.size() != RawSize * 2)
-    return createStringError(inconvertibleErrorCode(), "Bad ID length");
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Bad ID length");
   for (char C : Str)
-    if (!isHexDigit(C))
-      return createStringError(inconvertibleErrorCode(), "Bad hex ID");
-  return fromRaw(fromHex(Str));
+    if (!llvm::isHexDigit(C))
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "Bad hex ID");
+  return fromRaw(llvm::fromHex(Str));
 }
 
-raw_ostream &operator<<(raw_ostream &OS, const SymbolID &ID) {
-  return OS << toHex(ID.raw());
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID) {
+  return OS << llvm::toHex(ID.raw());
 }
 
 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..0e4fc66 100644
--- a/clangd/index/SymbolID.h
+++ b/clangd/index/SymbolID.h
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp
index d3ffddd..7aab39f 100644
--- a/clangd/index/YAMLSerialization.cpp
+++ b/clangd/index/YAMLSerialization.cpp
@@ -1,9 +1,8 @@
 //===--- SymbolYAML.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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -28,8 +27,6 @@
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
 
-using namespace llvm;
-
 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::clangd::Symbol::IncludeHeaderWithReferences)
 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::clangd::Ref)
 
@@ -38,8 +35,8 @@
     std::pair<clang::clangd::SymbolID, std::vector<clang::clangd::Ref>>;
 // This is a pale imitation of std::variant<Symbol, RefBundle>
 struct VariantEntry {
-  Optional<clang::clangd::Symbol> Symbol;
-  Optional<RefBundle> Refs;
+  llvm::Optional<clang::clangd::Symbol> Symbol;
+  llvm::Optional<RefBundle> Refs;
 };
 // A class helps YAML to serialize the 32-bit encoded position (Line&Column),
 // as YAMLIO can't directly map bitfields.
@@ -66,14 +63,14 @@
 struct NormalizedSymbolID {
   NormalizedSymbolID(IO &) {}
   NormalizedSymbolID(IO &, const SymbolID &ID) {
-    raw_string_ostream OS(HexString);
+    llvm::raw_string_ostream OS(HexString);
     OS << ID;
   }
 
   SymbolID denormalize(IO &I) {
     auto ID = SymbolID::fromStr(HexString);
     if (!ID) {
-      I.setError(toString(ID.takeError()));
+      I.setError(llvm::toString(ID.takeError()));
       return SymbolID();
     }
     return *ID;
@@ -294,8 +291,8 @@
 namespace clang {
 namespace clangd {
 
-void writeYAML(const IndexFileOut &O, raw_ostream &OS) {
-  yaml::Output Yout(OS);
+void writeYAML(const IndexFileOut &O, llvm::raw_ostream &OS) {
+  llvm::yaml::Output Yout(OS);
   for (const auto &Sym : *O.Symbols) {
     VariantEntry Entry;
     Entry.Symbol = Sym;
@@ -309,23 +306,27 @@
     }
 }
 
-Expected<IndexFileIn> readYAML(StringRef Data) {
+llvm::Expected<IndexFileIn> readYAML(llvm::StringRef Data) {
   SymbolSlab::Builder Symbols;
   RefSlab::Builder Refs;
-  BumpPtrAllocator Arena; // store the underlying data of Position::FileURI.
-  UniqueStringSaver Strings(Arena);
-  yaml::Input Yin(Data, &Strings);
-  do {
+  llvm::BumpPtrAllocator
+      Arena; // store the underlying data of Position::FileURI.
+  llvm::UniqueStringSaver Strings(Arena);
+  llvm::yaml::Input Yin(Data, &Strings);
+  while (Yin.setCurrentDocument()) {
+    llvm::yaml::EmptyContext Ctx;
     VariantEntry Variant;
-    Yin >> Variant;
+    yamlize(Yin, Variant, true, Ctx);
     if (Yin.error())
-      return errorCodeToError(Yin.error());
+      return llvm::errorCodeToError(Yin.error());
+
     if (Variant.Symbol)
       Symbols.insert(*Variant.Symbol);
     if (Variant.Refs)
       for (const auto &Ref : Variant.Refs->second)
         Refs.insert(Variant.Refs->first, Ref);
-  } while (Yin.nextDocument());
+    Yin.nextDocument();
+  }
 
   IndexFileIn Result;
   Result.Symbols.emplace(std::move(Symbols).build());
@@ -336,20 +337,20 @@
 std::string toYAML(const Symbol &S) {
   std::string Buf;
   {
-    raw_string_ostream OS(Buf);
-    yaml::Output Yout(OS);
+    llvm::raw_string_ostream OS(Buf);
+    llvm::yaml::Output Yout(OS);
     Symbol Sym = S; // copy: Yout<< requires mutability.
     Yout << Sym;
   }
   return Buf;
 }
 
-std::string toYAML(const std::pair<SymbolID, ArrayRef<Ref>> &Data) {
+std::string toYAML(const std::pair<SymbolID, llvm::ArrayRef<Ref>> &Data) {
   RefBundle Refs = {Data.first, Data.second};
   std::string Buf;
   {
-    raw_string_ostream OS(Buf);
-    yaml::Output Yout(OS);
+    llvm::raw_string_ostream OS(Buf);
+    llvm::yaml::Output Yout(OS);
     Yout << Refs;
   }
   return Buf;
diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp
index 8d64e1b..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,7 +19,6 @@
 #include <algorithm>
 #include <queue>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace dex {
@@ -44,61 +42,22 @@
 // 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);
   Result.emplace_back(Token::Kind::Scope, Sym.Scope);
   // Skip token generation for symbols with unknown declaration location.
-  if (!StringRef(Sym.CanonicalDeclaration.FileURI).empty())
+  if (!llvm::StringRef(Sym.CanonicalDeclaration.FileURI).empty())
     for (const auto &ProximityURI :
          generateProximityURIs(Sym.CanonicalDeclaration.FileURI))
       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(ArrayRef<std::string> ProximityPaths,
-                            const DenseMap<Token, PostingList> &InvertedIndex,
-                            const Corpus &Corpus) {
-  std::vector<std::unique_ptr<Iterator>> BoostingIterators;
-  // Deduplicate parent URIs extracted from the ProximityPaths.
-  StringSet<> ParentURIs;
-  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() {
@@ -124,7 +83,7 @@
   }
 
   // Populate TempInvertedIndex with lists for index symbols.
-  DenseMap<Token, std::vector<DocID>> TempInvertedIndex;
+  llvm::DenseMap<Token, std::vector<DocID>> TempInvertedIndex;
   for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) {
     const auto *Sym = Symbols[SymbolRank];
     for (const auto &Token : generateSearchTokens(*Sym))
@@ -143,11 +102,62 @@
                                    : 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.
 bool Dex::fuzzyFind(const FuzzyFindRequest &Req,
-                    function_ref<void(const Symbol &)> Callback) const {
+                    llvm::function_ref<void(const Symbol &)> Callback) const {
   assert(!StringRef(Req.Query).contains("::") &&
          "There must be no :: in query.");
   trace::Span Tracer("Dex fuzzyFind");
@@ -176,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));
@@ -190,7 +201,7 @@
   // FIXME(kbobyrev): Tune this ratio.
   if (Req.Limit)
     Root = Corpus.limit(move(Root), *Req.Limit * 100);
-  SPAN_ATTACH(Tracer, "query", to_string(*Root));
+  SPAN_ATTACH(Tracer, "query", llvm::to_string(*Root));
   vlog("Dex query tree: {0}", *Root);
 
   using IDAndScore = std::pair<DocID, float>;
@@ -204,7 +215,7 @@
   for (const auto &IDAndScore : IDAndScores) {
     const DocID SymbolDocID = IDAndScore.first;
     const auto *Sym = Symbols[SymbolDocID];
-    const Optional<float> Score = Filter.match(Sym->Name);
+    const llvm::Optional<float> Score = Filter.match(Sym->Name);
     if (!Score)
       continue;
     // Combine Fuzzy Matching score, precomputed symbol quality and boosting
@@ -225,7 +236,7 @@
 }
 
 void Dex::lookup(const LookupRequest &Req,
-                 function_ref<void(const Symbol &)> Callback) const {
+                 llvm::function_ref<void(const Symbol &)> Callback) const {
   trace::Span Tracer("Dex lookup");
   for (const auto &ID : Req.IDs) {
     auto I = LookupTable.find(ID);
@@ -235,12 +246,17 @@
 }
 
 void Dex::refs(const RefsRequest &Req,
-               function_ref<void(const Ref &)> Callback) const {
+               llvm::function_ref<void(const Ref &)> Callback) const {
   trace::Span Tracer("Dex refs");
+  uint32_t Remaining =
+      Req.Limit.getValueOr(std::numeric_limits<uint32_t>::max());
   for (const auto &ID : Req.IDs)
-    for (const auto &Ref : Refs.lookup(ID))
-      if (static_cast<int>(Req.Filter & Ref.Kind))
+    for (const auto &Ref : Refs.lookup(ID)) {
+      if (Remaining > 0 && static_cast<int>(Req.Filter & Ref.Kind)) {
+        --Remaining;
         Callback(Ref);
+      }
+    }
 }
 
 size_t Dex::estimateMemoryUsage() const {
@@ -254,13 +270,13 @@
   return Bytes + BackingDataSize;
 }
 
-std::vector<std::string> generateProximityURIs(StringRef URIPath) {
+std::vector<std::string> generateProximityURIs(llvm::StringRef URIPath) {
   std::vector<std::string> Result;
   auto ParsedURI = URI::parse(URIPath);
   assert(ParsedURI &&
          "Non-empty argument of generateProximityURIs() should be a valid "
          "URI.");
-  StringRef Body = ParsedURI->body();
+  llvm::StringRef Body = ParsedURI->body();
   // FIXME(kbobyrev): Currently, this is a heuristic which defines the maximum
   // size of resulting vector. Some projects might want to have higher limit if
   // the file hierarchy is deeper. For the generic case, it would be useful to
@@ -273,7 +289,7 @@
   while (!Body.empty() && --Limit > 0) {
     // FIXME(kbobyrev): Parsing and encoding path to URIs is not necessary and
     // could be optimized.
-    Body = sys::path::parent_path(Body, sys::path::Style::posix);
+    Body = llvm::sys::path::parent_path(Body, llvm::sys::path::Style::posix);
     URI TokenURI(ParsedURI->scheme(), ParsedURI->authority(), Body);
     if (!Body.empty())
       Result.emplace_back(TokenURI.toString());
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 9e62c15..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include <cassert>
 #include <numeric>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace dex {
@@ -77,7 +75,7 @@
   }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override {
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
     OS << "(& ";
     auto Separator = "";
     for (const auto &Child : Children) {
@@ -198,7 +196,7 @@
   }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override {
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
     OS << "(| ";
     auto Separator = "";
     for (const auto &Child : Children) {
@@ -246,7 +244,9 @@
   size_t estimateSize() const override { return Size; }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override { return OS << "true"; }
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
+    return OS << "true";
+  }
 
   DocID Index = 0;
   /// Size of the underlying virtual PostingList.
@@ -271,7 +271,9 @@
   size_t estimateSize() const override { return 0; }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override { return OS << "false"; }
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
+    return OS << "false";
+  }
 };
 
 /// Boost iterator is a wrapper around its child which multiplies scores of
@@ -294,7 +296,7 @@
   size_t estimateSize() const override { return Child->estimateSize(); }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override {
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
     return OS << "(* " << Factor << ' ' << *Child << ')';
   }
 
@@ -334,7 +336,7 @@
   }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override {
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
     return OS << "(LIMIT " << Limit << " " << *Child << ')';
   }
 
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 a0c8afd..44a668b 100644
--- a/clangd/index/dex/PostingList.cpp
+++ b/clangd/index/dex/PostingList.cpp
@@ -1,9 +1,8 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MathExtras.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace dex {
@@ -24,7 +22,7 @@
 /// them on-the-fly when the contents of chunk are to be seen.
 class ChunkIterator : public Iterator {
 public:
-  explicit ChunkIterator(const Token *Tok, ArrayRef<Chunk> Chunks)
+  explicit ChunkIterator(const Token *Tok, llvm::ArrayRef<Chunk> Chunks)
       : Tok(Tok), Chunks(Chunks), CurrentChunk(Chunks.begin()) {
     if (!Chunks.empty()) {
       DecompressedChunk = CurrentChunk->decompress();
@@ -71,7 +69,7 @@
   }
 
 private:
-  raw_ostream &dump(raw_ostream &OS) const override {
+  llvm::raw_ostream &dump(llvm::raw_ostream &OS) const override {
     if (Tok != nullptr)
       return OS << *Tok;
     OS << '[';
@@ -113,13 +111,13 @@
   }
 
   const Token *Tok;
-  ArrayRef<Chunk> Chunks;
+  llvm::ArrayRef<Chunk> Chunks;
   /// Iterator over chunks.
   /// If CurrentChunk is valid, then DecompressedChunk is
   /// CurrentChunk->decompress() and CurrentID is a valid (non-end) iterator
   /// into it.
   decltype(Chunks)::const_iterator CurrentChunk;
-  SmallVector<DocID, Chunk::PayloadSize + 1> DecompressedChunk;
+  llvm::SmallVector<DocID, Chunk::PayloadSize + 1> DecompressedChunk;
   /// Iterator over DecompressedChunk.
   decltype(DecompressedChunk)::iterator CurrentID;
 
@@ -130,11 +128,11 @@
 
 /// Writes a variable length DocID into the buffer and updates the buffer size.
 /// If it doesn't fit, returns false and doesn't write to the buffer.
-bool encodeVByte(DocID Delta, MutableArrayRef<uint8_t> &Payload) {
+bool encodeVByte(DocID Delta, llvm::MutableArrayRef<uint8_t> &Payload) {
   assert(Delta != 0 && "0 is not a valid PostingList delta.");
   // Calculate number of bytes Delta encoding would take by examining the
   // meaningful bits.
-  unsigned Width = 1 + findLastSet(Delta) / BitsPerEncodingByte;
+  unsigned Width = 1 + llvm::findLastSet(Delta) / BitsPerEncodingByte;
   if (Width > Payload.size())
     return false;
 
@@ -166,12 +164,12 @@
 /// DocIDs    42            47        7000
 /// gaps                    5         6958
 /// Encoding  (raw number)  00000101  10110110 00101110
-std::vector<Chunk> encodeStream(ArrayRef<DocID> Documents) {
+std::vector<Chunk> encodeStream(llvm::ArrayRef<DocID> Documents) {
   assert(!Documents.empty() && "Can't encode empty sequence.");
   std::vector<Chunk> Result;
   Result.emplace_back();
   DocID Last = Result.back().Head = Documents.front();
-  MutableArrayRef<uint8_t> RemainingPayload = Result.back().Payload;
+  llvm::MutableArrayRef<uint8_t> RemainingPayload = Result.back().Payload;
   for (DocID Doc : Documents.drop_front()) {
     if (!encodeVByte(Doc - Last, RemainingPayload)) { // didn't fit, flush chunk
       Result.emplace_back();
@@ -185,7 +183,7 @@
 
 /// Reads variable length DocID from the buffer and updates the buffer size. If
 /// the stream is terminated, return None.
-Optional<DocID> readVByte(ArrayRef<uint8_t> &Bytes) {
+llvm::Optional<DocID> readVByte(llvm::ArrayRef<uint8_t> &Bytes) {
   if (Bytes.front() == 0 || Bytes.empty())
     return None;
   DocID Result = 0;
@@ -203,9 +201,9 @@
 
 } // namespace
 
-SmallVector<DocID, Chunk::PayloadSize + 1> Chunk::decompress() const {
-  SmallVector<DocID, Chunk::PayloadSize + 1> Result{Head};
-  ArrayRef<uint8_t> Bytes(Payload);
+llvm::SmallVector<DocID, Chunk::PayloadSize + 1> Chunk::decompress() const {
+  llvm::SmallVector<DocID, Chunk::PayloadSize + 1> Result{Head};
+  llvm::ArrayRef<uint8_t> Bytes(Payload);
   DocID Delta;
   for (DocID Current = Head; !Bytes.empty(); Current += Delta) {
     auto MaybeDelta = readVByte(Bytes);
@@ -214,10 +212,10 @@
     Delta = *MaybeDelta;
     Result.push_back(Current + Delta);
   }
-  return SmallVector<DocID, Chunk::PayloadSize + 1>{Result};
+  return llvm::SmallVector<DocID, Chunk::PayloadSize + 1>{Result};
 }
 
-PostingList::PostingList(ArrayRef<DocID> Documents)
+PostingList::PostingList(llvm::ArrayRef<DocID> Documents)
     : Chunks(encodeStream(Documents)) {}
 
 std::unique_ptr<Iterator> PostingList::iterator(const Token *Tok) const {
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 7779e8b..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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,16 +16,15 @@
 #include <queue>
 #include <string>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace dex {
 
-std::vector<Token> generateIdentifierTrigrams(StringRef Identifier) {
+std::vector<Token> generateIdentifierTrigrams(llvm::StringRef Identifier) {
   // Apply fuzzy matching text segmentation.
   std::vector<CharRole> Roles(Identifier.size());
   calculateRoles(Identifier,
-                 makeMutableArrayRef(Roles.data(), Identifier.size()));
+                 llvm::makeMutableArrayRef(Roles.data(), Identifier.size()));
 
   std::string LowercaseIdentifier = Identifier.lower();
 
@@ -48,7 +46,7 @@
     }
   }
 
-  DenseSet<Token> UniqueTrigrams;
+  llvm::DenseSet<Token> UniqueTrigrams;
 
   auto Add = [&](std::string Chars) {
     UniqueTrigrams.insert(Token(Token::Kind::Trigram, Chars));
@@ -85,7 +83,7 @@
   return {UniqueTrigrams.begin(), UniqueTrigrams.end()};
 }
 
-std::vector<Token> generateQueryTrigrams(StringRef Query) {
+std::vector<Token> generateQueryTrigrams(llvm::StringRef Query) {
   if (Query.empty())
     return {};
   std::string LowercaseQuery = Query.lower();
@@ -94,9 +92,9 @@
 
   // Apply fuzzy matching text segmentation.
   std::vector<CharRole> Roles(Query.size());
-  calculateRoles(Query, makeMutableArrayRef(Roles.data(), Query.size()));
+  calculateRoles(Query, llvm::makeMutableArrayRef(Roles.data(), Query.size()));
 
-  DenseSet<Token> UniqueTrigrams;
+  llvm::DenseSet<Token> UniqueTrigrams;
   std::string Chars;
   for (unsigned I = 0; I < Query.size(); ++I) {
     if (Roles[I] != Head && Roles[I] != Tail)
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 795173c..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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -22,14 +21,13 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 
-using namespace llvm;
-using namespace clang;
-using namespace clangd;
-
+namespace clang {
+namespace clangd {
 namespace {
 
-cl::opt<std::string> IndexPath("index-path", cl::desc("Path to the index"),
-                               cl::Positional, cl::Required);
+llvm::cl::opt<std::string> IndexPath("index-path",
+                                     llvm::cl::desc("Path to the index"),
+                                     llvm::cl::Positional, llvm::cl::Required);
 
 static const std::string Overview = R"(
 This is an **experimental** interactive tool to process user-provided search
@@ -40,16 +38,16 @@
 Type use "help" request to get information about the details.
 )";
 
-void reportTime(StringRef Name, function_ref<void()> F) {
+void reportTime(llvm::StringRef Name, llvm::function_ref<void()> F) {
   const auto TimerStart = std::chrono::high_resolution_clock::now();
   F();
   const auto TimerStop = std::chrono::high_resolution_clock::now();
   const auto Duration = std::chrono::duration_cast<std::chrono::milliseconds>(
       TimerStop - TimerStart);
-  outs() << formatv("{0} took {1:ms+n}.\n", Name, Duration);
+  llvm::outs() << llvm::formatv("{0} took {1:ms+n}.\n", Name, Duration);
 }
 
-std::vector<SymbolID> getSymbolIDsFromIndex(StringRef QualifiedName,
+std::vector<SymbolID> getSymbolIDsFromIndex(llvm::StringRef QualifiedName,
                                             const SymbolIndex *Index) {
   FuzzyFindRequest Request;
   // Remove leading "::" qualifier as FuzzyFind doesn't need leading "::"
@@ -77,9 +75,9 @@
 // Creating a Command populates parser options, parseAndRun() resets them.
 class Command {
   // By resetting the parser options, we lost the standard -help flag.
-  cl::opt<bool, false, cl::parser<bool>> Help{
-      "help", cl::desc("Display available options"), cl::ValueDisallowed,
-      cl::cat(cl::GeneralCategory)};
+  llvm::cl::opt<bool, false, llvm::cl::parser<bool>> Help{
+      "help", llvm::cl::desc("Display available options"),
+      llvm::cl::ValueDisallowed, llvm::cl::cat(llvm::cl::GeneralCategory)};
   virtual void run() = 0;
 
 protected:
@@ -87,24 +85,25 @@
 
 public:
   virtual ~Command() = default;
-  virtual void parseAndRun(ArrayRef<const char *> Argv, const char *Overview,
-                           const SymbolIndex &Index) {
+  virtual void parseAndRun(llvm::ArrayRef<const char *> Argv,
+                           const char *Overview, const SymbolIndex &Index) {
     std::string ParseErrs;
-    raw_string_ostream OS(ParseErrs);
-    bool Ok =
-        cl::ParseCommandLineOptions(Argv.size(), Argv.data(), Overview, &OS);
+    llvm::raw_string_ostream OS(ParseErrs);
+    bool Ok = llvm::cl::ParseCommandLineOptions(Argv.size(), Argv.data(),
+                                                Overview, &OS);
     if (Help.getNumOccurrences() > 0) {
       // Avoid printing parse errors in this case.
       // (Well, in theory. A bunch get printed to llvm::errs() regardless!)
-      cl::PrintHelpMessage();
+      llvm::cl::PrintHelpMessage();
     } else {
-      outs() << OS.str();
+      llvm::outs() << OS.str();
       if (Ok) {
         this->Index = &Index;
         reportTime(Argv[0], [&] { run(); });
       }
     }
-    cl::ResetCommandLineParser(); // must do this before opts are destroyed.
+    llvm::cl::ResetCommandLineParser(); // must do this before opts are
+                                        // destroyed.
   }
 };
 
@@ -118,20 +117,20 @@
 // * print out tokens with least dense posting lists
 
 class FuzzyFind : public Command {
-  cl::opt<std::string> Query{
+  llvm::cl::opt<std::string> Query{
       "query",
-      cl::Positional,
-      cl::Required,
-      cl::desc("Query string to be fuzzy-matched"),
+      llvm::cl::Positional,
+      llvm::cl::Required,
+      llvm::cl::desc("Query string to be fuzzy-matched"),
   };
-  cl::opt<std::string> Scopes{
+  llvm::cl::opt<std::string> Scopes{
       "scopes",
-      cl::desc("Allowed symbol scopes (comma-separated list)"),
+      llvm::cl::desc("Allowed symbol scopes (comma-separated list)"),
   };
-  cl::opt<unsigned> Limit{
+  llvm::cl::opt<unsigned> Limit{
       "limit",
-      cl::init(10),
-      cl::desc("Max results to display"),
+      llvm::cl::init(10),
+      llvm::cl::desc("Max results to display"),
   };
 
   void run() override {
@@ -139,42 +138,45 @@
     Request.Limit = Limit;
     Request.Query = Query;
     if (Scopes.getNumOccurrences() > 0) {
-      SmallVector<StringRef, 8> Scopes;
-      StringRef(this->Scopes).split(Scopes, ',');
+      llvm::SmallVector<llvm::StringRef, 8> Scopes;
+      llvm::StringRef(this->Scopes).split(Scopes, ',');
       Request.Scopes = {Scopes.begin(), Scopes.end()};
     }
     Request.AnyScope = Request.Scopes.empty();
     // FIXME(kbobyrev): Print symbol final scores to see the distribution.
     static const auto OutputFormat = "{0,-4} | {1,-40} | {2,-25}\n";
-    outs() << formatv(OutputFormat, "Rank", "Symbol ID", "Symbol Name");
+    llvm::outs() << llvm::formatv(OutputFormat, "Rank", "Symbol ID",
+                                  "Symbol Name");
     size_t Rank = 0;
     Index->fuzzyFind(Request, [&](const Symbol &Sym) {
-      outs() << formatv(OutputFormat, Rank++, Sym.ID.str(),
-                        Sym.Scope + Sym.Name);
+      llvm::outs() << llvm::formatv(OutputFormat, Rank++, Sym.ID.str(),
+                                    Sym.Scope + Sym.Name);
     });
   }
 };
 
 class Lookup : public Command {
-  cl::opt<std::string> ID{
+  llvm::cl::opt<std::string> ID{
       "id",
-      cl::Positional,
-      cl::desc("Symbol ID to look up (hex)"),
+      llvm::cl::Positional,
+      llvm::cl::desc("Symbol ID to look up (hex)"),
   };
-  cl::opt<std::string> Name{
-      "name", cl::desc("Qualified name to look up."),
+  llvm::cl::opt<std::string> Name{
+      "name",
+      llvm::cl::desc("Qualified name to look up."),
   };
 
   void run() override {
     if (ID.getNumOccurrences() == 0 && Name.getNumOccurrences() == 0) {
-      outs() << "Missing required argument: please provide id or -name.\n";
+      llvm::outs()
+          << "Missing required argument: please provide id or -name.\n";
       return;
     }
     std::vector<SymbolID> IDs;
     if (ID.getNumOccurrences()) {
       auto SID = SymbolID::fromStr(ID);
       if (!SID) {
-        outs() << toString(SID.takeError()) << "\n";
+        llvm::outs() << llvm::toString(SID.takeError()) << "\n";
         return;
       }
       IDs.push_back(*SID);
@@ -187,60 +189,65 @@
     bool FoundSymbol = false;
     Index->lookup(Request, [&](const Symbol &Sym) {
       FoundSymbol = true;
-      outs() << toYAML(Sym);
+      llvm::outs() << toYAML(Sym);
     });
     if (!FoundSymbol)
-      outs() << "not found\n";
+      llvm::outs() << "not found\n";
   }
 };
 
 class Refs : public Command {
-  cl::opt<std::string> ID{
-      "id", cl::Positional,
-      cl::desc("Symbol ID of the symbol being queried (hex)."),
+  llvm::cl::opt<std::string> ID{
+      "id",
+      llvm::cl::Positional,
+      llvm::cl::desc("Symbol ID of the symbol being queried (hex)."),
   };
-  cl::opt<std::string> Name{
-      "name", cl::desc("Qualified name of the symbol being queried."),
+  llvm::cl::opt<std::string> Name{
+      "name",
+      llvm::cl::desc("Qualified name of the symbol being queried."),
   };
-  cl::opt<std::string> Filter{
-      "filter", cl::init(".*"),
-      cl::desc(
+  llvm::cl::opt<std::string> Filter{
+      "filter",
+      llvm::cl::init(".*"),
+      llvm::cl::desc(
           "Print all results from files matching this regular expression."),
   };
 
   void run() override {
     if (ID.getNumOccurrences() == 0 && Name.getNumOccurrences() == 0) {
-      outs() << "Missing required argument: please provide id or -name.\n";
+      llvm::outs()
+          << "Missing required argument: please provide id or -name.\n";
       return;
     }
     std::vector<SymbolID> IDs;
     if (ID.getNumOccurrences()) {
       auto SID = SymbolID::fromStr(ID);
       if (!SID) {
-        outs() << toString(SID.takeError()) << "\n";
+        llvm::outs() << llvm::toString(SID.takeError()) << "\n";
         return;
       }
       IDs.push_back(*SID);
     } else {
       IDs = getSymbolIDsFromIndex(Name, Index);
       if (IDs.size() > 1) {
-        outs() << formatv("The name {0} is ambiguous, found {1} different "
-                          "symbols. Please use id flag to disambiguate.\n",
-                          Name, IDs.size());
+        llvm::outs() << llvm::formatv(
+            "The name {0} is ambiguous, found {1} different "
+            "symbols. Please use id flag to disambiguate.\n",
+            Name, IDs.size());
         return;
       }
     }
     RefsRequest RefRequest;
     RefRequest.IDs.insert(IDs.begin(), IDs.end());
-    Regex RegexFilter(Filter);
+    llvm::Regex RegexFilter(Filter);
     Index->refs(RefRequest, [&RegexFilter](const Ref &R) {
       auto U = URI::parse(R.Location.FileURI);
       if (!U) {
-        outs() << U.takeError();
+        llvm::outs() << U.takeError();
         return;
       }
       if (RegexFilter.match(U->body()))
-        outs() << R << "\n";
+        llvm::outs() << R << "\n";
     });
   }
 };
@@ -257,16 +264,20 @@
      llvm::make_unique<Refs>},
 };
 
-std::unique_ptr<SymbolIndex> openIndex(StringRef Index) {
+std::unique_ptr<SymbolIndex> openIndex(llvm::StringRef Index) {
   return loadIndex(Index, /*UseDex=*/true);
 }
 
 } // namespace
+} // namespace clangd
+} // namespace clang
 
 int main(int argc, const char *argv[]) {
-  cl::ParseCommandLineOptions(argc, argv, Overview);
-  cl::ResetCommandLineParser(); // We reuse it for REPL commands.
-  sys::PrintStackTraceOnErrorSignal(argv[0]);
+  using namespace clang::clangd;
+
+  llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
+  llvm::cl::ResetCommandLineParser(); // We reuse it for REPL commands.
+  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
 
   std::unique_ptr<SymbolIndex> Index;
   reportTime("Dex build", [&]() {
@@ -274,28 +285,29 @@
   });
 
   if (!Index) {
-    outs() << "Failed to open the index.\n";
+    llvm::outs() << "Failed to open the index.\n";
     return -1;
   }
 
-  LineEditor LE("dexp");
+  llvm::LineEditor LE("dexp");
 
-  while (Optional<std::string> Request = LE.readLine()) {
+  while (llvm::Optional<std::string> Request = LE.readLine()) {
     // Split on spaces and add required null-termination.
     std::replace(Request->begin(), Request->end(), ' ', '\0');
-    SmallVector<StringRef, 8> Args;
-    StringRef(*Request).split(Args, '\0', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+    llvm::SmallVector<llvm::StringRef, 8> Args;
+    llvm::StringRef(*Request).split(Args, '\0', /*MaxSplit=*/-1,
+                                    /*KeepEmpty=*/false);
     if (Args.empty())
       continue;
     if (Args.front() == "help") {
-      outs() << "dexp - Index explorer\nCommands:\n";
+      llvm::outs() << "dexp - Index explorer\nCommands:\n";
       for (const auto &C : CommandInfo)
-        outs() << formatv("{0,16} - {1}\n", C.Name, C.Description);
-      outs() << "Get detailed command help with e.g. `find -help`.\n";
+        llvm::outs() << llvm::formatv("{0,16} - {1}\n", C.Name, C.Description);
+      llvm::outs() << "Get detailed command help with e.g. `find -help`.\n";
       continue;
     }
-    SmallVector<const char *, 8> FakeArgv;
-    for (StringRef S : Args)
+    llvm::SmallVector<const char *, 8> FakeArgv;
+    for (llvm::StringRef S : Args)
       FakeArgv.push_back(S.data()); // Terminated by separator or end of string.
 
     bool Recognized = false;
@@ -307,7 +319,7 @@
       }
     }
     if (!Recognized)
-      outs() << "Unknown command. Try 'help'.\n";
+      llvm::outs() << "Unknown command. Try 'help'.\n";
   }
 
   return 0;
diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp
index 46716a9..1621e8f 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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -22,20 +21,17 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 
-using namespace llvm;
-using namespace clang::tooling;
-
 namespace clang {
 namespace clangd {
 namespace {
 
-static cl::opt<IndexFileFormat>
-    Format("format", cl::desc("Format of the index to be written"),
-           cl::values(clEnumValN(IndexFileFormat::YAML, "yaml",
-                                 "human-readable YAML format"),
-                      clEnumValN(IndexFileFormat::RIFF, "binary",
-                                 "binary RIFF format")),
-           cl::init(IndexFileFormat::RIFF));
+static llvm::cl::opt<IndexFileFormat>
+    Format("format", llvm::cl::desc("Format of the index to be written"),
+           llvm::cl::values(clEnumValN(IndexFileFormat::YAML, "yaml",
+                                       "human-readable YAML format"),
+                            clEnumValN(IndexFileFormat::RIFF, "binary",
+                                       "binary RIFF format")),
+           llvm::cl::init(IndexFileFormat::RIFF));
 
 class IndexActionFactory : public tooling::FrontendActionFactory {
 public:
@@ -86,7 +82,7 @@
 } // namespace clang
 
 int main(int argc, const char **argv) {
-  sys::PrintStackTraceOnErrorSignal(argv[0]);
+  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
 
   const char *Overview = R"(
   Creates an index of symbol information etc in a whole project.
@@ -103,10 +99,10 @@
   )";
 
   auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
-      argc, argv, cl::GeneralCategory, Overview);
+      argc, argv, llvm::cl::GeneralCategory, Overview);
 
   if (!Executor) {
-    errs() << toString(Executor.takeError()) << "\n";
+    llvm::errs() << llvm::toString(Executor.takeError()) << "\n";
     return 1;
   }
 
@@ -115,12 +111,12 @@
   auto Err = Executor->get()->execute(
       llvm::make_unique<clang::clangd::IndexActionFactory>(Data));
   if (Err) {
-    errs() << toString(std::move(Err)) << "\n";
+    llvm::errs() << llvm::toString(std::move(Err)) << "\n";
   }
 
   // Emit collected data.
   clang::clangd::IndexFileOut Out(Data);
   Out.Format = clang::clangd::Format;
-  outs() << Out;
+  llvm::outs() << Out;
   return 0;
 }
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..6aeb5ef
--- /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 linker does not remove global
+# constructors that register individual tweaks in a global registry.
+# To enable these tweaks in exectubales 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/tool/CMakeLists.txt b/clangd/tool/CMakeLists.txt
index c188761..93d7f14 100644
--- a/clangd/tool/CMakeLists.txt
+++ b/clangd/tool/CMakeLists.txt
@@ -1,20 +1,30 @@
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
 
 add_clang_tool(clangd
   ClangdMain.cpp
+  $<TARGET_OBJECTS:obj.clangDaemonTweaks>
   )
 
 set(LLVM_LINK_COMPONENTS
   support
   )
 
+set(CLANGD_XPC_LIBS "")
+if(CLANGD_BUILD_XPC)
+  list(APPEND CLANGD_XPC_LIBS "clangdXpcJsonConversions" "clangdXpcTransport")
+endif()
+
 target_link_libraries(clangd
   PRIVATE
+  clangAST
   clangBasic
+  clangTidy
   clangDaemon
   clangFormat
   clangFrontend
   clangSema
   clangTooling
   clangToolingCore
+  ${CLANGD_XPC_LIBS}
   )
diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp
index 3d94401..9495869 100644
--- a/clangd/tool/ClangdMain.cpp
+++ b/clangd/tool/ClangdMain.cpp
@@ -1,12 +1,12 @@
 //===--- 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 "Path.h"
 #include "Trace.h"
@@ -25,176 +25,199 @@
 #include <string>
 #include <thread>
 
-using namespace llvm;
-using namespace clang;
-using namespace clang::clangd;
-
+namespace clang {
+namespace clangd {
 // FIXME: remove this option when Dex is cheap enough.
-static cl::opt<bool> UseDex("use-dex-index",
-                            cl::desc("Use experimental Dex dynamic index."),
-                            cl::init(false), cl::Hidden);
+static llvm::cl::opt<bool>
+    UseDex("use-dex-index",
+           llvm::cl::desc("Use experimental Dex dynamic index."),
+           llvm::cl::init(true), llvm::cl::Hidden);
 
-static cl::opt<Path> CompileCommandsDir(
+static llvm::cl::opt<Path> CompileCommandsDir(
     "compile-commands-dir",
-    cl::desc("Specify a path to look for compile_commands.json. If path "
-             "is invalid, clangd will look in the current directory and "
-             "parent paths of each source file."));
+    llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+                   "is invalid, clangd will look in the current directory and "
+                   "parent paths of each source file."));
 
-static cl::opt<unsigned>
-    WorkerThreadsCount("j", cl::desc("Number of async workers used by clangd"),
-                       cl::init(getDefaultAsyncThreadsCount()));
+static llvm::cl::opt<unsigned>
+    WorkerThreadsCount("j",
+                       llvm::cl::desc("Number of async workers used by clangd"),
+                       llvm::cl::init(getDefaultAsyncThreadsCount()));
 
 // FIXME: also support "plain" style where signatures are always omitted.
 enum CompletionStyleFlag { Detailed, Bundled };
-static cl::opt<CompletionStyleFlag> CompletionStyle(
-    "completion-style", cl::desc("Granularity of code completion suggestions"),
-    cl::values(
+static llvm::cl::opt<CompletionStyleFlag> CompletionStyle(
+    "completion-style",
+    llvm::cl::desc("Granularity of code completion suggestions"),
+    llvm::cl::values(
         clEnumValN(Detailed, "detailed",
                    "One completion item for each semantically distinct "
                    "completion, with full type information."),
         clEnumValN(Bundled, "bundled",
                    "Similar completion items (e.g. function overloads) are "
                    "combined. Type information shown where possible.")),
-    cl::init(Detailed));
+    llvm::cl::init(Detailed));
 
 // FIXME: Flags are the wrong mechanism for user preferences.
 // We should probably read a dotfile or similar.
-static cl::opt<bool> IncludeIneligibleResults(
+static llvm::cl::opt<bool> IncludeIneligibleResults(
     "include-ineligible-results",
-    cl::desc("Include ineligible completion results (e.g. private members)"),
-    cl::init(clangd::CodeCompleteOptions().IncludeIneligibleResults),
-    cl::Hidden);
+    llvm::cl::desc(
+        "Include ineligible completion results (e.g. private members)"),
+    llvm::cl::init(CodeCompleteOptions().IncludeIneligibleResults),
+    llvm::cl::Hidden);
 
-static cl::opt<JSONStreamStyle> InputStyle(
-    "input-style", cl::desc("Input JSON stream encoding"),
-    cl::values(
+static llvm::cl::opt<JSONStreamStyle> InputStyle(
+    "input-style", llvm::cl::desc("Input JSON stream encoding"),
+    llvm::cl::values(
         clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
         clEnumValN(JSONStreamStyle::Delimited, "delimited",
                    "messages delimited by --- lines, with # comment support")),
-    cl::init(JSONStreamStyle::Standard));
+    llvm::cl::init(JSONStreamStyle::Standard));
 
-static cl::opt<bool> PrettyPrint("pretty", cl::desc("Pretty-print JSON output"),
-                                 cl::init(false));
+static llvm::cl::opt<bool>
+    PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"),
+                llvm::cl::init(false));
 
-static cl::opt<Logger::Level> LogLevel(
-    "log", cl::desc("Verbosity of log messages written to stderr"),
-    cl::values(clEnumValN(Logger::Error, "error", "Error messages only"),
-               clEnumValN(Logger::Info, "info", "High level execution tracing"),
-               clEnumValN(Logger::Debug, "verbose", "Low level details")),
-    cl::init(Logger::Info));
+static llvm::cl::opt<Logger::Level> LogLevel(
+    "log", llvm::cl::desc("Verbosity of log messages written to stderr"),
+    llvm::cl::values(clEnumValN(Logger::Error, "error", "Error messages only"),
+                     clEnumValN(Logger::Info, "info",
+                                "High level execution tracing"),
+                     clEnumValN(Logger::Debug, "verbose", "Low level details")),
+    llvm::cl::init(Logger::Info));
 
-static cl::opt<bool>
+static llvm::cl::opt<bool>
     Test("lit-test",
-         cl::desc("Abbreviation for -input-style=delimited -pretty "
-                  "-run-synchronously -enable-test-scheme. "
-                  "Intended to simplify lit tests."),
-         cl::init(false), cl::Hidden);
+         llvm::cl::desc("Abbreviation for -input-style=delimited -pretty "
+                        "-run-synchronously -enable-test-scheme. "
+                        "Intended to simplify lit tests."),
+         llvm::cl::init(false), llvm::cl::Hidden);
 
-static cl::opt<bool> EnableTestScheme(
+static llvm::cl::opt<bool> EnableTestScheme(
     "enable-test-uri-scheme",
-    cl::desc("Enable 'test:' URI scheme. Only use in lit tests."),
-    cl::init(false), cl::Hidden);
+    llvm::cl::desc("Enable 'test:' URI scheme. Only use in lit tests."),
+    llvm::cl::init(false), llvm::cl::Hidden);
 
 enum PCHStorageFlag { Disk, Memory };
-static cl::opt<PCHStorageFlag> PCHStorage(
+static llvm::cl::opt<PCHStorageFlag> PCHStorage(
     "pch-storage",
-    cl::desc("Storing PCHs in memory increases memory usages, but may "
-             "improve performance"),
-    cl::values(clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
-               clEnumValN(PCHStorageFlag::Memory, "memory",
-                          "store PCHs in memory")),
-    cl::init(PCHStorageFlag::Disk));
+    llvm::cl::desc("Storing PCHs in memory increases memory usages, but may "
+                   "improve performance"),
+    llvm::cl::values(
+        clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
+        clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
+    llvm::cl::init(PCHStorageFlag::Disk));
 
-static cl::opt<int>
-    LimitResults("limit-results",
-                 cl::desc("Limit the number of results returned by clangd. "
-                          "0 means no limit."),
-                 cl::init(100));
+static llvm::cl::opt<int> LimitResults(
+    "limit-results",
+    llvm::cl::desc("Limit the number of results returned by clangd. "
+                   "0 means no limit."),
+    llvm::cl::init(100));
 
-static cl::opt<bool>
-    RunSynchronously("run-synchronously",
-                     cl::desc("Parse on main thread. If set, -j is ignored"),
-                     cl::init(false), cl::Hidden);
+static llvm::cl::opt<bool> RunSynchronously(
+    "run-synchronously",
+    llvm::cl::desc("Parse on main thread. If set, -j is ignored"),
+    llvm::cl::init(false), llvm::cl::Hidden);
 
-static cl::opt<Path> ResourceDir("resource-dir",
-                                 cl::desc("Directory for system clang headers"),
-                                 cl::init(""), cl::Hidden);
+static llvm::cl::opt<Path>
+    ResourceDir("resource-dir",
+                llvm::cl::desc("Directory for system clang headers"),
+                llvm::cl::init(""), llvm::cl::Hidden);
 
-static cl::opt<Path> InputMirrorFile(
+static llvm::cl::opt<Path> InputMirrorFile(
     "input-mirror-file",
-    cl::desc(
+    llvm::cl::desc(
         "Mirror all LSP input to the specified file. Useful for debugging."),
-    cl::init(""), cl::Hidden);
+    llvm::cl::init(""), llvm::cl::Hidden);
 
-static cl::opt<bool> EnableIndex(
+static llvm::cl::opt<bool> EnableIndex(
     "index",
-    cl::desc(
+    llvm::cl::desc(
         "Enable index-based features. By default, clangd maintains an index "
         "built from symbols in opened files. Global index support needs to "
         "enabled separatedly."),
-    cl::init(true), cl::Hidden);
+    llvm::cl::init(true), llvm::cl::Hidden);
 
-static cl::opt<bool> AllScopesCompletion(
+static llvm::cl::opt<bool> AllScopesCompletion(
     "all-scopes-completion",
-    cl::desc(
+    llvm::cl::desc(
         "If set to true, code completion will include index symbols that are "
         "not defined in the scopes (e.g. "
         "namespaces) visible from the code completion point. Such completions "
         "can insert scope qualifiers."),
-    cl::init(true));
+    llvm::cl::init(true));
 
-static cl::opt<bool>
-    ShowOrigins("debug-origin", cl::desc("Show origins of completion items"),
-                cl::init(clangd::CodeCompleteOptions().ShowOrigins),
-                cl::Hidden);
+static llvm::cl::opt<bool> ShowOrigins(
+    "debug-origin", llvm::cl::desc("Show origins of completion items"),
+    llvm::cl::init(CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden);
 
-static cl::opt<bool> HeaderInsertionDecorators(
+static llvm::cl::opt<bool> HeaderInsertionDecorators(
     "header-insertion-decorators",
-    cl::desc("Prepend a circular dot or space before the completion "
-             "label, depending on whether "
-             "an include line will be inserted or not."),
-    cl::init(true));
+    llvm::cl::desc("Prepend a circular dot or space before the completion "
+                   "label, depending on whether "
+                   "an include line will be inserted or not."),
+    llvm::cl::init(true));
 
-static cl::opt<Path> IndexFile(
+static llvm::cl::opt<Path> IndexFile(
     "index-file",
-    cl::desc(
+    llvm::cl::desc(
         "Index file to build the static index. The file must have been created "
         "by a compatible clangd-index.\n"
         "WARNING: This option is experimental only, and will be removed "
         "eventually. Don't rely on it."),
-    cl::init(""), cl::Hidden);
+    llvm::cl::init(""), llvm::cl::Hidden);
 
-static cl::opt<bool> EnableBackgroundIndex(
+static llvm::cl::opt<bool> EnableBackgroundIndex(
     "background-index",
-    cl::desc("Index project code in the background and persist index on disk. "
-             "Experimental"),
-    cl::init(false), cl::Hidden);
+    llvm::cl::desc(
+        "Index project code in the background and persist index on disk. "
+        "Experimental"),
+    llvm::cl::init(false), llvm::cl::Hidden);
 
-static cl::opt<int> BackgroundIndexRebuildPeriod(
+static llvm::cl::opt<int> BackgroundIndexRebuildPeriod(
     "background-index-rebuild-period",
-    cl::desc(
+    llvm::cl::desc(
         "If set to non-zero, the background index rebuilds the symbol index "
         "periodically every X milliseconds; otherwise, the "
         "symbol index will be updated for each indexed file."),
-    cl::init(5000), cl::Hidden);
+    llvm::cl::init(5000), llvm::cl::Hidden);
 
 enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };
-static cl::opt<CompileArgsFrom> CompileArgsFrom(
-    "compile_args_from", cl::desc("The source of compile commands"),
-    cl::values(clEnumValN(LSPCompileArgs, "lsp",
-                          "All compile commands come from LSP and "
-                          "'compile_commands.json' files are ignored"),
-               clEnumValN(FilesystemCompileArgs, "filesystem",
-                          "All compile commands come from the "
-                          "'compile_commands.json' files")),
-    cl::init(FilesystemCompileArgs), cl::Hidden);
+static llvm::cl::opt<CompileArgsFrom> CompileArgsFrom(
+    "compile_args_from", llvm::cl::desc("The source of compile commands"),
+    llvm::cl::values(clEnumValN(LSPCompileArgs, "lsp",
+                                "All compile commands come from LSP and "
+                                "'compile_commands.json' files are ignored"),
+                     clEnumValN(FilesystemCompileArgs, "filesystem",
+                                "All compile commands come from the "
+                                "'compile_commands.json' files")),
+    llvm::cl::init(FilesystemCompileArgs), llvm::cl::Hidden);
 
-static cl::opt<bool> EnableFunctionArgSnippets(
+static llvm::cl::opt<bool> EnableFunctionArgSnippets(
     "function-arg-placeholders",
-    cl::desc("When disabled, completions contain only parentheses for "
-             "function calls. When enabled, completions also contain "
-             "placeholders for method parameters."),
-    cl::init(clangd::CodeCompleteOptions().EnableFunctionArgSnippets));
+    llvm::cl::desc("When disabled, completions contain only parentheses for "
+                   "function calls. When enabled, completions also contain "
+                   "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(false));
+
+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(false));
 
 namespace {
 
@@ -204,33 +227,34 @@
 /// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix.
 class TestScheme : public URIScheme {
 public:
-  Expected<std::string> getAbsolutePath(StringRef /*Authority*/, StringRef Body,
-                                        StringRef /*HintPath*/) const override {
+  llvm::Expected<std::string>
+  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+                  llvm::StringRef /*HintPath*/) const override {
     using namespace llvm::sys;
     // Still require "/" in body to mimic file scheme, as we want lengths of an
     // equivalent URI in both schemes to be the same.
     if (!Body.startswith("/"))
-      return make_error<StringError>(
+      return llvm::make_error<llvm::StringError>(
           "Expect URI body to be an absolute path starting with '/': " + Body,
-          inconvertibleErrorCode());
+          llvm::inconvertibleErrorCode());
     Body = Body.ltrim('/');
-    SmallVector<char, 16> Path(Body.begin(), Body.end());
+    llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
     path::native(Path);
-    auto Err = fs::make_absolute(TestScheme::TestDir, Path);
-    if (Err)
-      llvm_unreachable("Failed to make absolute path in test scheme.");
+    fs::make_absolute(TestScheme::TestDir, Path);
     return std::string(Path.begin(), Path.end());
   }
 
-  Expected<URI> uriFromAbsolutePath(StringRef AbsolutePath) const override {
-    StringRef Body = AbsolutePath;
+  llvm::Expected<URI>
+  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
+    llvm::StringRef Body = AbsolutePath;
     if (!Body.consume_front(TestScheme::TestDir)) {
-      return make_error<StringError>("Path " + AbsolutePath +
-                                         " doesn't start with root " + TestDir,
-                                     inconvertibleErrorCode());
+      return llvm::make_error<llvm::StringError>(
+          "Path " + AbsolutePath + " doesn't start with root " + TestDir,
+          llvm::inconvertibleErrorCode());
     }
 
-    return URI("test", /*Authority=*/"", sys::path::convert_to_slash(Body));
+    return URI("test", /*Authority=*/"",
+               llvm::sys::path::convert_to_slash(Body));
   }
 
 private:
@@ -243,14 +267,24 @@
 const char TestScheme::TestDir[] = "/clangd-test";
 #endif
 
-}
+} // namespace
+} // namespace clangd
+} // namespace clang
+
+enum class ErrorResultCode : int {
+  NoShutdownRequest = 1,
+  CantRunAsXPCService = 2
+};
 
 int main(int argc, char *argv[]) {
-  sys::PrintStackTraceOnErrorSignal(argv[0]);
-  cl::SetVersionPrinter([](raw_ostream &OS) {
+  using namespace clang;
+  using namespace clang::clangd;
+
+  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
     OS << clang::getClangToolFullVersion("clangd") << "\n";
   });
-  cl::ParseCommandLineOptions(
+  llvm::cl::ParseCommandLineOptions(
       argc, argv,
       "clangd is a language server that provides IDE-like features to editors. "
       "\n\nIt should be used via an editor plugin rather than invoked "
@@ -270,26 +304,27 @@
   }
 
   if (!RunSynchronously && WorkerThreadsCount == 0) {
-    errs() << "A number of worker threads cannot be 0. Did you mean to "
-              "specify -run-synchronously?";
+    llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
+                    "specify -run-synchronously?";
     return 1;
   }
 
   if (RunSynchronously) {
     if (WorkerThreadsCount.getNumOccurrences())
-      errs() << "Ignoring -j because -run-synchronously is set.\n";
+      llvm::errs() << "Ignoring -j because -run-synchronously is set.\n";
     WorkerThreadsCount = 0;
   }
 
   // Validate command line arguments.
-  Optional<raw_fd_ostream> InputMirrorStream;
+  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
   if (!InputMirrorFile.empty()) {
     std::error_code EC;
     InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
-                              sys::fs::FA_Read | sys::fs::FA_Write);
+                              llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
     if (EC) {
       InputMirrorStream.reset();
-      errs() << "Error while opening an input mirror file: " << EC.message();
+      llvm::errs() << "Error while opening an input mirror file: "
+                   << EC.message();
     } else {
       InputMirrorStream->SetUnbuffered();
     }
@@ -298,51 +333,52 @@
   // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
   // trace flag in your editor's config is annoying, launching with
   // `CLANGD_TRACE=trace.json vim` is easier.
-  Optional<raw_fd_ostream> TraceStream;
+  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
   std::unique_ptr<trace::EventTracer> Tracer;
   if (auto *TraceFile = getenv("CLANGD_TRACE")) {
     std::error_code EC;
     TraceStream.emplace(TraceFile, /*ref*/ EC,
-                        sys::fs::FA_Read | sys::fs::FA_Write);
+                        llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
     if (EC) {
       TraceStream.reset();
-      errs() << "Error while opening trace file " << TraceFile << ": "
-             << EC.message();
+      llvm::errs() << "Error while opening trace file " << TraceFile << ": "
+                   << EC.message();
     } else {
       Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
     }
   }
 
-  Optional<trace::Session> TracingSession;
+  llvm::Optional<trace::Session> TracingSession;
   if (Tracer)
     TracingSession.emplace(*Tracer);
 
   // Use buffered stream to stderr (we still flush each log message). Unbuffered
   // stream can cause significant (non-deterministic) latency for the logger.
-  errs().SetBuffered();
-  StreamLogger Logger(errs(), LogLevel);
-  clangd::LoggingSession LoggingSession(Logger);
+  llvm::errs().SetBuffered();
+  StreamLogger Logger(llvm::errs(), LogLevel);
+  LoggingSession LoggingSession(Logger);
 
   // If --compile-commands-dir arg was invoked, check value and override default
   // path.
-  Optional<Path> CompileCommandsDirPath;
+  llvm::Optional<Path> CompileCommandsDirPath;
   if (!CompileCommandsDir.empty()) {
-    if (sys::fs::exists(CompileCommandsDir)) {
+    if (llvm::sys::fs::exists(CompileCommandsDir)) {
       // We support passing both relative and absolute paths to the
       // --compile-commands-dir argument, but we assume the path is absolute in
       // the rest of clangd so we make sure the path is absolute before
       // continuing.
-      SmallString<128> Path(CompileCommandsDir);
-      if (std::error_code EC = sys::fs::make_absolute(Path)) {
-        errs() << "Error while converting the relative path specified by "
-                  "--compile-commands-dir to an absolute path: "
-               << EC.message() << ". The argument will be ignored.\n";
+      llvm::SmallString<128> Path(CompileCommandsDir);
+      if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) {
+        llvm::errs() << "Error while converting the relative path specified by "
+                        "--compile-commands-dir to an absolute path: "
+                     << EC.message() << ". The argument will be ignored.\n";
       } else {
         CompileCommandsDirPath = Path.str();
       }
     } else {
-      errs() << "Path specified by --compile-commands-dir does not exist. The "
-                "argument will be ignored.\n";
+      llvm::errs()
+          << "Path specified by --compile-commands-dir does not exist. The "
+             "argument will be ignored.\n";
     }
   }
 
@@ -390,17 +426,42 @@
   CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
   CCOpts.AllScopes = AllScopesCompletion;
 
+  RealFileSystemProvider FSProvider;
   // Initialize and run ClangdLSPServer.
   // Change stdin to binary to not lose \r\n on windows.
-  sys::ChangeStdinToBinary();
-  auto Transport = newJSONTransport(
-      stdin, outs(),
-      InputMirrorStream ? InputMirrorStream.getPointer() : nullptr, PrettyPrint,
-      InputStyle);
+  llvm::sys::ChangeStdinToBinary();
+
+  std::unique_ptr<Transport> TransportLayer;
+  if (getenv("CLANGD_AS_XPC_SERVICE")) {
+#if CLANGD_BUILD_XPC
+    TransportLayer = newXPCTransport();
+#else
+    llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
+    return (int)ErrorResultCode::CantRunAsXPCService;
+#endif
+  } else {
+    TransportLayer = newJSONTransport(
+        stdin, llvm::outs(),
+        InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
+        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;
   ClangdLSPServer LSPServer(
-      *Transport, CCOpts, CompileCommandsDirPath,
+      *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
       /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts);
-  constexpr int NoShutdownRequestErrorCode = 1;
-  set_thread_name("clangd.main");
-  return LSPServer.run() ? 0 : NoShutdownRequestErrorCode;
+  llvm::set_thread_name("clangd.main");
+  return LSPServer.run() ? 0
+                         : static_cast<int>(ErrorResultCode::NoShutdownRequest);
 }
diff --git a/clangd/xpc/CMakeLists.txt b/clangd/xpc/CMakeLists.txt
new file mode 100644
index 0000000..788a66f
--- /dev/null
+++ b/clangd/xpc/CMakeLists.txt
@@ -0,0 +1,29 @@
+set(CLANGD_XPC_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(CLANGD_XPC_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+include(CreateClangdXPCFramework)
+
+add_subdirectory(framework)
+add_subdirectory(test-client)
+
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+)
+
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+# Needed by LLVM's CMake checks because this file defines multiple targets.
+set(LLVM_OPTIONAL_SOURCES Conversion.cpp XPCTransport.cpp)
+
+add_clang_library(clangdXpcJsonConversions
+  Conversion.cpp
+  )
+
+add_clang_library(clangdXpcTransport
+  XPCTransport.cpp
+  DEPENDS clangdXpcJsonConversions
+  LINK_LIBS clangdXpcJsonConversions
+  )
diff --git a/clangd/xpc/Conversion.cpp b/clangd/xpc/Conversion.cpp
new file mode 100644
index 0000000..3e8d36b
--- /dev/null
+++ b/clangd/xpc/Conversion.cpp
@@ -0,0 +1,39 @@
+//===--- Conversion.cpp - LSP data (de-)serialization through XPC - 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 "Logger.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+namespace clang {
+namespace clangd {
+
+xpc_object_t jsonToXpc(const json::Value &JSON) {
+  const char *const Key = "LSP";
+  xpc_object_t PayloadObj = xpc_string_create(llvm::to_string(JSON).c_str());
+  return xpc_dictionary_create(&Key, &PayloadObj, 1);
+}
+
+json::Value xpcToJson(const xpc_object_t &XPCObject) {
+  if (xpc_get_type(XPCObject) == XPC_TYPE_DICTIONARY) {
+    const char *const LSP = xpc_dictionary_get_string(XPCObject, "LSP");
+    auto Json = json::parse(llvm::StringRef(LSP));
+    if (Json)
+      return *Json;
+    else
+      elog("JSON parse error: {0}", toString(Json.takeError()));
+  }
+  return json::Value(nullptr);
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/xpc/Conversion.h b/clangd/xpc/Conversion.h
new file mode 100644
index 0000000..fccc095
--- /dev/null
+++ b/clangd/xpc/Conversion.h
@@ -0,0 +1,24 @@
+//===--- Conversion.h - LSP data (de-)serialization through XPC -*- 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_XPC_XPCJSONCONVERSIONS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XPC_XPCJSONCONVERSIONS_H
+
+#include "llvm/Support/JSON.h"
+#include <xpc/xpc.h>
+
+namespace clang {
+namespace clangd {
+
+xpc_object_t jsonToXpc(const llvm::json::Value &JSON);
+llvm::json::Value xpcToJson(const xpc_object_t &XPCObject);
+
+} // namespace clangd
+} // namespace clang
+
+#endif
diff --git a/clangd/xpc/README.txt b/clangd/xpc/README.txt
new file mode 100644
index 0000000..70ac761
--- /dev/null
+++ b/clangd/xpc/README.txt
@@ -0,0 +1,6 @@
+This directory contains:
+- the XPC transport layer (alternative transport layer to JSON-RPC)
+- XPC framework wrapper that wraps around Clangd to make it a valid XPC service
+- XPC test-client
+
+MacOS only. Feature is guarded by CLANGD_BUILD_XPC, including whole xpc/ dir.
\ No newline at end of file
diff --git a/clangd/xpc/XPCTransport.cpp b/clangd/xpc/XPCTransport.cpp
new file mode 100644
index 0000000..f7df8a9
--- /dev/null
+++ b/clangd/xpc/XPCTransport.cpp
@@ -0,0 +1,216 @@
+//===--- XPCTransport.cpp - sending and receiving LSP messages over XPC ---===//
+//
+// Part of the LLVM Project, under the Apache 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"
+#include "Logger.h"
+#include "Protocol.h" // For LSPError
+#include "Transport.h"
+#include "llvm/Support/Errno.h"
+
+#include <xpc/xpc.h>
+
+using namespace llvm;
+using namespace clang;
+using namespace clangd;
+
+namespace {
+
+json::Object encodeError(Error E) {
+  std::string Message;
+  ErrorCode Code = ErrorCode::UnknownErrorCode;
+  if (Error Unhandled =
+          handleErrors(std::move(E), [&](const LSPError &L) -> Error {
+            Message = L.Message;
+            Code = L.Code;
+            return Error::success();
+          }))
+    Message = toString(std::move(Unhandled));
+
+  return json::Object{
+      {"message", std::move(Message)},
+      {"code", int64_t(Code)},
+  };
+}
+
+Error decodeError(const json::Object &O) {
+  std::string Msg = O.getString("message").getValueOr("Unspecified error");
+  if (auto Code = O.getInteger("code"))
+    return make_error<LSPError>(std::move(Msg), ErrorCode(*Code));
+  return make_error<StringError>(std::move(Msg), inconvertibleErrorCode());
+}
+
+// C "closure" for XPCTransport::loop() method
+namespace xpcClosure {
+void connection_handler(xpc_connection_t clientConnection);
+}
+
+class XPCTransport : public Transport {
+public:
+  XPCTransport() {}
+
+  void notify(StringRef Method, json::Value Params) override {
+    sendMessage(json::Object{
+        {"jsonrpc", "2.0"},
+        {"method", Method},
+        {"params", std::move(Params)},
+    });
+  }
+  void call(StringRef Method, json::Value Params, json::Value ID) override {
+    sendMessage(json::Object{
+        {"jsonrpc", "2.0"},
+        {"id", std::move(ID)},
+        {"method", Method},
+        {"params", std::move(Params)},
+    });
+  }
+  void reply(json::Value ID, Expected<json::Value> Result) override {
+    if (Result) {
+      sendMessage(json::Object{
+          {"jsonrpc", "2.0"},
+          {"id", std::move(ID)},
+          {"result", std::move(*Result)},
+      });
+    } else {
+      sendMessage(json::Object{
+          {"jsonrpc", "2.0"},
+          {"id", std::move(ID)},
+          {"error", encodeError(Result.takeError())},
+      });
+    }
+  }
+
+  Error loop(MessageHandler &Handler) override;
+
+private:
+  // Needs access to handleMessage() and resetClientConnection()
+  friend void xpcClosure::connection_handler(xpc_connection_t clientConnection);
+
+  // Dispatches incoming message to Handler onNotify/onCall/onReply.
+  bool handleMessage(json::Value Message, MessageHandler &Handler);
+  void sendMessage(json::Value Message) {
+    xpc_object_t response = jsonToXpc(Message);
+    xpc_connection_send_message(clientConnection, response);
+    xpc_release(response);
+  }
+  void resetClientConnection(xpc_connection_t newClientConnection) {
+    clientConnection = newClientConnection;
+  }
+  xpc_connection_t clientConnection;
+};
+
+bool XPCTransport::handleMessage(json::Value Message, MessageHandler &Handler) {
+  // Message must be an object with "jsonrpc":"2.0".
+  auto *Object = Message.getAsObject();
+  if (!Object || Object->getString("jsonrpc") != Optional<StringRef>("2.0")) {
+    elog("Not a JSON-RPC 2.0 message: {0:2}", Message);
+    return false;
+  }
+  // ID may be any JSON value. If absent, this is a notification.
+  Optional<json::Value> ID;
+  if (auto *I = Object->get("id"))
+    ID = std::move(*I);
+  auto Method = Object->getString("method");
+  if (!Method) { // This is a response.
+    if (!ID) {
+      elog("No method and no response ID: {0:2}", Message);
+      return false;
+    }
+    if (auto *Err = Object->getObject("error"))
+      return Handler.onReply(std::move(*ID), decodeError(*Err));
+    // Result should be given, use null if not.
+    json::Value Result = nullptr;
+    if (auto *R = Object->get("result"))
+      Result = std::move(*R);
+    return Handler.onReply(std::move(*ID), std::move(Result));
+  }
+  // Params should be given, use null if not.
+  json::Value Params = nullptr;
+  if (auto *P = Object->get("params"))
+    Params = std::move(*P);
+
+  if (ID)
+    return Handler.onCall(*Method, std::move(Params), std::move(*ID));
+  else
+    return Handler.onNotify(*Method, std::move(Params));
+}
+
+namespace xpcClosure {
+// "owner" of this "closure object" - necessary for propagating connection to
+// XPCTransport so it can send messages to the client.
+XPCTransport *TransportObject = nullptr;
+Transport::MessageHandler *HandlerPtr = nullptr;
+
+void connection_handler(xpc_connection_t clientConnection) {
+  xpc_connection_set_target_queue(clientConnection, dispatch_get_main_queue());
+
+  xpc_transaction_begin();
+
+  TransportObject->resetClientConnection(clientConnection);
+
+  xpc_connection_set_event_handler(clientConnection, ^(xpc_object_t message) {
+    if (message == XPC_ERROR_CONNECTION_INVALID) {
+      // connection is being terminated
+      log("Received XPC_ERROR_CONNECTION_INVALID message - returning from the "
+          "event_handler.");
+      return;
+    }
+
+    if (xpc_get_type(message) != XPC_TYPE_DICTIONARY) {
+      log("Received XPC message of unknown type - returning from the "
+          "event_handler.");
+      return;
+    }
+
+    const json::Value Doc = xpcToJson(message);
+    if (Doc == json::Value(nullptr)) {
+      log("XPC message was converted to Null JSON message - returning from the "
+          "event_handler.");
+      return;
+    }
+
+    vlog("<<< {0}\n", Doc);
+
+    if (!TransportObject->handleMessage(std::move(Doc), *HandlerPtr)) {
+      log("Received exit notification - cancelling connection.");
+      xpc_connection_cancel(xpc_dictionary_get_remote_connection(message));
+      xpc_transaction_end();
+    }
+  });
+
+  xpc_connection_resume(clientConnection);
+}
+} // namespace xpcClosure
+
+Error XPCTransport::loop(MessageHandler &Handler) {
+  assert(xpcClosure::TransportObject == nullptr &&
+         "TransportObject has already been set.");
+  // This looks scary since lifetime of this (or any) XPCTransport object has
+  // to fully contain lifetime of any XPC connection. In practise any Transport
+  // object is destroyed only at the end of main() which is always after
+  // exit of xpc_main().
+  xpcClosure::TransportObject = this;
+
+  assert(xpcClosure::HandlerPtr == nullptr &&
+         "HandlerPtr has already been set.");
+  xpcClosure::HandlerPtr = &Handler;
+
+  xpc_main(xpcClosure::connection_handler);
+  // xpc_main doesn't ever return
+  return errorCodeToError(std::make_error_code(std::errc::io_error));
+}
+
+} // namespace
+
+namespace clang {
+namespace clangd {
+
+std::unique_ptr<Transport> newXPCTransport() {
+  return llvm::make_unique<XPCTransport>();
+}
+
+} // namespace clangd
+} // namespace clang
diff --git a/clangd/xpc/cmake/Info.plist.in b/clangd/xpc/cmake/Info.plist.in
new file mode 100644
index 0000000..c5eb9fd
--- /dev/null
+++ b/clangd/xpc/cmake/Info.plist.in
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDevelopmentRegion</key>
+  <string>English</string>
+  <key>CFBundleExecutable</key>
+  <string>${CLANGD_XPC_FRAMEWORK_NAME}</string>
+  <key>CFBundleIconFile</key>
+  <string></string>
+  <key>CFBundleIdentifier</key>
+  <string>org.llvm.${CLANGD_XPC_FRAMEWORK_NAME}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>${CLANGD_XPC_FRAMEWORK_NAME}</string>
+  <key>CFBundlePackageType</key>
+  <string>FMWK</string>
+  <key>CFBundleSignature</key>
+  <string>????</string>
+  <key>CFBundleVersion</key>
+  <string></string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0</string>
+  <key>CSResourcesFileMapped</key>
+  <true/>
+</dict>
+</plist>
diff --git a/clangd/xpc/cmake/XPCServiceInfo.plist.in b/clangd/xpc/cmake/XPCServiceInfo.plist.in
new file mode 100644
index 0000000..3c3f8dc
--- /dev/null
+++ b/clangd/xpc/cmake/XPCServiceInfo.plist.in
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleExecutable</key>
+  <string>${CLANGD_XPC_SERVICE_NAME}</string>
+  <key>CFBundleIdentifier</key>
+  <string>${CLANGD_XPC_SERVICE_BUNDLE_NAME}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleName</key>
+  <string>${CLANGD_XPC_SERVICE_NAME}</string>
+  <key>CFBundlePackageType</key>
+  <string>XPC!</string>
+  <key>CFBundleVersion</key>
+  <string></string>
+  <key>CFBundleShortVersionString</key>
+  <string>1.0</string>
+  <key>XPCService</key>
+  <dict>
+    <key>ServiceType</key>
+    <string>Application</string>
+    <key>EnvironmentVariables</key>
+    <dict>
+        <key>CLANGD_AS_XPC_SERVICE</key>
+        <string>1</string>
+    </dict>
+  </dict>
+</dict>
+</plist>
diff --git a/clangd/xpc/cmake/modules/CreateClangdXPCFramework.cmake b/clangd/xpc/cmake/modules/CreateClangdXPCFramework.cmake
new file mode 100644
index 0000000..2299bc8
--- /dev/null
+++ b/clangd/xpc/cmake/modules/CreateClangdXPCFramework.cmake
@@ -0,0 +1,73 @@
+# Creates the ClangdXPC framework.
+macro(create_clangd_xpc_framework target name)
+  set(CLANGD_FRAMEWORK_LOCATION "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${name}.framework")
+  set(CLANGD_FRAMEWORK_OUT_LOCATION "${CLANGD_FRAMEWORK_LOCATION}/Versions/A")
+
+  # Create the framework info PLIST.
+  set(CLANGD_XPC_FRAMEWORK_NAME "${name}")
+  configure_file(
+    "${CLANGD_XPC_SOURCE_DIR}/cmake/Info.plist.in"
+    "${CLANGD_XPC_BINARY_DIR}/${name}.Info.plist")
+
+  set(CLANGD_XPC_SERVICE_NAME "clangd")
+  set(CLANGD_XPC_SERVICE_OUT_LOCATION
+      "${CLANGD_FRAMEWORK_OUT_LOCATION}/XPCServices/${CLANGD_XPC_SERVICE_NAME}.xpc/Contents")
+
+  # Create the XPC service info PLIST.
+  set(CLANGD_XPC_SERVICE_BUNDLE_NAME "org.llvm.${CLANGD_XPC_SERVICE_NAME}")
+  configure_file(
+    "${CLANGD_XPC_SOURCE_DIR}/cmake/XPCServiceInfo.plist.in"
+    "${CLANGD_XPC_BINARY_DIR}/${name}Service.Info.plist")
+
+  # Create the custom command
+  add_custom_command(OUTPUT ${CLANGD_FRAMEWORK_LOCATION}
+    # Copy the PLIST.
+    COMMAND ${CMAKE_COMMAND} -E copy
+      "${CLANGD_XPC_BINARY_DIR}/${name}.Info.plist"
+      "${CLANGD_FRAMEWORK_OUT_LOCATION}/Resources/Info.plist"
+
+    # Copy the framework binary.
+    COMMAND ${CMAKE_COMMAND} -E copy
+       "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${target}.dylib"
+       "${CLANGD_FRAMEWORK_OUT_LOCATION}/${name}"
+
+    # Copy the XPC Service PLIST.
+    COMMAND ${CMAKE_COMMAND} -E copy
+      "${CLANGD_XPC_BINARY_DIR}/${name}Service.Info.plist"
+      "${CLANGD_XPC_SERVICE_OUT_LOCATION}/Info.plist"
+
+    # Copy the Clangd binary.
+    COMMAND ${CMAKE_COMMAND} -E copy
+      "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/clangd"
+      "${CLANGD_XPC_SERVICE_OUT_LOCATION}/MacOS/clangd"
+
+     COMMAND ${CMAKE_COMMAND} -E create_symlink "A"
+     "${CLANGD_FRAMEWORK_LOCATION}/Versions/Current"
+
+     COMMAND ${CMAKE_COMMAND} -E create_symlink
+     "Versions/Current/Resources"
+     "${CLANGD_FRAMEWORK_LOCATION}/Resources"
+
+     COMMAND ${CMAKE_COMMAND} -E create_symlink
+     "Versions/Current/XPCServices"
+     "${CLANGD_FRAMEWORK_LOCATION}/XPCServices"
+
+     COMMAND ${CMAKE_COMMAND} -E create_symlink
+     "Versions/Current/${name}"
+     "${CLANGD_FRAMEWORK_LOCATION}/${name}"
+
+    DEPENDS
+      "${CLANGD_XPC_BINARY_DIR}/${name}.Info.plist"
+      "${CLANGD_XPC_BINARY_DIR}/${name}Service.Info.plist"
+      clangd
+    COMMENT "Creating ClangdXPC framework"
+    VERBATIM
+  )
+
+  add_custom_target(
+    ClangdXPC
+    DEPENDS
+    ${target}
+    ${CLANGD_FRAMEWORK_LOCATION}
+  )
+endmacro(create_clangd_xpc_framework)
diff --git a/clangd/xpc/framework/CMakeLists.txt b/clangd/xpc/framework/CMakeLists.txt
new file mode 100644
index 0000000..a20340f
--- /dev/null
+++ b/clangd/xpc/framework/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+set(SOURCES
+    ClangdXPC.cpp)
+add_clang_library(ClangdXPCLib SHARED
+  ${SOURCES}
+  DEPENDS
+  clangd
+)
+create_clangd_xpc_framework(ClangdXPCLib "ClangdXPC")
diff --git a/clangd/xpc/framework/ClangdXPC.cpp b/clangd/xpc/framework/ClangdXPC.cpp
new file mode 100644
index 0000000..6c68f5c
--- /dev/null
+++ b/clangd/xpc/framework/ClangdXPC.cpp
@@ -0,0 +1,5 @@
+
+/// Returns the bundle identifier of the Clangd XPC service.
+extern "C" const char *clangd_xpc_get_bundle_identifier() {
+  return "org.llvm.clangd";
+}
diff --git a/clangd/xpc/test-client/CMakeLists.txt b/clangd/xpc/test-client/CMakeLists.txt
new file mode 100644
index 0000000..283599e
--- /dev/null
+++ b/clangd/xpc/test-client/CMakeLists.txt
@@ -0,0 +1,26 @@
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+)
+
+add_clang_tool(
+  clangd-xpc-test-client
+  ClangdXPCTestClient.cpp
+
+  DEPENDS ClangdXPC
+)
+
+set(LLVM_LINK_COMPONENTS
+    support
+)
+
+target_link_libraries(clangd-xpc-test-client
+  PRIVATE
+  clangBasic
+  clangDaemon
+  clangFormat
+  clangFrontend
+  clangSema
+  clangTooling
+  clangToolingCore
+  clangdXpcJsonConversions
+)
diff --git a/clangd/xpc/test-client/ClangdXPCTestClient.cpp b/clangd/xpc/test-client/ClangdXPCTestClient.cpp
new file mode 100644
index 0000000..da204a6
--- /dev/null
+++ b/clangd/xpc/test-client/ClangdXPCTestClient.cpp
@@ -0,0 +1,96 @@
+#include "xpc/Conversion.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+#include <xpc/xpc.h>
+
+typedef const char *(*clangd_xpc_get_bundle_identifier_t)(void);
+
+using namespace llvm;
+using namespace clang;
+
+std::string getLibraryPath() {
+  Dl_info info;
+  if (dladdr((void *)(uintptr_t)getLibraryPath, &info) == 0)
+    llvm_unreachable("Call to dladdr() failed");
+  llvm::SmallString<128> LibClangPath;
+  LibClangPath = llvm::sys::path::parent_path(
+      llvm::sys::path::parent_path(info.dli_fname));
+  llvm::sys::path::append(LibClangPath, "lib", "ClangdXPC.framework",
+                          "ClangdXPC");
+  return LibClangPath.str();
+}
+
+static void dumpXPCObject(xpc_object_t Object, llvm::raw_ostream &OS) {
+  xpc_type_t Type = xpc_get_type(Object);
+  if (Type == XPC_TYPE_DICTIONARY) {
+    json::Value Json = clang::clangd::xpcToJson(Object);
+    OS << Json;
+  } else {
+    OS << "<UNKNOWN>";
+  }
+}
+
+int main(int argc, char *argv[]) {
+  // Open the ClangdXPC dylib in the framework.
+  std::string LibPath = getLibraryPath();
+  void *dlHandle = dlopen(LibPath.c_str(), RTLD_LOCAL | RTLD_FIRST);
+  if (!dlHandle)
+    return 1;
+
+  // Lookup the XPC service bundle name, and launch it.
+  clangd_xpc_get_bundle_identifier_t clangd_xpc_get_bundle_identifier =
+      (clangd_xpc_get_bundle_identifier_t)dlsym(
+          dlHandle, "clangd_xpc_get_bundle_identifier");
+  xpc_connection_t conn = xpc_connection_create(
+      clangd_xpc_get_bundle_identifier(), dispatch_get_main_queue());
+
+  // Dump the XPC events.
+  xpc_connection_set_event_handler(conn, ^(xpc_object_t event) {
+    if (event == XPC_ERROR_CONNECTION_INVALID) {
+      llvm::errs() << "Received XPC_ERROR_CONNECTION_INVALID.";
+      exit(EXIT_SUCCESS);
+    }
+    if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
+      llvm::errs() << "Received XPC_ERROR_CONNECTION_INTERRUPTED.";
+      exit(EXIT_SUCCESS);
+    }
+
+    dumpXPCObject(event, llvm::outs());
+    llvm::outs() << "\n";
+  });
+
+  xpc_connection_resume(conn);
+
+  // Read the input to determine the things to send to clangd.
+  llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> Stdin =
+      llvm::MemoryBuffer::getSTDIN();
+  if (!Stdin) {
+    llvm::errs() << "Failed to get STDIN!\n";
+    return 1;
+  }
+  for (llvm::line_iterator It(**Stdin, /*SkipBlanks=*/true,
+                              /*CommentMarker=*/'#');
+       !It.is_at_eof(); ++It) {
+    StringRef Line = *It;
+    if (auto Request = json::parse(Line)) {
+      xpc_object_t Object = clangd::jsonToXpc(*Request);
+      xpc_connection_send_message(conn, Object);
+    } else {
+      llvm::errs() << llvm::Twine("JSON parse error: ")
+                   << llvm::toString(Request.takeError());
+      return 1;
+    }
+  }
+
+  dispatch_main();
+
+  // dispatch_main() doesn't return
+  return EXIT_FAILURE;
+}
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 1976f78..f932af4 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,7 +57,7 @@
 Improvements to clang-query
 ---------------------------
 
-The improvements are...
+- ...
 
 Improvements to clang-rename
 ----------------------------
@@ -67,186 +67,36 @@
 Improvements to clang-tidy
 --------------------------
 
-- New :doc:`abseil-duration-comparison
-  <clang-tidy/checks/abseil-duration-comparison>` check.
+- New :doc:`abseil-duration-addition
+  <clang-tidy/checks/abseil-duration-addition>` check.
 
-  Checks for comparisons which should be done in the ``absl::Duration`` domain
-  instead of the float of integer domains.
+  Checks for cases where addition should be performed in the ``absl::Time``
+  domain.
 
-- New :doc:`abseil-duration-division
-  <clang-tidy/checks/abseil-duration-division>` check.
+- New :doc:`abseil-duration-conversion-cast
+  <clang-tidy/checks/abseil-duration-conversion-cast>` 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 casts of ``absl::Duration`` conversion functions, and recommends
+  the right conversion function instead.
 
-- New :doc:`abseil-duration-factory-float
-  <clang-tidy/checks/abseil-duration-factory-float>` check.
+- New :doc:`abseil-duration-unnecessary-conversion
+  <clang-tidy/checks/abseil-duration-unnecessary-conversion>` 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.
+  Finds and fixes cases where ``absl::Duration`` values are being converted to
+  numeric types and back again.
 
-- New :doc:`abseil-duration-factory-scale
-  <clang-tidy/checks/abseil-duration-factory-scale>` check.
+- New :doc:`google-readability-avoid-underscore-in-googletest-name
+  <clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name>`
+  check.
 
-  Checks for cases where arguments to ``absl::Duration`` factory functions are
-  scaled internally and could be changed to a different factory function.
+  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-duration-subtraction
-  <clang-tidy/checks/abseil-duration-subtraction>` check.
-
-  Checks for cases where subtraction should be performed in the
-  ``absl::Duration`` domain.
-
-- New :doc:`abseil-faster-strsplit-delimiter
-  <clang-tidy/checks/abseil-faster-strsplit-delimiter>` check.
-
-  Finds instances of ``absl::StrSplit()`` or ``absl::MaxSplits()`` where the
-  delimiter is a single character string literal and replaces with a character.
-
-- New :doc:`abseil-no-internal-dependencies
-  <clang-tidy/checks/abseil-no-internal-dependencies>` check.
-
-  Gives a warning if code using Abseil depends on internal details.
-
-- New :doc:`abseil-no-namespace
-  <clang-tidy/checks/abseil-no-namespace>` check.
-
-  Ensures code does not open ``namespace absl`` as that violates Abseil's
-  compatibility guidelines.
-
-- New :doc:`abseil-redundant-strcat-calls
-  <clang-tidy/checks/abseil-redundant-strcat-calls>` check.
-
-  Suggests removal of unnecessary calls to ``absl::StrCat`` when the result is
-  being passed to another ``absl::StrCat`` or ``absl::StrAppend``.
-
-- New :doc:`abseil-str-cat-append
-  <clang-tidy/checks/abseil-str-cat-append>` check.
-
-  Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
-  ``absl::StrAppend()`` should be used instead.
-
-- New :doc:`abseil-upgrade-duration-conversions
-  <clang-tidy/checks/abseil-upgrade-duration-conversions>` check.
-
-  Finds calls to ``absl::Duration`` arithmetic operators and factories whose
-  argument needs an explicit cast to continue compiling after upcoming API
-  changes.
-
-- New :doc:`bugprone-too-small-loop-variable
-  <clang-tidy/checks/bugprone-too-small-loop-variable>` 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.
-
-- New :doc:`cppcoreguidelines-macro-usage
-  <clang-tidy/checks/cppcoreguidelines-macro-usage>` check.
-
-  Finds macro usage that is considered problematic because better language
-  constructs exist for the task.
-
-- New :doc:`google-objc-function-naming
-  <clang-tidy/checks/google-objc-function-naming>` check.
-
-  Checks that function names in function declarations comply with the naming
-  conventions described in the Google Objective-C Style Guide.
-
-- 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:`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-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:`readability-redundant-smartptr-get
-  <clang-tidy/checks/readability-redundant-smartptr-get>` check does not warn
-  about calls inside macros anymore by default.
-
-- 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:`bugprone-argument-comment
+  <clang-tidy/checks/bugprone-argument-comment>` now supports
+  `CommentBoolLiterals`, `CommentIntegerLiterals`,  `CommentFloatLiterals`,
+  `CommentUserDefiniedLiterals`, `CommentStringLiterals`,
+  `CommentCharacterLiterals` & `CommentNullPtrs` options.
 
 Improvements to include-fixer
 -----------------------------
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/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..719bed3
--- /dev/null
+++ b/docs/clang-tidy/Contributing.rst
@@ -0,0 +1,512 @@
+================
+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 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: 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 "../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
+<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-unnecessary-conversion.rst b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst
new file mode 100644
index 0000000..938c46d
--- /dev/null
+++ b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst
@@ -0,0 +1,31 @@
+.. 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.
+
+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 - 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;
+
+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/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/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 e454208..13d8f6f 100644
--- a/docs/clang-tidy/checks/list.rst
+++ b/docs/clang-tidy/checks/list.rst
@@ -4,17 +4,20 @@
 =================
 
 .. 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-string-find-startswith
    abseil-str-cat-append
+   abseil-string-find-startswith
    abseil-upgrade-duration-conversions
    android-cloexec-accept
    android-cloexec-accept4
@@ -91,8 +94,8 @@
    cert-msc50-cpp
    cert-msc51-cpp
    cert-oop11-cpp (redirects to performance-move-constructor-init) <cert-oop11-cpp>
-   cppcoreguidelines-avoid-goto
    cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <cppcoreguidelines-avoid-c-arrays>
+   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-interfaces-global-init
@@ -130,6 +133,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>
@@ -159,6 +163,7 @@
    hicpp-special-member-functions (redirects to cppcoreguidelines-special-member-functions) <hicpp-special-member-functions>
    hicpp-static-assert (redirects to misc-static-assert) <hicpp-static-assert>
    hicpp-undelegated-constructor (redirects to bugprone-undelegated-constructor) <hicpp-undelegated-constructor>
+   hicpp-uppercase-literal-suffix (redirects to readability-uppercase-literal-suffix) <hicpp-uppercase-literal-suffix>
    hicpp-use-auto (redirects to modernize-use-auto) <hicpp-use-auto>
    hicpp-use-emplace (redirects to modernize-use-emplace) <hicpp-use-emplace>
    hicpp-use-equals-default (redirects to modernize-use-equals-default) <hicpp-use-equals-default>
@@ -167,7 +172,6 @@
    hicpp-use-nullptr (redirects to modernize-use-nullptr) <hicpp-use-nullptr>
    hicpp-use-override (redirects to modernize-use-override) <hicpp-use-override>
    hicpp-vararg (redirects to cppcoreguidelines-pro-type-vararg) <hicpp-vararg>
-   hicpp-uppercase-literal-suffix (redirects to readability-uppercase-literal-suffix) <hicpp-uppercase-literal-suffix>
    llvm-header-guard
    llvm-include-order
    llvm-namespace-comment
@@ -207,6 +211,7 @@
    modernize-use-emplace
    modernize-use-equals-default
    modernize-use-equals-delete
+   modernize-use-nodiscard
    modernize-use-noexcept
    modernize-use-nullptr
    modernize-use-override
@@ -253,6 +258,7 @@
    readability-redundant-declaration
    readability-redundant-function-ptr-dereference
    readability-redundant-member-init
+   readability-redundant-preprocessor
    readability-redundant-smartptr-get
    readability-redundant-string-cstr
    readability-redundant-string-init
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/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/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-nodiscard.rst b/docs/clang-tidy/checks/modernize-use-nodiscard.rst
new file mode 100644
index 0000000..3048db8
--- /dev/null
+++ b/docs/clang-tidy/checks/modernize-use-nodiscard.rst
@@ -0,0 +1,82 @@
+.. title:: clang-tidy - modernize-use-nodiscard
+
+modernize-use-nodiscard
+=======================
+
+Adds ``[[nodiscard]]`` attributes (introduced in C++17) to member functions in
+order to highlight at compile time which return values should not be ignored.
+
+Member functions need to satisfy the following conditions to be considered by
+this check:
+
+ - no ``[[nodiscard]]``, ``[[noreturn]]``,
+   ``__attribute__((warn_unused_result))``,
+   ``[[clang::warn_unused_result]]`` nor ``[[gcc::warn_unused_result]]``
+   attribute,
+ - non-void return type,
+ - non-template return types,
+ - const member function,
+ - non-variadic functions,
+ - no non-const reference parameters,
+ - no pointer parameters,
+ - no template parameters,
+ - no template function parameters,
+ - not be a member of a class with mutable member variables,
+ - no Lambdas,
+ - no conversion functions.
+
+Such functions have no means of altering any state or passing values other than
+via the return type. Unless the member functions are altering state via some
+external call (e.g. I/O).
+
+Example
+-------
+
+.. code-block:: c++
+
+    bool empty() const;
+    bool empty(int i) const;
+
+transforms to:
+
+.. code-block:: c++
+
+    [[nodiscard] bool empty() const;
+    [[nodiscard] bool empty(int i) const;
+
+Options
+-------
+
+.. option:: ReplacementString
+
+    Specifies a macro to use instead of ``[[nodiscard]]``. This is useful when
+    maintaining source code that needs to compile with a pre-C++17 compiler.
+
+Example
+^^^^^^^
+
+.. code-block:: c++
+
+    bool empty() const;
+    bool empty(int i) const;
+
+transforms to:
+
+.. code-block:: c++
+
+    NO_DISCARD bool empty() const;
+    NO_DISCARD bool empty(int i) const;
+
+if the :option:`ReplacementString` option is set to `NO_DISCARD`.
+
+.. note::
+
+    If the :option:`ReplacementString` is not a C++ attribute, but instead a 
+    macro, then that macro must be defined in scope or the fix-it will not be 
+    applied.
+
+.. note::
+
+    For alternative ``__attribute__`` syntax options to mark functions as
+    ``[[nodiscard]]`` in non-c++17 source code.
+    See https://clang.llvm.org/docs/AttributeReference.html#nodiscard-warn-unused-result
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-identifier-naming.rst b/docs/clang-tidy/checks/readability-identifier-naming.rst
index 30408c1..d7e8859 100644
--- a/docs/clang-tidy/checks/readability-identifier-naming.rst
+++ b/docs/clang-tidy/checks/readability-identifier-naming.rst
@@ -5,14 +5,1919 @@
 
 Checks for identifiers naming style mismatch.
 
-This check will try to enforce coding guidelines on the identifiers naming.
-It supports `lower_case`, `UPPER_CASE`, `camelBack` and `CamelCase` casing and
-tries to convert from one to another if a mismatch is detected.
+This check will try to enforce coding guidelines on the identifiers naming. It
+supports one of the following casing types and tries to convert from one to
+another if a mismatch is detected
 
-It also supports a fixed prefix and suffix that will be prepended or
-appended to the identifiers, regardless of the casing.
+Casing types inclde:
+
+ - ``lower_case``,
+ - ``UPPER_CASE``,
+ - ``camelBack``,
+ - ``CamelCase``,
+ - ``camel_Snake_Back``,
+ - ``Camel_Snake_Case``,
+ - ``aNy_CasE``.
+
+It also supports a fixed prefix and suffix that will be prepended or appended
+to the identifiers, regardless of the casing.
 
 Many configuration options are available, in order to be able to create
-different rules for different kind of identifier. In general, the
-rules are falling back to a more generic rule if the specific case is not
-configured.
+different rules for different kinds of identifiers. In general, the rules are
+falling back to a more generic rule if the specific case is not configured.
+
+Options
+-------
+
+The following options are describe below:
+
+ - :option:`AbstractClassCase`, :option:`AbstractClassPrefix`, :option:`AbstractClassSuffix`
+ - :option:`ClassCase`, :option:`ClassPrefix`, :option:`ClassSuffix`
+ - :option:`ClassConstantCase`, :option:`ClassConstantPrefix`, :option:`ClassConstantSuffix`
+ - :option:`ClassMemberCase`, :option:`ClassMemberPrefix`, :option:`ClassMemberSuffix`
+ - :option:`ClassMethodCase`, :option:`ClassMethodPrefix`, :option:`ClassMethodSuffix`
+ - :option:`ConstantCase`, :option:`ConstantPrefix`, :option:`ConstantSuffix`
+ - :option:`ConstantMemberCase`, :option:`ConstantMemberPrefix`, :option:`ConstantMemberSuffix`
+ - :option:`ConstantParameterCase`, :option:`ConstantParameterPrefix`, :option:`ConstantParameterSuffix`
+ - :option:`ConstantPointerParameterCase`, :option:`ConstantPointerParameterPrefix`, :option:`ConstantPointerParameterSuffix`
+ - :option:`ConstexprFunctionCase`, :option:`ConstexprFunctionPrefix`, :option:`ConstexprFunctionSuffix`
+ - :option:`ConstexprMethodCase`, :option:`ConstexprMethodPrefix`, :option:`ConstexprMethodSuffix`
+ - :option:`ConstexprVariableCase`, :option:`ConstexprVariablePrefix`, :option:`ConstexprVariableSuffix`
+ - :option:`EnumCase`, :option:`EnumPrefix`, :option:`EnumSuffix`
+ - :option:`EnumConstantCase`, :option:`EnumConstantPrefix`, :option:`EnumConstantSuffix`
+ - :option:`FunctionCase`, :option:`FunctionPrefix`, :option:`FunctionSuffix`
+ - :option:`GlobalConstantCase`, :option:`GlobalConstantPrefix`, :option:`GlobalConstantSuffix`
+ - :option:`GlobalConstantPointerCase`, :option:`GlobalConstantPointerPrefix`, :option:`GlobalConstantPointerSuffix`
+ - :option:`GlobalFunctionCase`, :option:`GlobalFunctionPrefix`, :option:`GlobalFunctionSuffix`
+ - :option:`GlobalPointerCase`, :option:`GlobalPointerPrefix`, :option:`GlobalPointerSuffix`
+ - :option:`GlobalVariableCase`, :option:`GlobalVariablePrefix`, :option:`GlobalVariableSuffix`
+ - :option:`InlineNamespaceCase`, :option:`InlineNamespacePrefix`, :option:`InlineNamespaceSuffix`
+ - :option:`LocalConstantCase`, :option:`LocalConstantPrefix`, :option:`LocalConstantSuffix`
+ - :option:`LocalConstantPointerCase`, :option:`LocalConstantPointerPrefix`, :option:`LocalConstantPointerSuffix`
+ - :option:`LocalPointerCase`, :option:`LocalPointerPrefix`, :option:`LocalPointerSuffix`
+ - :option:`LocalVariableCase`, :option:`LocalVariablePrefix`, :option:`LocalVariableSuffix`
+ - :option:`MemberCase`, :option:`MemberPrefix`, :option:`MemberSuffix`
+ - :option:`MethodCase`, :option:`MethodPrefix`, :option:`MethodSuffix`
+ - :option:`NamespaceCase`, :option:`NamespacePrefix`, :option:`NamespaceSuffix`
+ - :option:`ParameterCase`, :option:`ParameterPrefix`, :option:`ParameterSuffix`
+ - :option:`ParameterPackCase`, :option:`ParameterPackPrefix`, :option:`ParameterPackSuffix`
+ - :option:`PointerParameterCase`, :option:`PointerParameterPrefix`, :option:`PointerParameterSuffix`
+ - :option:`PrivateMemberCase`, :option:`PrivateMemberPrefix`, :option:`PrivateMemberSuffix`
+ - :option:`PrivateMethodCase`, :option:`PrivateMethodPrefix`, :option:`PrivateMethodSuffix`
+ - :option:`ProtectedMemberCase`, :option:`ProtectedMemberPrefix`, :option:`ProtectedMemberSuffix`
+ - :option:`ProtectedMethodCase`, :option:`ProtectedMethodPrefix`, :option:`ProtectedMethodSuffix`
+ - :option:`PublicMemberCase`, :option:`PublicMemberPrefix`, :option:`PublicMemberSuffix`
+ - :option:`PublicMethodCase`, :option:`PublicMethodPrefix`, :option:`PublicMethodSuffix`
+ - :option:`StaticConstantCase`, :option:`StaticConstantPrefix`, :option:`StaticConstantSuffix`
+ - :option:`StaticVariableCase`, :option:`StaticVariablePrefix`, :option:`StaticVariableSuffix`
+ - :option:`StructCase`, :option:`StructPrefix`, :option:`StructSuffix`
+ - :option:`TemplateParameterCase`, :option:`TemplateParameterPrefix`, :option:`TemplateParameterSuffix`
+ - :option:`TemplateTemplateParameterCase`, :option:`TemplateTemplateParameterPrefix`, :option:`TemplateTemplateParameterSuffix`
+ - :option:`TypeAliasCase`, :option:`TypeAliasPrefix`, :option:`TypeAliasSuffix`
+ - :option:`TypedefCase`, :option:`TypedefPrefix`, :option:`TypedefSuffix`
+ - :option:`TypeTemplateParameterCase`, :option:`TypeTemplateParameterPrefix`, :option:`TypeTemplateParameterSuffix`
+ - :option:`UnionCase`, :option:`UnionPrefix`, :option:`UnionSuffix`
+ - :option:`ValueTemplateParameterCase`, :option:`ValueTemplateParameterPrefix`, :option:`ValueTemplateParameterSuffix`
+ - :option:`VariableCase`, :option:`VariablePrefix`, :option:`VariableSuffix`
+ - :option:`VirtualMethodCase`, :option:`VirtualMethodPrefix`, :option:`VirtualMethodSuffix`
+
+.. option:: AbstractClassCase
+
+    When defined, the check will ensure abstract class names conform to the
+    selected casing.
+
+.. option:: AbstractClassPrefix
+
+    When defined, the check will ensure abstract class names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: AbstractClassSuffix
+
+    When defined, the check will ensure abstract class names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - AbstractClassCase of ``lower_case``
+   - AbstractClassPrefix of ``pre_``
+   - AbstractClassSuffix of ``_post``
+
+Identifies and/or transforms abstract class names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class ABSTRACT_CLASS {
+    public:
+      ABSTRACT_CLASS();
+    };
+
+After:
+
+.. code-block:: c++
+
+    class pre_abstract_class_post {
+    public:
+      pre_abstract_class_post();
+    };
+
+.. option:: ClassCase
+
+    When defined, the check will ensure class names conform to the
+    selected casing.
+
+.. option:: ClassPrefix
+
+    When defined, the check will ensure class names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ClassSuffix
+
+    When defined, the check will ensure class names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ClassCase of ``lower_case``
+   - ClassPrefix of ``pre_``
+   - ClassSuffix of ``_post``
+
+Identifies and/or transforms class names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      FOO();
+      ~FOO();
+    };
+
+After:
+
+.. code-block:: c++
+
+    class pre_foo_post {
+    public:
+      pre_foo_post();
+      ~pre_foo_post();
+    };
+
+.. option:: ClassConstantCase
+
+    When defined, the check will ensure class constant names conform to the
+    selected casing.
+
+.. option:: ClassConstantPrefix
+
+    When defined, the check will ensure class constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ClassConstantSuffix
+
+    When defined, the check will ensure class constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ClassConstantCase of ``lower_case``
+   - ClassConstantPrefix of ``pre_``
+   - ClassConstantSuffix of ``_post``
+
+Identifies and/or transforms class constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      static const int CLASS_CONSTANT;
+    };
+
+After:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      static const int pre_class_constant_post;
+    };
+
+.. option:: ClassMemberCase
+
+    When defined, the check will ensure class member names conform to the
+    selected casing.
+
+.. option:: ClassMemberPrefix
+
+    When defined, the check will ensure class member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ClassMemberSuffix
+
+    When defined, the check will ensure class member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ClassMemberCase of ``lower_case``
+   - ClassMemberPrefix of ``pre_``
+   - ClassMemberSuffix of ``_post``
+
+Identifies and/or transforms class member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      static int CLASS_CONSTANT;
+    };
+
+After:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      static int pre_class_constant_post;
+    };
+
+.. option:: ClassMethodCase
+
+    When defined, the check will ensure class method names conform to the
+    selected casing.
+
+.. option:: ClassMethodPrefix
+
+    When defined, the check will ensure class method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ClassMethodSuffix
+
+    When defined, the check will ensure class method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ClassMethodCase of ``lower_case``
+   - ClassMethodPrefix of ``pre_``
+   - ClassMethodSuffix of ``_post``
+
+Identifies and/or transforms class method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      int CLASS_MEMBER();
+    };
+
+After:
+
+.. code-block:: c++
+
+    class FOO {
+    public:
+      int pre_class_member_post();
+    };
+
+.. option:: ConstantCase
+
+    When defined, the check will ensure constant names conform to the
+    selected casing.
+
+.. option:: ConstantPrefix
+
+    When defined, the check will ensure constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstantSuffix
+
+    When defined, the check will ensure constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstantCase of ``lower_case``
+   - ConstantPrefix of ``pre_``
+   - ConstantSuffix of ``_post``
+
+Identifies and/or transforms constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void function() { unsigned const MyConst_array[] = {1, 2, 3}; }
+
+After:
+
+.. code-block:: c++
+
+    void function() { unsigned const pre_myconst_array_post[] = {1, 2, 3}; }
+
+.. option:: ConstantMemberCase
+
+    When defined, the check will ensure constant member names conform to the
+    selected casing.
+
+.. option:: ConstantMemberPrefix
+
+    When defined, the check will ensure constant member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstantMemberSuffix
+
+    When defined, the check will ensure constant member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstantMemberCase of ``lower_case``
+   - ConstantMemberPrefix of ``pre_``
+   - ConstantMemberSuffix of ``_post``
+
+Identifies and/or transforms constant member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+      char const MY_ConstMember_string[4] = "123";
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+      char const pre_my_constmember_string_post[4] = "123";
+    }
+
+.. option:: ConstantParameterCase
+
+    When defined, the check will ensure constant parameter names conform to the
+    selected casing.
+
+.. option:: ConstantParameterPrefix
+
+    When defined, the check will ensure constant parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstantParameterSuffix
+
+    When defined, the check will ensure constant parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstantParameterCase of ``lower_case``
+   - ConstantParameterPrefix of ``pre_``
+   - ConstantParameterSuffix of ``_post``
+
+Identifies and/or transforms constant parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
+
+After:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int PARAMETER_1, int const pre_const_parameter_post);
+
+.. option:: ConstantPointerParameterCase
+
+    When defined, the check will ensure constant pointer parameter names conform to the
+    selected casing.
+
+.. option:: ConstantPointerParameterPrefix
+
+    When defined, the check will ensure constant pointer parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstantPointerParameterSuffix
+
+    When defined, the check will ensure constant pointer parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstantPointerParameterCase of ``lower_case``
+   - ConstantPointerParameterPrefix of ``pre_``
+   - ConstantPointerParameterSuffix of ``_post``
+
+Identifies and/or transforms constant pointer parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int const *CONST_parameter);
+
+After:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int const *pre_const_parameter_post);
+
+.. option:: ConstexprFunctionCase
+
+    When defined, the check will ensure constexpr function names conform to the
+    selected casing.
+
+.. option:: ConstexprFunctionPrefix
+
+    When defined, the check will ensure constexpr function names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstexprFunctionSuffix
+
+    When defined, the check will ensure constexpr function names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstexprFunctionCase of ``lower_case``
+   - ConstexprFunctionPrefix of ``pre_``
+   - ConstexprFunctionSuffix of ``_post``
+
+Identifies and/or transforms constexpr function names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    constexpr int CE_function() { return 3; }
+
+After:
+
+.. code-block:: c++
+
+    constexpr int pre_ce_function_post() { return 3; }
+
+.. option:: ConstexprMethodCase
+
+    When defined, the check will ensure constexpr method names conform to the
+    selected casing.
+
+.. option:: ConstexprMethodPrefix
+
+    When defined, the check will ensure constexpr method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstexprMethodSuffix
+
+    When defined, the check will ensure constexpr method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstexprMethodCase of ``lower_case``
+   - ConstexprMethodPrefix of ``pre_``
+   - ConstexprMethodSuffix of ``_post``
+
+Identifies and/or transforms constexpr method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      constexpr int CST_expr_Method() { return 2; }
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      constexpr int pre_cst_expr_method_post() { return 2; }
+    }
+
+.. option:: ConstexprVariableCase
+
+    When defined, the check will ensure constexpr variable names conform to the
+    selected casing.
+
+.. option:: ConstexprVariablePrefix
+
+    When defined, the check will ensure constexpr variable names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ConstexprVariableSuffix
+
+    When defined, the check will ensure constexpr variable names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ConstexprVariableCase of ``lower_case``
+   - ConstexprVariablePrefix of ``pre_``
+   - ConstexprVariableSuffix of ``_post``
+
+Identifies and/or transforms constexpr variable names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    constexpr int ConstExpr_variable = MyConstant;
+
+After:
+
+.. code-block:: c++
+
+    constexpr int pre_constexpr_variable_post = MyConstant;
+
+.. option:: EnumCase
+
+    When defined, the check will ensure enumeration names conform to the
+    selected casing.
+
+.. option:: EnumPrefix
+
+    When defined, the check will ensure enumeration names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: EnumSuffix
+
+    When defined, the check will ensure enumeration names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - EnumCase of ``lower_case``
+   - EnumPrefix of ``pre_``
+   - EnumSuffix of ``_post``
+
+Identifies and/or transforms enumeration names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    enum FOO { One, Two, Three };
+
+After:
+
+.. code-block:: c++
+
+    enum pre_foo_post { One, Two, Three };
+
+.. option:: EnumConstantCase
+
+    When defined, the check will ensure enumeration constant names conform to the
+    selected casing.
+
+.. option:: EnumConstantPrefix
+
+    When defined, the check will ensure enumeration constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: EnumConstantSuffix
+
+    When defined, the check will ensure enumeration constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - EnumConstantCase of ``lower_case``
+   - EnumConstantPrefix of ``pre_``
+   - EnumConstantSuffix of ``_post``
+
+Identifies and/or transforms enumeration constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    enum FOO { One, Two, Three };
+
+After:
+
+.. code-block:: c++
+
+    enum FOO { pre_One_post, pre_Two_post, pre_Three_post };
+
+.. option:: FunctionCase
+
+    When defined, the check will ensure function names conform to the
+    selected casing.
+
+.. option:: FunctionPrefix
+
+    When defined, the check will ensure function names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: FunctionSuffix
+
+    When defined, the check will ensure function names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - FunctionCase of ``lower_case``
+   - FunctionPrefix of ``pre_``
+   - FunctionSuffix of ``_post``
+
+Identifies and/or transforms function names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    char MY_Function_string();
+
+After:
+
+.. code-block:: c++
+
+    char pre_my_function_string_post();
+
+.. option:: GlobalConstantCase
+
+    When defined, the check will ensure global constant names conform to the
+    selected casing.
+
+.. option:: GlobalConstantPrefix
+
+    When defined, the check will ensure global constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: GlobalConstantSuffix
+
+    When defined, the check will ensure global constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - GlobalConstantCase of ``lower_case``
+   - GlobalConstantPrefix of ``pre_``
+   - GlobalConstantSuffix of ``_post``
+
+Identifies and/or transforms global constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    unsigned const MyConstGlobal_array[] = {1, 2, 3};
+
+After:
+
+.. code-block:: c++
+
+    unsigned const pre_myconstglobal_array_post[] = {1, 2, 3};
+
+.. option:: GlobalConstantPointerCase
+
+    When defined, the check will ensure global constant pointer names conform to the
+    selected casing.
+
+.. option:: GlobalConstantPointerPrefix
+
+    When defined, the check will ensure global constant pointer names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: GlobalConstantPointerSuffix
+
+    When defined, the check will ensure global constant pointer names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - GlobalConstantPointerCase of ``lower_case``
+   - GlobalConstantPointerPrefix of ``pre_``
+   - GlobalConstantPointerSuffix of ``_post``
+
+Identifies and/or transforms global constant pointer names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    int *const MyConstantGlobalPointer = nullptr;
+
+After:
+
+.. code-block:: c++
+
+    int *const pre_myconstantglobalpointer_post = nullptr;
+
+.. option:: GlobalFunctionCase
+
+    When defined, the check will ensure global function names conform to the
+    selected casing.
+
+.. option:: GlobalFunctionPrefix
+
+    When defined, the check will ensure global function names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: GlobalFunctionSuffix
+
+    When defined, the check will ensure global function names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - GlobalFunctionCase of ``lower_case``
+   - GlobalFunctionPrefix of ``pre_``
+   - GlobalFunctionSuffix of ``_post``
+
+Identifies and/or transforms global function names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
+
+After:
+
+.. code-block:: c++
+
+    void pre_global_function_post(int PARAMETER_1, int const CONST_parameter);
+
+.. option:: GlobalPointerCase
+
+    When defined, the check will ensure global pointer names conform to the
+    selected casing.
+
+.. option:: GlobalPointerPrefix
+
+    When defined, the check will ensure global pointer names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: GlobalPointerSuffix
+
+    When defined, the check will ensure global pointer names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - GlobalPointerCase of ``lower_case``
+   - GlobalPointerPrefix of ``pre_``
+   - GlobalPointerSuffix of ``_post``
+
+Identifies and/or transforms global pointer names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    int *GLOBAL3;
+
+After:
+
+.. code-block:: c++
+
+    int *pre_global3_post;
+
+.. option:: GlobalVariableCase
+
+    When defined, the check will ensure global variable names conform to the
+    selected casing.
+
+.. option:: GlobalVariablePrefix
+
+    When defined, the check will ensure global variable names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: GlobalVariableSuffix
+
+    When defined, the check will ensure global variable names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - GlobalVariableCase of ``lower_case``
+   - GlobalVariablePrefix of ``pre_``
+   - GlobalVariableSuffix of ``_post``
+
+Identifies and/or transforms global variable names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    int GLOBAL3;
+
+After:
+
+.. code-block:: c++
+
+    int pre_global3_post;
+
+.. option:: InlineNamespaceCase
+
+    When defined, the check will ensure inline namespaces names conform to the
+    selected casing.
+
+.. option:: InlineNamespacePrefix
+
+    When defined, the check will ensure inline namespaces names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: InlineNamespaceSuffix
+
+    When defined, the check will ensure inline namespaces names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - InlineNamespaceCase of ``lower_case``
+   - InlineNamespacePrefix of ``pre_``
+   - InlineNamespaceSuffix of ``_post``
+
+Identifies and/or transforms inline namespaces names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    namespace FOO_NS {
+    inline namespace InlineNamespace {
+    ...
+    }
+    } // namespace FOO_NS
+
+After:
+
+.. code-block:: c++
+
+    namespace FOO_NS {
+    inline namespace pre_inlinenamespace_post {
+    ...
+    }
+    } // namespace FOO_NS
+
+.. option:: LocalConstantCase
+
+    When defined, the check will ensure local constant names conform to the
+    selected casing.
+
+.. option:: LocalConstantPrefix
+
+    When defined, the check will ensure local constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: LocalConstantSuffix
+
+    When defined, the check will ensure local constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - LocalConstantCase of ``lower_case``
+   - LocalConstantPrefix of ``pre_``
+   - LocalConstantSuffix of ``_post``
+
+Identifies and/or transforms local constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void foo() { int const local_Constant = 3; }
+
+After:
+
+.. code-block:: c++
+
+    void foo() { int const pre_local_constant_post = 3; }
+
+.. option:: LocalConstantPointerCase
+
+    When defined, the check will ensure local constant pointer names conform to the
+    selected casing.
+
+.. option:: LocalConstantPointerPrefix
+
+    When defined, the check will ensure local constant pointer names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: LocalConstantPointerSuffix
+
+    When defined, the check will ensure local constant pointer names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - LocalConstantPointerCase of ``lower_case``
+   - LocalConstantPointerPrefix of ``pre_``
+   - LocalConstantPointerSuffix of ``_post``
+
+Identifies and/or transforms local constant pointer names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void foo() { int const *local_Constant = 3; }
+
+After:
+
+.. code-block:: c++
+
+    void foo() { int const *pre_local_constant_post = 3; }
+
+.. option:: LocalPointerCase
+
+    When defined, the check will ensure local pointer names conform to the
+    selected casing.
+
+.. option:: LocalPointerPrefix
+
+    When defined, the check will ensure local pointer names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: LocalPointerSuffix
+
+    When defined, the check will ensure local pointer names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - LocalPointerCase of ``lower_case``
+   - LocalPointerPrefix of ``pre_``
+   - LocalPointerSuffix of ``_post``
+
+Identifies and/or transforms local pointer names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void foo() { int *local_Constant; }
+
+After:
+
+.. code-block:: c++
+
+    void foo() { int *pre_local_constant_post; }
+
+.. option:: LocalVariableCase
+
+    When defined, the check will ensure local variable names conform to the
+    selected casing.
+
+.. option:: LocalVariablePrefix
+
+    When defined, the check will ensure local variable names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: LocalVariableSuffix
+
+    When defined, the check will ensure local variable names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - LocalVariableCase of ``lower_case``
+   - LocalVariablePrefix of ``pre_``
+   - LocalVariableSuffix of ``_post``
+
+Identifies and/or transforms local variable names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void foo() { int local_Constant; }
+
+After:
+
+.. code-block:: c++
+
+    void foo() { int pre_local_constant_post; }
+
+.. option:: MemberCase
+
+    When defined, the check will ensure member names conform to the
+    selected casing.
+
+.. option:: MemberPrefix
+
+    When defined, the check will ensure member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: MemberSuffix
+
+    When defined, the check will ensure member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - MemberCase of ``lower_case``
+   - MemberPrefix of ``pre_``
+   - MemberSuffix of ``_post``
+
+Identifies and/or transforms member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+      char MY_ConstMember_string[4];
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+      char pre_my_constmember_string_post[4];
+    }
+
+.. option:: MethodCase
+
+    When defined, the check will ensure method names conform to the
+    selected casing.
+
+.. option:: MethodPrefix
+
+    When defined, the check will ensure method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: MethodSuffix
+
+    When defined, the check will ensure method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - MethodCase of ``lower_case``
+   - MethodPrefix of ``pre_``
+   - MethodSuffix of ``_post``
+
+Identifies and/or transforms method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+      char MY_Method_string();
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+      char pre_my_method_string_post();
+    }
+
+.. option:: NamespaceCase
+
+    When defined, the check will ensure namespace names conform to the
+    selected casing.
+
+.. option:: NamespacePrefix
+
+    When defined, the check will ensure namespace names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: NamespaceSuffix
+
+    When defined, the check will ensure namespace names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - NamespaceCase of ``lower_case``
+   - NamespacePrefix of ``pre_``
+   - NamespaceSuffix of ``_post``
+
+Identifies and/or transforms namespace names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    namespace FOO_NS {
+    ...
+    }
+
+After:
+
+.. code-block:: c++
+
+    namespace pre_foo_ns_post {
+    ...
+    }
+
+.. option:: ParameterCase
+
+    When defined, the check will ensure parameter names conform to the
+    selected casing.
+
+.. option:: ParameterPrefix
+
+    When defined, the check will ensure parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ParameterSuffix
+
+    When defined, the check will ensure parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ParameterCase of ``lower_case``
+   - ParameterPrefix of ``pre_``
+   - ParameterSuffix of ``_post``
+
+Identifies and/or transforms parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int PARAMETER_1, int const CONST_parameter);
+
+After:
+
+.. code-block:: c++
+
+    void GLOBAL_FUNCTION(int pre_parameter_post, int const CONST_parameter);
+
+.. option:: ParameterPackCase
+
+    When defined, the check will ensure parameter pack names conform to the
+    selected casing.
+
+.. option:: ParameterPackPrefix
+
+    When defined, the check will ensure parameter pack names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ParameterPackSuffix
+
+    When defined, the check will ensure parameter pack names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ParameterPackCase of ``lower_case``
+   - ParameterPackPrefix of ``pre_``
+   - ParameterPackSuffix of ``_post``
+
+Identifies and/or transforms parameter pack names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    template <typename... TYPE_parameters> {
+      void FUNCTION(int... TYPE_parameters);
+    }
+
+After:
+
+.. code-block:: c++
+
+    template <typename... TYPE_parameters> {
+      void FUNCTION(int... pre_type_parameters_post);
+    }
+
+.. option:: PointerParameterCase
+
+    When defined, the check will ensure pointer parameter names conform to the
+    selected casing.
+
+.. option:: PointerParameterPrefix
+
+    When defined, the check will ensure pointer parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: PointerParameterSuffix
+
+    When defined, the check will ensure pointer parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - PointerParameterCase of ``lower_case``
+   - PointerParameterPrefix of ``pre_``
+   - PointerParameterSuffix of ``_post``
+
+Identifies and/or transforms pointer parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    void FUNCTION(int *PARAMETER);
+
+After:
+
+.. code-block:: c++
+
+    void FUNCTION(int *pre_parameter_post);
+
+.. option:: PrivateMemberCase
+
+    When defined, the check will ensure private member names conform to the
+    selected casing.
+
+.. option:: PrivateMemberPrefix
+
+    When defined, the check will ensure private member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: PrivateMemberSuffix
+
+    When defined, the check will ensure private member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - PrivateMemberCase of ``lower_case``
+   - PrivateMemberPrefix of ``pre_``
+   - PrivateMemberSuffix of ``_post``
+
+Identifies and/or transforms private member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    private:
+      int Member_Variable;
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    private:
+      int pre_member_variable_post;
+    }
+
+.. option:: PrivateMethodCase
+
+    When defined, the check will ensure private method names conform to the
+    selected casing.
+
+.. option:: PrivateMethodPrefix
+
+    When defined, the check will ensure private method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: PrivateMethodSuffix
+
+    When defined, the check will ensure private method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - PrivateMethodCase of ``lower_case``
+   - PrivateMethodPrefix of ``pre_``
+   - PrivateMethodSuffix of ``_post``
+
+Identifies and/or transforms private method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    private:
+      int Member_Method();
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    private:
+      int pre_member_method_post();
+    }
+
+.. option:: ProtectedMemberCase
+
+    When defined, the check will ensure protected member names conform to the
+    selected casing.
+
+.. option:: ProtectedMemberPrefix
+
+    When defined, the check will ensure protected member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ProtectedMemberSuffix
+
+    When defined, the check will ensure protected member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ProtectedMemberCase of ``lower_case``
+   - ProtectedMemberPrefix of ``pre_``
+   - ProtectedMemberSuffix of ``_post``
+
+Identifies and/or transforms protected member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    protected:
+      int Member_Variable;
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    protected:
+      int pre_member_variable_post;
+    }
+
+.. option:: ProtectedMethodCase
+
+    When defined, the check will ensure protect method names conform to the
+    selected casing.
+
+.. option:: ProtectedMethodPrefix
+
+    When defined, the check will ensure protect method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ProtectedMethodSuffix
+
+    When defined, the check will ensure protect method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ProtectedMethodCase of ``lower_case``
+   - ProtectedMethodPrefix of ``pre_``
+   - ProtectedMethodSuffix of ``_post``
+
+Identifies and/or transforms protect method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    protected:
+      int Member_Method();
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    protected:
+      int pre_member_method_post();
+    }
+
+.. option:: PublicMemberCase
+
+    When defined, the check will ensure public member names conform to the
+    selected casing.
+
+.. option:: PublicMemberPrefix
+
+    When defined, the check will ensure public member names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: PublicMemberSuffix
+
+    When defined, the check will ensure public member names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - PublicMemberCase of ``lower_case``
+   - PublicMemberPrefix of ``pre_``
+   - PublicMemberSuffix of ``_post``
+
+Identifies and/or transforms public member names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      int Member_Variable;
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      int pre_member_variable_post;
+    }
+
+.. option:: PublicMethodCase
+
+    When defined, the check will ensure public method names conform to the
+    selected casing.
+
+.. option:: PublicMethodPrefix
+
+    When defined, the check will ensure public method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: PublicMethodSuffix
+
+    When defined, the check will ensure public method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - PublicMethodCase of ``lower_case``
+   - PublicMethodPrefix of ``pre_``
+   - PublicMethodSuffix of ``_post``
+
+Identifies and/or transforms public method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      int Member_Method();
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      int pre_member_method_post();
+    }
+
+.. option:: StaticConstantCase
+
+    When defined, the check will ensure static constant names conform to the
+    selected casing.
+
+.. option:: StaticConstantPrefix
+
+    When defined, the check will ensure static constant names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: StaticConstantSuffix
+
+    When defined, the check will ensure static constant names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - StaticConstantCase of ``lower_case``
+   - StaticConstantPrefix of ``pre_``
+   - StaticConstantSuffix of ``_post``
+
+Identifies and/or transforms static constant names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    static unsigned const MyConstStatic_array[] = {1, 2, 3};
+
+After:
+
+.. code-block:: c++
+
+    static unsigned const pre_myconststatic_array_post[] = {1, 2, 3};
+
+.. option:: StaticVariableCase
+
+    When defined, the check will ensure static variable names conform to the
+    selected casing.
+
+.. option:: StaticVariablePrefix
+
+    When defined, the check will ensure static variable names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: StaticVariableSuffix
+
+    When defined, the check will ensure static variable names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - StaticVariableCase of ``lower_case``
+   - StaticVariablePrefix of ``pre_``
+   - StaticVariableSuffix of ``_post``
+
+Identifies and/or transforms static variable names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    static unsigned MyStatic_array[] = {1, 2, 3};
+
+After:
+
+.. code-block:: c++
+
+    static unsigned pre_mystatic_array_post[] = {1, 2, 3};
+
+.. option:: StructCase
+
+    When defined, the check will ensure struct names conform to the
+    selected casing.
+
+.. option:: StructPrefix
+
+    When defined, the check will ensure struct names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: StructSuffix
+
+    When defined, the check will ensure struct names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - StructCase of ``lower_case``
+   - StructPrefix of ``pre_``
+   - StructSuffix of ``_post``
+
+Identifies and/or transforms struct names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    struct FOO {
+      FOO();
+      ~FOO();
+    };
+
+After:
+
+.. code-block:: c++
+
+    struct pre_foo_post {
+      pre_foo_post();
+      ~pre_foo_post();
+    };
+
+.. option:: TemplateParameterCase
+
+    When defined, the check will ensure template parameter names conform to the
+    selected casing.
+
+.. option:: TemplateParameterPrefix
+
+    When defined, the check will ensure template parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: TemplateParameterSuffix
+
+    When defined, the check will ensure template parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - TemplateParameterCase of ``lower_case``
+   - TemplateParameterPrefix of ``pre_``
+   - TemplateParameterSuffix of ``_post``
+
+Identifies and/or transforms template parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    template <typename T> class Foo {};
+
+After:
+
+.. code-block:: c++
+
+    template <typename pre_t_post> class Foo {};
+
+.. option:: TemplateTemplateParameterCase
+
+    When defined, the check will ensure template template parameter names conform to the
+    selected casing.
+
+.. option:: TemplateTemplateParameterPrefix
+
+    When defined, the check will ensure template template parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: TemplateTemplateParameterSuffix
+
+    When defined, the check will ensure template template parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - TemplateTemplateParameterCase of ``lower_case``
+   - TemplateTemplateParameterPrefix of ``pre_``
+   - TemplateTemplateParameterSuffix of ``_post``
+
+Identifies and/or transforms template template parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    template <template <typename> class TPL_parameter, int COUNT_params,
+              typename... TYPE_parameters>
+
+After:
+
+.. code-block:: c++
+
+    template <template <typename> class pre_tpl_parameter_post, int COUNT_params,
+              typename... TYPE_parameters>
+
+.. option:: TypeAliasCase
+
+    When defined, the check will ensure type alias names conform to the
+    selected casing.
+
+.. option:: TypeAliasPrefix
+
+    When defined, the check will ensure type alias names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: TypeAliasSuffix
+
+    When defined, the check will ensure type alias names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - TypeAliasCase of ``lower_case``
+   - TypeAliasPrefix of ``pre_``
+   - TypeAliasSuffix of ``_post``
+
+Identifies and/or transforms type alias names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    using MY_STRUCT_TYPE = my_structure;
+
+After:
+
+.. code-block:: c++
+
+    using pre_my_struct_type_post = my_structure;
+
+.. option:: TypedefCase
+
+    When defined, the check will ensure typedef names conform to the
+    selected casing.
+
+.. option:: TypedefPrefix
+
+    When defined, the check will ensure typedef names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: TypedefSuffix
+
+    When defined, the check will ensure typedef names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - TypedefCase of ``lower_case``
+   - TypedefPrefix of ``pre_``
+   - TypedefSuffix of ``_post``
+
+Identifies and/or transforms typedef names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    typedef int MYINT;
+
+After:
+
+.. code-block:: c++
+
+    typedef int pre_myint_post;
+
+.. option:: TypeTemplateParameterCase
+
+    When defined, the check will ensure type template parameter names conform to the
+    selected casing.
+
+.. option:: TypeTemplateParameterPrefix
+
+    When defined, the check will ensure type template parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: TypeTemplateParameterSuffix
+
+    When defined, the check will ensure type template parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - TypeTemplateParameterCase of ``lower_case``
+   - TypeTemplateParameterPrefix of ``pre_``
+   - TypeTemplateParameterSuffix of ``_post``
+
+Identifies and/or transforms type template parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    template <template <typename> class TPL_parameter, int COUNT_params,
+              typename... TYPE_parameters>
+
+After:
+
+.. code-block:: c++
+
+    template <template <typename> class TPL_parameter, int COUNT_params,
+              typename... pre_type_parameters_post>
+
+.. option:: UnionCase
+
+    When defined, the check will ensure union names conform to the
+    selected casing.
+
+.. option:: UnionPrefix
+
+    When defined, the check will ensure union names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: UnionSuffix
+
+    When defined, the check will ensure union names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - UnionCase of ``lower_case``
+   - UnionPrefix of ``pre_``
+   - UnionSuffix of ``_post``
+
+Identifies and/or transforms union names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    union FOO {
+      int a;
+      char b;
+    };
+
+After:
+
+.. code-block:: c++
+
+    union pre_foo_post {
+      int a;
+      char b;
+    };
+
+.. option:: ValueTemplateParameterCase
+
+    When defined, the check will ensure value template parameter names conform to the
+    selected casing.
+
+.. option:: ValueTemplateParameterPrefix
+
+    When defined, the check will ensure value template parameter names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: ValueTemplateParameterSuffix
+
+    When defined, the check will ensure value template parameter names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - ValueTemplateParameterCase of ``lower_case``
+   - ValueTemplateParameterPrefix of ``pre_``
+   - ValueTemplateParameterSuffix of ``_post``
+
+Identifies and/or transforms value template parameter names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    template <template <typename> class TPL_parameter, int COUNT_params,
+              typename... TYPE_parameters>
+
+After:
+
+.. code-block:: c++
+
+    template <template <typename> class TPL_parameter, int pre_count_params_post,
+              typename... TYPE_parameters>
+
+.. option:: VariableCase
+
+    When defined, the check will ensure variable names conform to the
+    selected casing.
+
+.. option:: VariablePrefix
+
+    When defined, the check will ensure variable names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: VariableSuffix
+
+    When defined, the check will ensure variable names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - VariableCase of ``lower_case``
+   - VariablePrefix of ``pre_``
+   - VariableSuffix of ``_post``
+
+Identifies and/or transforms variable names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    unsigned MyVariable;
+
+After:
+
+.. code-block:: c++
+
+    unsigned pre_myvariable_post;
+
+.. option:: VirtualMethodCase
+
+    When defined, the check will ensure virtual method names conform to the
+    selected casing.
+
+.. option:: VirtualMethodPrefix
+
+    When defined, the check will ensure virtual method names will add the
+    prefixed with the given value (regardless of casing).
+
+.. option:: VirtualMethodSuffix
+
+    When defined, the check will ensure virtual method names will add the
+    suffix with the given value (regardless of casing).
+
+For example using values of:
+
+   - VirtualMethodCase of ``lower_case``
+   - VirtualMethodPrefix of ``pre_``
+   - VirtualMethodSuffix of ``_post``
+
+Identifies and/or transforms virtual method names as follows:
+
+Before:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      virtual int MemberFunction();
+    }
+
+After:
+
+.. code-block:: c++
+
+    class Foo {
+    public:
+      virtual int pre_member_function_post();
+    }
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/checks/readability-redundant-preprocessor.rst b/docs/clang-tidy/checks/readability-redundant-preprocessor.rst
new file mode 100644
index 0000000..f013a34
--- /dev/null
+++ b/docs/clang-tidy/checks/readability-redundant-preprocessor.rst
@@ -0,0 +1,61 @@
+.. title:: clang-tidy - readability-redundant-preprocessor
+
+readability-redundant-preprocessor
+==================================
+
+Finds potentially redundant preprocessor directives. At the moment the
+following cases are detected:
+
+* `#ifdef` .. `#endif` pairs which are nested inside an outer pair with the
+  same condition. For example:
+
+.. code-block:: c++
+
+  #ifdef FOO
+  #ifdef FOO // inner ifdef is considered redundant
+  void f();
+  #endif
+  #endif
+
+* Same for `#ifndef` .. `#endif` pairs. For example:
+
+.. code-block:: c++
+
+  #ifndef FOO
+  #ifndef FOO // inner ifndef is considered redundant
+  void f();
+  #endif
+  #endif
+
+* `#ifndef` inside an `#ifdef` with the same condition:
+
+.. code-block:: c++
+
+  #ifdef FOO
+  #ifndef FOO // inner ifndef is considered redundant
+  void f();
+  #endif
+  #endif
+
+* `#ifdef` inside an `#ifndef` with the same condition:
+
+.. code-block:: c++
+
+  #ifndef FOO
+  #ifdef FOO // inner ifdef is considered redundant
+  void f();
+  #endif
+  #endif
+
+* `#if` .. `#endif` pairs which are nested inside an outer pair with the same
+  condition. For example:
+
+.. code-block:: c++
+
+  #define FOO 4
+  #if FOO == 4
+  #if FOO == 4 // inner if is considered redundant
+  void f();
+  #endif
+  #endif
+
diff --git a/docs/clang-tidy/checks/readability-uppercase-literal-suffix.rst b/docs/clang-tidy/checks/readability-uppercase-literal-suffix.rst
index e3da086..82c083d 100644
--- a/docs/clang-tidy/checks/readability-uppercase-literal-suffix.rst
+++ b/docs/clang-tidy/checks/readability-uppercase-literal-suffix.rst
@@ -49,3 +49,8 @@
 * ``uL`` will be kept as is.
 * ``ull`` will be kept as is, since it is not in the list
 * and so on.
+
+.. option:: IgnoreMacros
+
+   If this option is set to non-zero (default is `1`), the check will not warn
+   about literal suffixes inside macros.
diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst
index 20b18b4..1cbd8dc 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
@@ -223,7 +225,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 +260,50 @@
 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>`_ can be
+silenced by re-initializing the variable after it has been moved out,
+`bugprone-string-integer-assignment
+<checks/bugprone-string-integer-assignment>`_ can be suppressed by explicitly
+casting the integer to ``char``, `readability-implicit-bool-conversion
+<checks/readability-implicit-bool-conversion>`_ 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 +327,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..0843bca 100644
--- a/docs/clangd.rst
+++ b/docs/clangd.rst
@@ -31,7 +31,7 @@
 ==================
 
 Packages are available for debian-based distributions, see the `LLVM packages
-page <http://apt.llvm.org/>`_. :program:`Clangd` is included in the
+page <https://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.
@@ -143,18 +143,37 @@
 :program:`Emacs` provides `lsp-mode <github.com/emacs-lsp/lsp-mode>`_ and
 `Eglot <https://github.com/joaotavora/eglot>`_ plugins for LSP integration.
 
+Project-wide Index
+==================
+
+By default :program:`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 :program:`Clangd`.
+
+There are two ways you can generate a project-wide index for clangd:
+
+- Passing experimental `-background-index` commandline argument, which will
+  incrementally build an index of projects that you work on and make use of that
+  in clangd automatically.
+- Generate an index file using `clangd-indexer
+  <https://github.com/llvm-mirror/clang-tools-extra/blob/master/clangd/indexer/IndexerMain.cpp>`_
+  Afterwards 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 standard clang-tools package. You will likely have to
+  build from source to use this option*
+
 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
+<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
-<http://lists.llvm.org/mailman/listinfo/cfe-dev>`_.
+<https://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
+<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 :program:`Clangd` can eventually implement them in a
diff --git a/docs/conf.py b/docs/conf.py
index 1b07e8e..a79558f 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.
diff --git a/docs/include-fixer.rst b/docs/include-fixer.rst
index fcd2998..9898840 100644
--- a/docs/include-fixer.rst
+++ b/docs/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
 ---------------------------------------------------
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..9cfbef5 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`.
 
@@ -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:
@@ -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/include-fixer/FuzzySymbolIndex.cpp b/include-fixer/FuzzySymbolIndex.cpp
index d91f455..099d738 100644
--- a/include-fixer/FuzzySymbolIndex.cpp
+++ b/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/include-fixer/FuzzySymbolIndex.h
index 245191e..2ea1660 100644
--- a/include-fixer/FuzzySymbolIndex.h
+++ b/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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/InMemorySymbolIndex.cpp b/include-fixer/InMemorySymbolIndex.cpp
index 14753bd..e785893 100644
--- a/include-fixer/InMemorySymbolIndex.cpp
+++ b/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/include-fixer/InMemorySymbolIndex.h
index 0e1310e..bea8be9 100644
--- a/include-fixer/InMemorySymbolIndex.h
+++ b/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/include-fixer/IncludeFixer.cpp
index c6dfd7f..540b263 100644
--- a/include-fixer/IncludeFixer.cpp
+++ b/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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/IncludeFixer.h b/include-fixer/IncludeFixer.h
index 13092a3..5528e89 100644
--- a/include-fixer/IncludeFixer.h
+++ b/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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/IncludeFixerContext.cpp b/include-fixer/IncludeFixerContext.cpp
index 8106e20..a9fef45 100644
--- a/include-fixer/IncludeFixerContext.cpp
+++ b/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/include-fixer/IncludeFixerContext.h
index 3c44574..bbb87e2 100644
--- a/include-fixer/IncludeFixerContext.h
+++ b/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/include-fixer/SymbolIndex.h
index f3e6ecd..ca04d50 100644
--- a/include-fixer/SymbolIndex.h
+++ b/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/include-fixer/SymbolIndexManager.cpp
index e4312bf..603b9d4 100644
--- a/include-fixer/SymbolIndexManager.cpp
+++ b/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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/include-fixer/SymbolIndexManager.h b/include-fixer/SymbolIndexManager.h
index 12963dd..ca2d739 100644
--- a/include-fixer/SymbolIndexManager.h
+++ b/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/include-fixer/YamlSymbolIndex.cpp
index f3f2d5a..de72e9a 100644
--- a/include-fixer/YamlSymbolIndex.cpp
+++ b/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/include-fixer/YamlSymbolIndex.h
index d5d699a..3c4f514 100644
--- a/include-fixer/YamlSymbolIndex.h
+++ b/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/FindAllMacros.cpp b/include-fixer/find-all-symbols/FindAllMacros.cpp
index 3dc2b96..ed1bc2f 100644
--- a/include-fixer/find-all-symbols/FindAllMacros.cpp
+++ b/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/include-fixer/find-all-symbols/FindAllMacros.h
index 10b4a69..5aaf388 100644
--- a/include-fixer/find-all-symbols/FindAllMacros.h
+++ b/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/include-fixer/find-all-symbols/FindAllSymbols.cpp
index bd5032d..bb6a3fa 100644
--- a/include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/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/include-fixer/find-all-symbols/FindAllSymbols.h
index fca849f..d78da66 100644
--- a/include-fixer/find-all-symbols/FindAllSymbols.h
+++ b/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/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
index bc00547..9f1d31d 100644
--- a/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
+++ b/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/include-fixer/find-all-symbols/FindAllSymbolsAction.h
index 7be9fe2..ccffa4b 100644
--- a/include-fixer/find-all-symbols/FindAllSymbolsAction.h
+++ b/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/include-fixer/find-all-symbols/HeaderMapCollector.cpp
index 379df81..6ec49ca 100644
--- a/include-fixer/find-all-symbols/HeaderMapCollector.cpp
+++ b/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/include-fixer/find-all-symbols/HeaderMapCollector.h
index 65edd75..2135827 100644
--- a/include-fixer/find-all-symbols/HeaderMapCollector.h
+++ b/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/include-fixer/find-all-symbols/PathConfig.cpp
index de799b9..4f1ebc7 100644
--- a/include-fixer/find-all-symbols/PathConfig.cpp
+++ b/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/include-fixer/find-all-symbols/PathConfig.h
index 50de548..9c430f2 100644
--- a/include-fixer/find-all-symbols/PathConfig.h
+++ b/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/include-fixer/find-all-symbols/PragmaCommentHandler.cpp
index 0242d38..4948975 100644
--- a/include-fixer/find-all-symbols/PragmaCommentHandler.cpp
+++ b/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/include-fixer/find-all-symbols/PragmaCommentHandler.h
index 9eb4972..752c82f 100644
--- a/include-fixer/find-all-symbols/PragmaCommentHandler.h
+++ b/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/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
index 4a49479..0d0bbd9 100644
--- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp
+++ b/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/include-fixer/find-all-symbols/STLPostfixHeaderMap.h
index 162580d..49bc5f3 100644
--- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.h
+++ b/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/include-fixer/find-all-symbols/SymbolInfo.cpp
index 00bfbe5..e5b4dba 100644
--- a/include-fixer/find-all-symbols/SymbolInfo.cpp
+++ b/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/include-fixer/find-all-symbols/SymbolInfo.h
index 92d360d..6def1c7 100644
--- a/include-fixer/find-all-symbols/SymbolInfo.h
+++ b/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/include-fixer/find-all-symbols/SymbolReporter.h
index 2398234..25e8621 100644
--- a/include-fixer/find-all-symbols/SymbolReporter.h
+++ b/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/FindAllSymbolsMain.cpp b/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
index e09a5aa..dbbe073 100644
--- a/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
+++ b/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/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/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/IncludeFixerPlugin.cpp b/include-fixer/plugin/IncludeFixerPlugin.cpp
index 0d6bdb7..bc9c497 100644
--- a/include-fixer/plugin/IncludeFixerPlugin.cpp
+++ b/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/ClangIncludeFixer.cpp b/include-fixer/tool/ClangIncludeFixer.cpp
index d9d97d2..64bfdb7 100644
--- a/include-fixer/tool/ClangIncludeFixer.cpp
+++ b/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
 //
 //===----------------------------------------------------------------------===//
 
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..4ed40b3 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
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/pp-trace/PPCallbacksTracker.h b/pp-trace/PPCallbacksTracker.h
index b46210e..ec52fee 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
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/pp-trace/PPTrace.cpp b/pp-trace/PPTrace.cpp
index 08e0f51..6524828 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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 451c181..adeb036 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -16,7 +16,8 @@
 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
 
 llvm_canonicalize_cmake_booleans(
-  CLANG_ENABLE_STATIC_ANALYZER)
+  CLANG_ENABLE_STATIC_ANALYZER
+  CLANGD_BUILD_XPC_SUPPORT)
 
 configure_lit_site_cfg(
   ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
@@ -61,7 +62,11 @@
   clang-headers
 
   clang-tidy
-  )
+)
+
+if(CLANGD_BUILD_XPC_SUPPORT)
+  list(APPEND CLANG_TOOLS_TEST_DEPS clangd-xpc-test-client)
+endif()
 
 set(CLANGD_TEST_DEPS
   clangd
diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h
index 9d136a5..8da3c2c 100644
--- a/test/clang-tidy/Inputs/absl/time/time.h
+++ b/test/clang-tidy/Inputs/absl/time/time.h
@@ -14,6 +14,8 @@
   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);
@@ -55,6 +57,19 @@
 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);
+
 // Relational Operators
 constexpr bool operator<(Duration lhs, Duration rhs);
 constexpr bool operator>(Duration lhs, Duration rhs);
diff --git a/test/clang-tidy/Inputs/mock-libcxx/bin/clang b/test/clang-tidy/Inputs/mock-libcxx/bin/clang
new file mode 100644
index 0000000..ed34c1f
--- /dev/null
+++ b/test/clang-tidy/Inputs/mock-libcxx/bin/clang
@@ -0,0 +1 @@
+This file is a placeholder to keep its parent directory in git.
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-comparison.cpp b/test/clang-tidy/abseil-duration-comparison.cpp
index 7a70db6..9fa422b 100644
--- a/test/clang-tidy/abseil-duration-comparison.cpp
+++ b/test/clang-tidy/abseil-duration-comparison.cpp
@@ -127,6 +127,33 @@
   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison]
   // CHECK-FIXES: absl::Milliseconds((y + 5) * 10) > d1;
 
+  // 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::ToDoubleSeconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the duration domain [abseil-duration-comparison]
+  // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+#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::ToDoubleSeconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the duration domain [abseil-duration-comparison]
+  // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1);
+#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, d1, Double);
+#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, d1, Double);
+#undef VALUE_IF
+#undef VALUE_IF_2
+
   // These should not match
   b = 6 < 4;
 
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-factory-scale.cpp b/test/clang-tidy/abseil-duration-factory-scale.cpp
index dc94773..04c3613 100644
--- a/test/clang-tidy/abseil-duration-factory-scale.cpp
+++ b/test/clang-tidy/abseil-duration-factory-scale.cpp
@@ -2,6 +2,9 @@
 
 #include "absl/time/time.h"
 
+namespace std { typedef long long int64_t; }
+using int64_t = std::int64_t;
+
 void ScaleTest() {
   absl::Duration d;
 
@@ -30,6 +33,15 @@
   d = absl::Seconds(0x0.000001p-126f);
   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
   // CHECK-FIXES: absl::ZeroDuration();
+  d = absl::Seconds(int{0});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+  // CHECK-FIXES: absl::ZeroDuration();
+  d = absl::Seconds(int64_t{0});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+  // CHECK-FIXES: absl::ZeroDuration();
+  d = absl::Seconds(float{0});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale]
+  // CHECK-FIXES: absl::ZeroDuration();
 
   // Fold seconds into minutes
   d = absl::Seconds(30 * 60);
@@ -83,6 +95,8 @@
 
   // None of these should trigger the check
   d = absl::Seconds(60);
+  d = absl::Seconds(int{60});
+  d = absl::Seconds(float{60});
   d = absl::Seconds(60 + 30);
   d = absl::Seconds(60 - 30);
   d = absl::Seconds(50 * 30);
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..9414182
--- /dev/null
+++ b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp
@@ -0,0 +1,69 @@
+// 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: d1
+  d2 = absl::Minutes(absl::ToDoubleMinutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Seconds(absl::ToDoubleSeconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: 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: d1
+  d2 = absl::Minutes(absl::ToInt64Minutes(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Seconds(absl::ToInt64Seconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Microseconds(absl::ToInt64Microseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: d1
+  d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1));
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion]
+  // CHECK-FIXES: 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);
+}
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/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-string-constructor.cpp b/test/clang-tidy/bugprone-string-constructor.cpp
index 51d9130..3ab4f42 100644
--- a/test/clang-tidy/bugprone-string-constructor.cpp
+++ b/test/clang-tidy/bugprone-string-constructor.cpp
@@ -9,6 +9,7 @@
 struct basic_string {
   basic_string();
   basic_string(const C*, unsigned int size);
+  basic_string(const C *, const A &allocator = A());
   basic_string(unsigned int size, C c);
 };
 typedef basic_string<char> string;
@@ -45,6 +46,15 @@
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger then string literal size
   std::string q5(kText3,  0x1000000);
   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
+  std::string q6(nullptr);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour
+  std::string q7 = 0;
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
+}
+
+std::string StringFromZero() {
+  return 0;
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
 }
 
 void Valid() {
@@ -53,4 +63,5 @@
   std::wstring wstr(4, L'x');
   std::string s1("test", 4);
   std::string s2("test", 3);
+  std::string s3("test");
 }
diff --git a/test/clang-tidy/bugprone-use-after-move.cpp b/test/clang-tidy/bugprone-use-after-move.cpp
index 59dcb90..dd37aec 100644
--- a/test/clang-tidy/bugprone-use-after-move.cpp
+++ b/test/clang-tidy/bugprone-use-after-move.cpp
@@ -244,6 +244,19 @@
     std::move(ptr);
     ptr.get();
   }
+  // Make sure we treat references to smart pointers correctly.
+  {
+    std::unique_ptr<A> ptr;
+    std::unique_ptr<A>& ref_to_ptr = ptr;
+    std::move(ref_to_ptr);
+    ref_to_ptr.get();
+  }
+  {
+    std::unique_ptr<A> ptr;
+    std::unique_ptr<A>&& rvalue_ref_to_ptr = std::move(ptr);
+    std::move(rvalue_ref_to_ptr);
+    rvalue_ref_to_ptr.get();
+  }
   // We don't give any special treatment to types that are called "unique_ptr"
   // or "shared_ptr" but are not in the "::std" namespace.
   {
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/fuchsia-overloaded-operator.cpp b/test/clang-tidy/fuchsia-overloaded-operator.cpp
index be65a32..7f7a36e 100644
--- a/test/clang-tidy/fuchsia-overloaded-operator.cpp
+++ b/test/clang-tidy/fuchsia-overloaded-operator.cpp
@@ -19,3 +19,5 @@
 
 void operator delete(void*, void*) throw();
 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: overloading 'operator delete' is disallowed
+
+auto x = []{};
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-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-nodiscard-clang-unused.cpp b/test/clang-tidy/modernize-use-nodiscard-clang-unused.cpp
new file mode 100644
index 0000000..0951e61
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard-clang-unused.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '[[clang::warn_unused_result]]'}]}" \
+// RUN: -- -std=c++11 
+
+class Foo
+{
+public:
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f1() const;
+
+    bool f2(int) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f2(int) const;
+
+    bool f3(const int &) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f3(const int &) const;
+
+    bool f4(void) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[clang::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[clang::warn_unused_result\]\]}} bool f4(void) const;
+
+};
+
diff --git a/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp b/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp
new file mode 100644
index 0000000..cbf0cea
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard-cxx11.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '__attribute__((warn_unused_result))'}]}" \
+// RUN: -- -std=c++11
+
+class Foo
+{
+public:
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+    // CHECK-FIXES: __attribute__((warn_unused_result)) bool f1() const;
+
+    bool f2(int) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+    // CHECK-FIXES: __attribute__((warn_unused_result)) bool f2(int) const;
+
+    bool f3(const int &) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+    // CHECK-FIXES: __attribute__((warn_unused_result)) bool f3(const int &) const;
+
+    bool f4(void) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked __attribute__((warn_unused_result)) [modernize-use-nodiscard]
+    // CHECK-FIXES: __attribute__((warn_unused_result)) bool f4(void) const;
+};
+
diff --git a/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp b/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp
new file mode 100644
index 0000000..54b808e
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard-gcc-unused.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: '[[gcc::warn_unused_result]]'}]}" \
+// RUN: -- -std=c++11 
+
+class Foo
+{
+public:
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f1() const;
+
+    bool f2(int) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f2(int) const;
+
+    bool f3(const int &) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f3(const int &) const;
+
+    bool f4(void) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[gcc::warn_unused_result\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[gcc::warn_unused_result\]\]}} bool f4(void) const;
+
+};
+
diff --git a/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp b/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp
new file mode 100644
index 0000000..0564a13
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard-no-macro-inscope-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: 'CUSTOM_NO_DISCARD'}]}" -- -std=c++11 
+
+// As if the macro was not defined.
+// #define CUSTOM_NO_DISCARD __attribute_((warn_unused_result))
+
+class Foo
+{
+public:
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked CUSTOM_NO_DISCARD [modernize-use-nodiscard]
+};
+
diff --git a/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp b/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp
new file mode 100644
index 0000000..7898b6e
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard-no-macro.cpp
@@ -0,0 +1,22 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- -- -std=c++17 
+
+class Foo
+{
+public:
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f1() const;
+
+    bool f2(int) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f2(int) const;
+
+    bool f3(const int &) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f3(const int &) const;
+
+    bool f4(void) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked {{\[\[nodiscard\]\]}} [modernize-use-nodiscard]
+    // CHECK-FIXES: {{\[\[nodiscard\]\]}} bool f4(void) const;
+
+};
diff --git a/test/clang-tidy/modernize-use-nodiscard.cpp b/test/clang-tidy/modernize-use-nodiscard.cpp
new file mode 100644
index 0000000..a571f09
--- /dev/null
+++ b/test/clang-tidy/modernize-use-nodiscard.cpp
@@ -0,0 +1,262 @@
+// RUN: %check_clang_tidy %s modernize-use-nodiscard %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-nodiscard.ReplacementString, value: 'NO_DISCARD'}]}" \
+// RUN: -- -std=c++17
+
+namespace std {
+template <class>
+class function;
+class string {};
+}
+
+namespace boost {
+template <class>
+class function;
+}
+
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#define NO_DISCARD [[nodiscard]]
+#define NO_RETURN [[noreturn]]
+
+#define BOOLEAN_FUNC bool f23() const
+
+typedef unsigned my_unsigned;
+typedef unsigned &my_unsigned_reference;
+typedef const unsigned &my_unsigned_const_reference;
+
+class Foo {
+public:
+    using size_type = unsigned;
+
+    bool f1() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f1' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f1() const;
+
+    bool f2(int) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f2' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f2(int) const;
+
+    bool f3(const int &) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f3' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f3(const int &) const;
+
+    bool f4(void) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f4' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f4(void) const;
+    
+    // negative tests
+
+    void f5() const;
+    
+    bool f6();
+    
+    bool f7(int &);
+    
+    bool f8(int &) const;
+    
+    bool f9(int *) const;
+    
+    bool f10(const int &, int &) const;
+    
+    NO_DISCARD bool f12() const;
+    
+    MUST_USE_RESULT bool f13() const;
+    
+    [[nodiscard]] bool f11() const;
+    
+    [[clang::warn_unused_result]] bool f11a() const;
+    
+    [[gnu::warn_unused_result]] bool f11b() const;
+
+    bool _f20() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function '_f20' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool _f20() const;
+    
+    NO_RETURN bool f21() const;
+    
+    ~Foo();
+    
+    bool operator+=(int) const;
+    
+    // extra keywords (virtual,inline,const) on return type
+    
+    virtual bool f14() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f14' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD virtual bool f14() const;
+    
+    const bool f15() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f15' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD const bool f15() const;
+    
+    inline const bool f16() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f16' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD inline const bool f16() const;
+
+    inline const std::string &f45() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f45' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD inline const std::string &f45() const;
+
+    inline virtual const bool f17() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f17' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD inline virtual const bool f17() const;
+
+    // inline with body
+    bool f18() const 
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f18' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f18() const 
+    {
+     return true;
+    }
+
+    bool f19() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f19' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f19() const;
+
+    BOOLEAN_FUNC;
+    
+    bool f24(size_type) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f24' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f24(size_type) const;
+    
+    bool f28(my_unsigned) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f28' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f28(my_unsigned) const;
+
+    bool f29(my_unsigned_reference) const;
+
+    bool f30(my_unsigned_const_reference) const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f30' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool f30(my_unsigned_const_reference) const;
+
+    template <class F>
+    F f37(F a, F b) const;
+
+    template <class F>
+    bool f38(F a) const;
+
+    bool f39(const std::function<bool()> &predicate) const;
+
+    bool f39a(std::function<bool()> predicate) const;
+
+    bool f39b(const std::function<bool()> predicate) const;
+
+    bool f45(const boost::function<bool()> &predicate) const;
+
+    bool f45a(boost::function<bool()> predicate) const;
+
+    bool f45b(const boost::function<bool()> predicate) const;
+
+    // Do not add ``[[nodiscard]]`` to parameter packs.
+    template <class... Args>
+    bool ParameterPack(Args... args) const;
+
+    template <typename... Targs>
+    bool ParameterPack2(Targs... Fargs) const;
+
+    // Do not add ``[[nodiscard]]`` to variadic functions.
+    bool VariadicFunctionTest(const int &, ...) const;
+
+    // Do not add ``[[nodiscard]]`` to non constant static functions.
+    static bool not_empty();
+
+    // Do not add ``[[nodiscard]]`` to conversion functions.
+    // explicit operator bool() const { return true; }
+};
+
+// Do not add ``[[nodiscard]]`` to Lambda.
+const auto nonConstReferenceType = [] {
+  return true;
+};
+
+auto lambda1 = [](int a, int b) { return a < b; };
+auto lambda1a = [](int a) { return a; };
+auto lambda1b = []()  { return true;};
+
+auto get_functor = [](bool check) {
+    return  [&](const std::string& sr)->std::string {
+        if(check){
+            return std::string();
+        }
+        return std::string();
+    };
+};
+
+// Do not add ``[[nodiscard]]`` to function definition.
+bool Foo::f19() const {
+  return true;
+}
+
+template <class T>
+class Bar {
+public:
+    using value_type = T;
+    using reference = value_type &;
+    using const_reference = const value_type &;
+
+    // Do not add ``[[nodiscard]]`` to non explicit conversion functions.
+    operator bool() const { return true; }
+
+    bool empty() const;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'empty' should be marked NO_DISCARD [modernize-use-nodiscard]
+    // CHECK-FIXES: NO_DISCARD bool empty() const;
+
+    // we cannot assume that the template parameter isn't a pointer
+    bool f25(value_type) const;
+
+    bool f27(reference) const;
+
+    typename T::value_type f35() const;
+
+    T f34() const;
+
+    bool f31(T) const;
+
+    bool f33(T &) const;
+
+    bool f26(const_reference) const;
+
+    bool f32(const T &) const;
+};
+
+template <typename _Tp, int cn>
+class Vec {
+public:
+    Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
+
+    Vec cross(const Vec &v) const;
+
+    template <typename T2>
+    operator Vec<T2, cn>() const;
+};
+    
+template <class T>
+class Bar2 {
+public:
+  typedef T value_type;
+  typedef value_type &reference;
+  typedef const value_type &const_reference;
+
+  // we cannot assume that the template parameter isn't a pointer
+  bool f40(value_type) const;
+
+  bool f41(reference) const;
+
+  value_type f42() const;
+
+  typename T::value_type f43() const;
+
+  bool f44(const_reference) const;
+};
+
+template <class T>
+bool Bar<T>::empty() const {
+  return true;
+}
+
+// don't mark typical ``[[nodiscard]]`` candidates if the class
+// has mutable member variables
+class MutableExample {
+  mutable bool m_isempty;
+
+public:
+  bool empty() const;
+};
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-redundant-preprocessor-ifdef.cpp b/test/clang-tidy/readability-redundant-preprocessor-ifdef.cpp
new file mode 100644
index 0000000..72b608b
--- /dev/null
+++ b/test/clang-tidy/readability-redundant-preprocessor-ifdef.cpp
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy %s readability-redundant-preprocessor %t -- -- -DFOO
+
+// Positive testing.
+#ifdef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifdef; consider removing it [readability-redundant-preprocessor]
+#ifdef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifdef was here
+void f();
+#endif
+#endif
+
+// Positive testing of inverted condition.
+#ifdef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
+#ifndef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifdef was here
+void f2();
+#endif
+#endif
+
+// Negative testing.
+#ifdef BAR
+void g();
+#endif
+
+#ifdef FOO
+#ifdef BAR
+void h();
+#endif
+#endif
+
+#ifdef FOO
+#ifndef BAR
+void i();
+#endif
+#endif
diff --git a/test/clang-tidy/readability-redundant-preprocessor.cpp b/test/clang-tidy/readability-redundant-preprocessor.cpp
new file mode 100644
index 0000000..6cffd8f
--- /dev/null
+++ b/test/clang-tidy/readability-redundant-preprocessor.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s readability-redundant-preprocessor %t -- -- -I %S
+
+// Positive testing.
+#ifndef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
+#ifndef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifndef was here
+void f();
+#endif
+#endif
+
+// Positive testing of inverted condition.
+#ifndef FOO
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #ifdef; consider removing it [readability-redundant-preprocessor]
+#ifdef FOO
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #ifndef was here
+void f2();
+#endif
+#endif
+
+// Negative testing.
+#include "readability-redundant-preprocessor.h"
+
+#ifndef BAR
+void g();
+#endif
+
+#ifndef FOO
+#ifndef BAR
+void h();
+#endif
+#endif
+
+#ifndef FOO
+#ifdef BAR
+void i();
+#endif
+#endif
+
+// Positive #if testing.
+#define FOO 4
+
+#if FOO == 4
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == 4
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+#if FOO == 3 + 1
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == 3 + 1
+// CHECK-NOTES: [[@LINE-3]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+#if FOO == \
+    4
+// CHECK-NOTES: [[@LINE+1]]:2: warning: nested redundant #if; consider removing it [readability-redundant-preprocessor]
+#if FOO == \
+    4
+// CHECK-NOTES: [[@LINE-5]]:2: note: previous #if was here
+void j();
+#endif
+#endif
+
+// Negative #if testing.
+#define BAR 4
+
+#if FOO == 4
+#if BAR == 4
+void k();
+#endif
+#endif
+
+#if FOO == \
+    4
+#if BAR == \
+    5
+void k();
+#endif
+#endif
diff --git a/test/clang-tidy/readability-redundant-preprocessor.h b/test/clang-tidy/readability-redundant-preprocessor.h
new file mode 100644
index 0000000..dfe5f97
--- /dev/null
+++ b/test/clang-tidy/readability-redundant-preprocessor.h
@@ -0,0 +1,5 @@
+#ifndef FOO
+#ifndef FOO // this would warn, but not in a header
+void f();
+#endif
+#endif
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/readability-uppercase-literal-suffix-integer-macro.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp
index 9668a9e..40a9c26 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-integer-macro.cpp
@@ -1,4 +1,6 @@
-// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -I %S
+// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- \
+// RUN:   -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.IgnoreMacros, value: 0}]}" \
+// RUN:   -- -I %S
 
 void macros() {
 #define INMACRO(X) 1.f
diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp
index c4fcd18..a6f38a8 100644
--- a/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp
+++ b/test/clang-tidy/readability-uppercase-literal-suffix-integer.cpp
@@ -235,6 +235,10 @@
   // CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(1U);
   static_assert(is_same<decltype(m0), const unsigned int>::value, "");
   static_assert(m0 == 1, "");
+
+  // This location is inside a macro, no warning on that by default.
+#define MACRO 1u
+  int foo = MACRO;
 }
 
 // Check that user-defined literals do not cause any diags.
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/Inputs/background-index/definition.jsonrpc b/test/clangd/Inputs/background-index/definition.jsonrpc
index 89d5048..933e779 100644
--- a/test/clangd/Inputs/background-index/definition.jsonrpc
+++ b/test/clangd/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/background-index.test b/test/clangd/background-index.test
index 7826ef2..34c419a 100644
--- a/test/clangd/background-index.test
+++ b/test/clangd/background-index.test
@@ -16,6 +16,5 @@
 # RUN: ls %t/.clangd-index/foo.cpp.*.idx
 
 # Test the index is read from disk: delete code and restart clangd.
-# FIXME: This test currently fails as we don't read the index yet.
 # RUN: rm %t/foo.cpp
-# RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | not FileCheck %t/definition.jsonrpc
+# RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc
diff --git a/test/clangd/completion-auto-trigger.test b/test/clangd/completion-auto-trigger.test
new file mode 100644
index 0000000..db3cc53
--- /dev/null
+++ b/test/clangd/completion-auto-trigger.test
@@ -0,0 +1,106 @@
+# 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":"namespace ns { int ns_member; } struct vector { int size; static int default_capacity; };\nvoid test(vector *a, vector *b) {\n  if (a > b) {} \n  a->size = 10;\n\n  a ? a : b;\n  ns::ns_member = 10;\n}"}}}
+---
+{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":9},"context":{"triggerKind":2,"triggerCharacter":">"}}}
+#      CHECK:  "error": {
+# CHECK-NEXT:    "code": -32001,
+# CHECK-NEXT:    "message": "ignored auto-triggered completion, preceding char did not match"
+# CHECK-NEXT:  },
+# CHECK-NEXT:  "id": 1,
+---
+{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":3,"character":5},"context":{"triggerKind":2,"triggerCharacter":">"}}}
+#      CHECK:  "id": 2,
+# CHECK-NEXT:  "jsonrpc": "2.0"
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "isIncomplete": false,
+# CHECK-NEXT:    "items": [
+# CHECK-NEXT:       {
+# CHECK-NEXT:        "detail": "int",
+# CHECK-NEXT:        "filterText": "size",
+# CHECK-NEXT:        "insertText": "size",
+# CHECK-NEXT:        "insertTextFormat": 1,
+# CHECK-NEXT:        "kind": 5,
+# CHECK-NEXT:        "label": " size",
+# CHECK-NEXT:        "sortText": "3eacccccsize",
+# CHECK-NEXT:        "textEdit": {
+# CHECK-NEXT:          "newText": "size",
+# CHECK-NEXT:          "range": {
+# CHECK-NEXT:            "end": {
+# CHECK-NEXT:              "character": 5,
+# CHECK-NEXT:              "line": 3
+# CHECK-NEXT:            },
+# CHECK-NEXT:            "start": {
+# CHECK-NEXT:              "character": 5,
+# CHECK-NEXT:              "line": 3
+# CHECK-NEXT:            }
+# CHECK-NEXT:          }
+# CHECK-NEXT:        }
+# CHECK-NEXT:      },
+# CHECK-NEXT:      {
+# CHECK-NEXT:         "detail": "int",
+# CHECK-NEXT:         "filterText": "default_capacity",
+# CHECK-NEXT:         "insertText": "default_capacity",
+# CHECK-NEXT:         "insertTextFormat": 1,
+# CHECK-NEXT:         "kind": 10,
+# CHECK-NEXT:         "label": " default_capacity",
+# CHECK-NEXT:         "sortText": "3fd70a3ddefault_capacity",
+# CHECK-NEXT:         "textEdit": {
+# CHECK-NEXT:           "newText": "default_capacity",
+# CHECK-NEXT:           "range": {
+# CHECK-NEXT:             "end": {
+# CHECK-NEXT:               "character": 5,
+# CHECK-NEXT:               "line": 3
+# CHECK-NEXT:             },
+# CHECK-NEXT:             "start": {
+# CHECK-NEXT:               "character": 5,
+# CHECK-NEXT:               "line": 3
+# CHECK-NEXT:             }
+# CHECK-NEXT:           }
+# CHECK-NEXT:         }
+# CHECK-NEXT:       }
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+---
+{"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":5,"character":9},"context":{"triggerKind":2,"triggerCharacter":":"}}}
+#      CHECK:  "error": {
+# CHECK-NEXT:    "code": -32001,
+# CHECK-NEXT:    "message": "ignored auto-triggered completion, preceding char did not match"
+# CHECK-NEXT:  },
+# CHECK-NEXT:  "id": 3,
+---
+{"jsonrpc":"2.0","id":4,"method":"textDocument/completion","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":6,"character":6},"context":{"triggerKind":2,"triggerCharacter":":"}}}
+---
+#      CHECK:  "id": 4,
+# CHECK-NEXT:  "jsonrpc": "2.0"
+# CHECK-NEXT:  "result": {
+# CHECK-NEXT:    "isIncomplete": false,
+# CHECK-NEXT:    "items": [
+# CHECK-NEXT:      {
+# CHECK-NEXT:        "detail": "int",
+# CHECK-NEXT:        "filterText": "ns_member",
+# CHECK-NEXT:        "insertText": "ns_member",
+# CHECK-NEXT:        "insertTextFormat": 1,
+# CHECK-NEXT:        "kind": 6,
+# CHECK-NEXT:        "label": " ns_member",
+# CHECK-NEXT:        "sortText": "3f2cccccns_member",
+# CHECK-NEXT:        "textEdit": {
+# CHECK-NEXT:          "newText": "ns_member",
+# CHECK-NEXT:          "range": {
+# CHECK-NEXT:            "end": {
+# CHECK-NEXT:              "character": 6,
+# CHECK-NEXT:              "line": 6
+# CHECK-NEXT:            },
+# CHECK-NEXT:            "start": {
+# CHECK-NEXT:              "character": 6,
+# CHECK-NEXT:              "line": 6
+# CHECK-NEXT:            }
+# CHECK-NEXT:          }
+# CHECK-NEXT:        }
+# CHECK-NEXT:      }
+# CHECK-NEXT:    ]
+# CHECK-NEXT:  }
+{"jsonrpc":"2.0","id":5,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/diagnostic-category.test b/test/clangd/diagnostic-category.test
index 440afbb..08ad581 100644
--- a/test/clangd/diagnostic-category.test
+++ b/test/clangd/diagnostic-category.test
@@ -7,7 +7,7 @@
 # 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:        "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,
diff --git a/test/clangd/diagnostics.test b/test/clangd/diagnostics.test
index a191c08..ae66269 100644
--- a/test/clangd/diagnostics.test
+++ b/test/clangd/diagnostics.test
@@ -6,7 +6,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Return type of 'main' is not 'int'",
+# CHECK-NEXT:        "message": "Return type of 'main' is not 'int' (fix available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 4,
diff --git a/test/clangd/did-change-configuration-params.test b/test/clangd/did-change-configuration-params.test
index 51b4a87..5c21601 100644
--- a/test/clangd/did-change-configuration-params.test
+++ b/test/clangd/did-change-configuration-params.test
@@ -24,7 +24,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Variable 'i' is uninitialized when used here",
+# CHECK-NEXT:        "message": "Variable 'i' is uninitialized when used here (fix available)",
 # CHECK-NEXT:        "range": {
 # CHECK-NEXT:          "end": {
 # CHECK-NEXT:            "character": 28,
diff --git a/test/clangd/execute-command.test b/test/clangd/execute-command.test
index 85d4b9b..3c9c45f 100644
--- a/test/clangd/execute-command.test
+++ b/test/clangd/execute-command.test
@@ -6,7 +6,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# 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,
diff --git a/test/clangd/filestatus.test b/test/clangd/filestatus.test
new file mode 100644
index 0000000..c485939
--- /dev/null
+++ b/test/clangd/filestatus.test
@@ -0,0 +1,13 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"initializationOptions":{"clangdFileStatus": true},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x; int y = x;"}}}
+#      CHECK:  "method": "textDocument/clangd.fileStatus",
+# CHECK-NEXT:  "params": {
+# CHECK-NEXT:    "state": "parsing includes",
+# CHECK-NEXT:    "uri": "{{.*}}/main.cpp"
+# CHECK-NEXT:  }
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/fixits-codeaction.test b/test/clangd/fixits-codeaction.test
index 97dd4ff..47d7565 100644
--- a/test/clangd/fixits-codeaction.test
+++ b/test/clangd/fixits-codeaction.test
@@ -6,7 +6,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# 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,
@@ -23,14 +23,14 @@
 # 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": [
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "diagnostics": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses",
+# 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,
@@ -82,7 +82,7 @@
 # CHECK-NEXT:    {
 # CHECK-NEXT:      "diagnostics": [
 # CHECK-NEXT:        {
-# CHECK-NEXT:          "message": "Using the result of an assignment as a condition without parentheses",
+# 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,
diff --git a/test/clangd/fixits-command.test b/test/clangd/fixits-command.test
index 67f70db..da50832 100644
--- a/test/clangd/fixits-command.test
+++ b/test/clangd/fixits-command.test
@@ -6,7 +6,7 @@
 # CHECK-NEXT:  "params": {
 # CHECK-NEXT:    "diagnostics": [
 # CHECK-NEXT:      {
-# CHECK-NEXT:        "message": "Using the result of an assignment as a condition without parentheses",
+# 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,
@@ -23,7 +23,7 @@
 # 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 +92,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/test/clangd/fixits-embed-in-diagnostic.test
index f1aa1cf..560fca6 100644
--- a/test/clangd/fixits-embed-in-diagnostic.test
+++ b/test/clangd/fixits-embed-in-diagnostic.test
@@ -31,7 +31,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,
diff --git a/test/clangd/initialize-params.test b/test/clangd/initialize-params.test
index 62f7b41..b9fec65 100644
--- a/test/clangd/initialize-params.test
+++ b/test/clangd/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,
diff --git a/test/clangd/tweaks-format.test b/test/clangd/tweaks-format.test
new file mode 100644
index 0000000..8fe7a11
--- /dev/null
+++ b/test/clangd/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/test/clangd/xpc/initialize.test b/test/clangd/xpc/initialize.test
new file mode 100644
index 0000000..44bef65
--- /dev/null
+++ b/test/clangd/xpc/initialize.test
@@ -0,0 +1,10 @@
+# RUN: clangd-xpc-test-client < %s | FileCheck %s
+# REQUIRES: clangd-xpc-support
+
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"test:///workspace","capabilities":{},"trace":"off"}}
+# CHECK: {"id":0,"jsonrpc":"2.0","result":{"capabilities"
+
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+# CHECK: {"id":3,"jsonrpc":"2.0","result":null}
+
+{"jsonrpc":"2.0","method":"exit"}
diff --git a/test/clangd/xrefs.test b/test/clangd/xrefs.test
index 58ca44c..128c97f 100644
--- a/test/clangd/xrefs.test
+++ b/test/clangd/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/test/lit.cfg b/test/lit.cfg
index 8f8ebaf..ed7bb83 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -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,6 +115,10 @@
 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.in
index bf33b15..d71ca18 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -11,6 +11,7 @@
 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.
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..8e7ce88 100644
--- a/test/pp-trace/pp-trace-conditional.cpp
+++ b/test/pp-trace/pp-trace-conditional.cpp
@@ -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-macro.cpp b/test/pp-trace/pp-trace-macro.cpp
index e6ba761..1202aa2 100644
--- a/test/pp-trace/pp-trace-macro.cpp
+++ b/test/pp-trace/pp-trace-macro.cpp
@@ -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/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/change-namespace/ChangeNamespaceTests.cpp b/unittests/change-namespace/ChangeNamespaceTests.cpp
index 4008600..d66fede 100644
--- a/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ b/unittests/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-apply-replacements/ApplyReplacementsTest.cpp b/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp
index 85aaebf..c532a37 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
 //
 //===----------------------------------------------------------------------===//
 
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/clang-move/ClangMoveTests.cpp b/unittests/clang-move/ClangMoveTests.cpp
index 97c7ce0..0385a79 100644
--- a/unittests/clang-move/ClangMoveTests.cpp
+++ b/unittests/clang-move/ClangMoveTests.cpp
@@ -1,9 +1,8 @@
 //===-- ClangMoveTest.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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-query/QueryEngineTest.cpp b/unittests/clang-query/QueryEngineTest.cpp
index c1d67a1..df3be13 100644
--- a/unittests/clang-query/QueryEngineTest.cpp
+++ b/unittests/clang-query/QueryEngineTest.cpp
@@ -1,9 +1,8 @@
 //===---- QueryTest.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/ClangTidyTest.h b/unittests/clang-tidy/ClangTidyTest.h
index 32bb53c..ca886e4 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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/clang-tidy/IncludeInserterTest.cpp b/unittests/clang-tidy/IncludeInserterTest.cpp
index 7a70f66..bf9a350 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
 //
 //===----------------------------------------------------------------------===//
 
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
index a53f70c..7a3f94a 100644
--- a/unittests/clangd/Annotations.cpp
+++ b/unittests/clangd/Annotations.cpp
@@ -1,35 +1,33 @@
 //===--- 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.
+// Part of the LLVM Project, under the Apache 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"
 
-using namespace llvm;
 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, StringRef Code) {
+static void require(bool Assertion, const char *Msg, llvm::StringRef Code) {
   if (!Assertion) {
-    errs() << "Annotated testcase: " << Msg << "\n" << Code << "\n";
+    llvm::errs() << "Annotated testcase: " << Msg << "\n" << Code << "\n";
     llvm_unreachable("Annotated testcase assertion failed!");
   }
 }
 
-Annotations::Annotations(StringRef Text) {
+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);
   };
-  Optional<StringRef> Name;
-  SmallVector<std::pair<StringRef, Position>, 8> OpenRanges;
+  llvm::Optional<llvm::StringRef> Name;
+  llvm::SmallVector<std::pair<llvm::StringRef, Position>, 8> OpenRanges;
 
   Code.reserve(Text.size());
   while (!Text.empty()) {
@@ -52,7 +50,7 @@
       continue;
     }
     if (Text.consume_front("$")) {
-      Name = Text.take_while(isAlnum);
+      Name = Text.take_while(llvm::isAlnum);
       Text = Text.drop_front(Name->size());
       continue;
     }
@@ -63,23 +61,23 @@
   Require(OpenRanges.empty(), "unmatched [[");
 }
 
-Position Annotations::point(StringRef Name) const {
+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(StringRef Name) const {
+std::vector<Position> Annotations::points(llvm::StringRef Name) const {
   auto P = Points.lookup(Name);
   return {P.begin(), P.end()};
 }
-Range Annotations::range(StringRef Name) const {
+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(StringRef Name) const {
+std::vector<Range> Annotations::ranges(llvm::StringRef Name) const {
   auto R = Ranges.lookup(Name);
   return {R.begin(), R.end()};
 }
diff --git a/unittests/clangd/Annotations.h b/unittests/clangd/Annotations.h
index 4d787c2..07f79b5 100644
--- a/unittests/clangd/Annotations.h
+++ b/unittests/clangd/Annotations.h
@@ -1,9 +1,8 @@
 //===--- 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.
+// Part of the LLVM Project, under the Apache License v2.0 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/BackgroundIndexTests.cpp b/unittests/clangd/BackgroundIndexTests.cpp
index 377e501..09a117d 100644
--- a/unittests/clangd/BackgroundIndexTests.cpp
+++ b/unittests/clangd/BackgroundIndexTests.cpp
@@ -9,11 +9,11 @@
 
 using testing::_;
 using testing::AllOf;
+using testing::Contains;
 using testing::ElementsAre;
 using testing::Not;
 using testing::UnorderedElementsAre;
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -76,7 +76,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 +113,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;
@@ -125,7 +125,7 @@
   ASSERT_TRUE(Idx.blockUntilIdleForTest());
   EXPECT_THAT(
       runFuzzyFind(Idx, ""),
-      UnorderedElementsAre(Named("common"), Named("A_CC"),
+      UnorderedElementsAre(Named("common"), Named("A_CC"), Named("g"),
                            AllOf(Named("f_b"), Declared(), Not(Defined()))));
 
   Cmd.Filename = testPath("root/B.cc");
@@ -135,7 +135,7 @@
   ASSERT_TRUE(Idx.blockUntilIdleForTest());
   // B_CC is dropped as we don't collect symbols from A.h in this compilation.
   EXPECT_THAT(runFuzzyFind(Idx, ""),
-              UnorderedElementsAre(Named("common"), Named("A_CC"),
+              UnorderedElementsAre(Named("common"), Named("A_CC"), Named("g"),
                                    AllOf(Named("f_b"), Declared(), Defined())));
 
   auto Syms = runFuzzyFind(Idx, "common");
@@ -147,7 +147,7 @@
                        FileURI("unittest:///root/B.cc")}));
 }
 
-TEST_F(BackgroundIndexTest, ShardStorageWriteTest) {
+TEST_F(BackgroundIndexTest, ShardStorageTest) {
   MockFSProvider FS;
   FS.Files[testPath("root/A.h")] = R"cpp(
       void common();
@@ -168,7 +168,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());
@@ -176,6 +176,16 @@
   EXPECT_EQ(CacheHits, 0U);
   EXPECT_EQ(Storage.size(), 2U);
 
+  {
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache.
+  EXPECT_EQ(Storage.size(), 2U);
+
   auto ShardHeader = MSS.loadShard(testPath("root/A.h"));
   EXPECT_NE(ShardHeader, nullptr);
   EXPECT_THAT(
@@ -188,7 +198,7 @@
 
   auto ShardSource = MSS.loadShard(testPath("root/A.cc"));
   EXPECT_NE(ShardSource, nullptr);
-  EXPECT_THAT(*ShardSource->Symbols, UnorderedElementsAre());
+  EXPECT_THAT(*ShardSource->Symbols, UnorderedElementsAre(Named("g")));
   EXPECT_THAT(*ShardSource->Refs, RefsAre({FileURI("unittest:///root/A.cc")}));
 }
 
@@ -214,7 +224,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());
@@ -243,15 +253,17 @@
               EmptyIncludeNode());
 }
 
-TEST_F(BackgroundIndexTest, PeriodicalIndex) {
+// FIXME: figure out the right timeouts or rewrite to not use the timeouts and
+// re-enable.
+TEST_F(BackgroundIndexTest, DISABLED_PeriodicalIndex) {
   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; },
-      /*BuildIndexPeriodMs=*/100);
+      Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; },
+      /*BuildIndexPeriodMs=*/500);
 
   FS.Files[testPath("root/A.cc")] = "#include \"A.h\"";
 
@@ -263,7 +275,7 @@
 
   ASSERT_TRUE(Idx.blockUntilIdleForTest());
   EXPECT_THAT(runFuzzyFind(Idx, ""), ElementsAre());
-  std::this_thread::sleep_for(std::chrono::milliseconds(150));
+  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
   EXPECT_THAT(runFuzzyFind(Idx, ""), ElementsAre(Named("X")));
 
   FS.Files[testPath("root/A.h")] = "class Y {};";
@@ -273,9 +285,148 @@
 
   ASSERT_TRUE(Idx.blockUntilIdleForTest());
   EXPECT_THAT(runFuzzyFind(Idx, ""), ElementsAre(Named("X")));
-  std::this_thread::sleep_for(std::chrono::milliseconds(150));
+  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
   EXPECT_THAT(runFuzzyFind(Idx, ""), ElementsAre(Named("Y")));
 }
 
+TEST_F(BackgroundIndexTest, ShardStorageLoad) {
+  MockFSProvider FS;
+  FS.Files[testPath("root/A.h")] = R"cpp(
+      void common();
+      void f_b();
+      class A_CC {};
+      )cpp";
+  FS.Files[testPath("root/A.cc")] =
+      "#include \"A.h\"\nvoid g() { (void)common; }";
+
+  llvm::StringMap<std::string> Storage;
+  size_t CacheHits = 0;
+  MemoryShardStorage MSS(Storage, CacheHits);
+
+  tooling::CompileCommand Cmd;
+  Cmd.Filename = testPath("root/A.cc");
+  Cmd.Directory = testPath("root");
+  Cmd.CommandLine = {"clang++", testPath("root/A.cc")};
+  // 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,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+
+  // Change header.
+  FS.Files[testPath("root/A.h")] = R"cpp(
+      void common();
+      void f_b();
+      class A_CC {};
+      class A_CCnew {};
+      )cpp";
+  {
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache.
+
+  // Check if the new symbol has arrived.
+  auto ShardHeader = MSS.loadShard(testPath("root/A.h"));
+  EXPECT_NE(ShardHeader, nullptr);
+  EXPECT_THAT(*ShardHeader->Symbols, Contains(Named("A_CCnew")));
+
+  // Change source.
+  FS.Files[testPath("root/A.cc")] =
+      "#include \"A.h\"\nvoid g() { (void)common; }\nvoid f_b() {}";
+  {
+    CacheHits = 0;
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache.
+
+  // Check if the new symbol has arrived.
+  ShardHeader = MSS.loadShard(testPath("root/A.h"));
+  EXPECT_NE(ShardHeader, nullptr);
+  EXPECT_THAT(*ShardHeader->Symbols, Contains(Named("A_CCnew")));
+  auto ShardSource = MSS.loadShard(testPath("root/A.cc"));
+  EXPECT_NE(ShardSource, nullptr);
+  EXPECT_THAT(*ShardSource->Symbols,
+              Contains(AllOf(Named("f_b"), Declared(), Defined())));
+}
+
+TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) {
+  MockFSProvider FS;
+  FS.Files[testPath("root/A.h")] = R"cpp(
+      void common();
+      void f_b();
+      class A_CC {};
+      )cpp";
+  FS.Files[testPath("root/B.h")] = R"cpp(
+      #include "A.h"
+      )cpp";
+  FS.Files[testPath("root/A.cc")] =
+      "#include \"B.h\"\nvoid g() { (void)common; }";
+
+  llvm::StringMap<std::string> Storage;
+  size_t CacheHits = 0;
+  MemoryShardStorage MSS(Storage, CacheHits);
+
+  tooling::CompileCommand Cmd;
+  Cmd.Filename = testPath("root/A.cc");
+  Cmd.Directory = testPath("root");
+  Cmd.CommandLine = {"clang++", testPath("root/A.cc")};
+  // Check that A.cc, A.h and B.h has been stored.
+  {
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_THAT(Storage.keys(),
+              UnorderedElementsAre(testPath("root/A.cc"), testPath("root/A.h"),
+                                   testPath("root/B.h")));
+  auto ShardHeader = MSS.loadShard(testPath("root/B.h"));
+  EXPECT_NE(ShardHeader, nullptr);
+  EXPECT_TRUE(ShardHeader->Symbols->empty());
+
+  // Check that A.cc, A.h and B.h has been loaded.
+  {
+    CacheHits = 0;
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_EQ(CacheHits, 3U);
+
+  // Update B.h to contain some symbols.
+  FS.Files[testPath("root/B.h")] = R"cpp(
+      #include "A.h"
+      void new_func();
+      )cpp";
+  // Check that B.h has been stored with new contents.
+  {
+    CacheHits = 0;
+    OverlayCDB CDB(/*Base=*/nullptr);
+    BackgroundIndex Idx(Context::empty(), FS, CDB,
+                        [&](llvm::StringRef) { return &MSS; });
+    CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
+    ASSERT_TRUE(Idx.blockUntilIdleForTest());
+  }
+  EXPECT_EQ(CacheHits, 3U);
+  ShardHeader = MSS.loadShard(testPath("root/B.h"));
+  EXPECT_NE(ShardHeader, nullptr);
+  EXPECT_THAT(*ShardHeader->Symbols,
+              Contains(AllOf(Named("new_func"), Declared(), Not(Defined()))));
+}
+
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt
index f47b1fc..deae9ce 100644
--- a/unittests/clangd/CMakeLists.txt
+++ b/unittests/clangd/CMakeLists.txt
@@ -18,6 +18,7 @@
   CodeCompletionStringsTests.cpp
   ContextTests.cpp
   DexTests.cpp
+  DiagnosticsTests.cpp
   DraftStoreTests.cpp
   ExpectedTypeTest.cpp
   FileDistanceTests.cpp
@@ -33,6 +34,7 @@
   JSONTransportTests.cpp
   QualityTests.cpp
   RIFFTests.cpp
+  SelectionTests.cpp
   SerializationTests.cpp
   SourceCodeTests.cpp
   SymbolCollectorTests.cpp
@@ -44,8 +46,11 @@
   TestTU.cpp
   ThreadingTests.cpp
   TraceTests.cpp
+  TweakTests.cpp
   URITests.cpp
   XRefsTests.cpp
+
+  $<TARGET_OBJECTS:obj.clangDaemonTweaks>
   )
 
 target_link_libraries(ClangdTests
@@ -59,9 +64,14 @@
   clangLex
   clangSema
   clangSerialization
+  clangTidy
   clangTooling
   clangToolingCore
   clangToolingInclusions
   LLVMSupport
   LLVMTestingSupport
   )
+
+if (CLANGD_BUILD_XPC)
+  add_subdirectory(xpc)
+endif ()
diff --git a/unittests/clangd/CancellationTests.cpp b/unittests/clangd/CancellationTests.cpp
index 45a0170..611ce07 100644
--- a/unittests/clangd/CancellationTests.cpp
+++ b/unittests/clangd/CancellationTests.cpp
@@ -8,7 +8,6 @@
 #include <memory>
 #include <thread>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -22,7 +21,7 @@
 }
 
 TEST(CancellationTest, CancelerDiesContextLives) {
-  Optional<WithContext> ContextWithCancellation;
+  llvm::Optional<WithContext> ContextWithCancellation;
   {
     auto Task = cancelableTask();
     ContextWithCancellation.emplace(std::move(Task.first));
diff --git a/unittests/clangd/ClangdTests.cpp b/unittests/clangd/ClangdTests.cpp
index 7f954fd..6454ec8 100644
--- a/unittests/clangd/ClangdTests.cpp
+++ b/unittests/clangd/ClangdTests.cpp
@@ -1,15 +1,15 @@
 //===-- 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"
@@ -30,7 +30,6 @@
 #include <thread>
 #include <vector>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -44,8 +43,9 @@
 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) {
@@ -109,14 +109,14 @@
 
 private:
   mutable std::mutex Mutex;
-  StringMap<bool> LastDiagsHadError;
+  llvm::StringMap<bool> LastDiagsHadError;
 };
 
 /// Replaces all patterns of the form 0x123abc with spaces
 std::string replacePtrsInDump(std::string const &Dump) {
-  Regex RE("0x[0-9a-fA-F]+");
-  SmallVector<StringRef, 1> Matches;
-  StringRef Pending = Dump;
+  llvm::Regex RE("0x[0-9a-fA-F]+");
+  llvm::SmallVector<llvm::StringRef, 1> Matches;
+  llvm::StringRef Pending = Dump;
 
   std::string Result;
   while (RE.match(Pending, &Matches)) {
@@ -139,8 +139,8 @@
 class ClangdVFSTest : public ::testing::Test {
 protected:
   std::string parseSourceAndDumpAST(
-      PathRef SourceFileRelPath, StringRef SourceContents,
-      std::vector<std::pair<PathRef, StringRef>> ExtraFiles = {},
+      PathRef SourceFileRelPath, llvm::StringRef SourceContents,
+      std::vector<std::pair<PathRef, llvm::StringRef>> ExtraFiles = {},
       bool ExpectErrors = false) {
     MockFSProvider FS;
     ErrorCheckingDiagConsumer DiagConsumer;
@@ -269,7 +269,7 @@
 TEST_F(ClangdVFSTest, PropagatesContexts) {
   static Key<int> Secret;
   struct FSProvider : public FileSystemProvider {
-    IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() const override {
+    IntrusiveRefCntPtr<llvm::vfs::FileSystem> getFileSystem() const override {
       Got = Context::current().getExisting(Secret);
       return buildTestFS({});
     }
@@ -313,19 +313,19 @@
 
   // A lib dir for gcc installation
   SmallString<64> LibDir("/randomusr/lib/gcc/x86_64-linux-gnu");
-  sys::path::append(LibDir, Version);
+  llvm::sys::path::append(LibDir, Version);
 
   // Put crtbegin.o into LibDir/64 to trick clang into thinking there's a gcc
   // installation there.
   SmallString<64> DummyLibFile;
-  sys::path::append(DummyLibFile, LibDir, "64", "crtbegin.o");
+  llvm::sys::path::append(DummyLibFile, LibDir, "64", "crtbegin.o");
   FS.Files[DummyLibFile] = "";
 
   SmallString<64> IncludeDir("/randomusr/include/c++");
-  sys::path::append(IncludeDir, Version);
+  llvm::sys::path::append(IncludeDir, Version);
 
   SmallString<64> StringPath;
-  sys::path::append(StringPath, IncludeDir, "string");
+  llvm::sys::path::append(StringPath, IncludeDir, "string");
   FS.Files[StringPath] = "class mock_string {};";
 
   auto FooCpp = testPath("foo.cpp");
@@ -459,10 +459,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();
@@ -475,10 +474,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) {
@@ -533,7 +531,7 @@
   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
@@ -598,7 +596,7 @@
 
     void onDiagnosticsReady(PathRef File,
                             std::vector<Diag> Diagnostics) override {
-      StringRef FileIndexStr = sys::path::stem(File);
+      StringRef FileIndexStr = llvm::sys::path::stem(File);
       ASSERT_TRUE(FileIndexStr.consume_front("Foo"));
 
       unsigned long FileIndex = std::stoul(FileIndexStr.str());
@@ -718,7 +716,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)
@@ -728,13 +726,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(
@@ -976,28 +974,28 @@
 TEST(ClangdTests, PreambleVFSStatCache) {
   class ListenStatsFSProvider : public FileSystemProvider {
   public:
-    ListenStatsFSProvider(StringMap<unsigned> &CountStats)
+    ListenStatsFSProvider(llvm::StringMap<unsigned> &CountStats)
         : CountStats(CountStats) {}
 
-    IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() const override {
-      class ListenStatVFS : public vfs::ProxyFileSystem {
+    IntrusiveRefCntPtr<llvm::vfs::FileSystem> getFileSystem() const override {
+      class ListenStatVFS : public llvm::vfs::ProxyFileSystem {
       public:
-        ListenStatVFS(IntrusiveRefCntPtr<vfs::FileSystem> FS,
-                      StringMap<unsigned> &CountStats)
+        ListenStatVFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
+                      llvm::StringMap<unsigned> &CountStats)
             : ProxyFileSystem(std::move(FS)), CountStats(CountStats) {}
 
-        ErrorOr<std::unique_ptr<vfs::File>>
+        llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
         openFileForRead(const Twine &Path) override {
-          ++CountStats[sys::path::filename(Path.str())];
+          ++CountStats[llvm::sys::path::filename(Path.str())];
           return ProxyFileSystem::openFileForRead(Path);
         }
-        ErrorOr<vfs::Status> status(const Twine &Path) override {
-          ++CountStats[sys::path::filename(Path.str())];
+        llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override {
+          ++CountStats[llvm::sys::path::filename(Path.str())];
           return ProxyFileSystem::status(Path);
         }
 
       private:
-        StringMap<unsigned> &CountStats;
+        llvm::StringMap<unsigned> &CountStats;
       };
 
       return IntrusiveRefCntPtr<ListenStatVFS>(
@@ -1005,11 +1003,11 @@
     }
 
     // If relative paths are used, they are resolved with testPath().
-    StringMap<std::string> Files;
-    StringMap<unsigned> &CountStats;
+    llvm::StringMap<std::string> Files;
+    llvm::StringMap<unsigned> &CountStats;
   };
 
-  StringMap<unsigned> CountStats;
+  llvm::StringMap<unsigned> CountStats;
   ListenStatsFSProvider FS(CountStats);
   ErrorCheckingDiagConsumer DiagConsumer;
   MockCompilationDatabase CDB;
@@ -1038,6 +1036,28 @@
 }
 #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>");
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/ClangdUnitTests.cpp b/unittests/clangd/ClangdUnitTests.cpp
index 4b31677..dd3fc6d 100644
--- a/unittests/clangd/ClangdUnitTests.cpp
+++ b/unittests/clangd/ClangdUnitTests.cpp
@@ -1,9 +1,8 @@
 //===-- 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.
+// Part of the LLVM Project, under the Apache 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,266 +14,11 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 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 " + to_string(Range) + " = [" + Message + "]") {
-  return arg.Range == Range && arg.Message == Message;
-}
-
-MATCHER_P3(Fix, Range, Replacement, Message,
-           "Fix " + 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 " + 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 " + 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(
diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp
index d29e8b5..3a0082a 100644
--- a/unittests/clangd/CodeCompleteTests.cpp
+++ b/unittests/clangd/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,6 +16,7 @@
 #include "SourceCode.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
+#include "TestIndex.h"
 #include "index/MemIndex.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/Support/Error.h"
@@ -24,11 +24,11 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
 namespace {
+using ::llvm::Failed;
 using ::testing::AllOf;
 using ::testing::Contains;
 using ::testing::Each;
@@ -87,7 +87,7 @@
   return MemIndex::build(std::move(Slab).build(), RefSlab());
 }
 
-CodeCompleteResult completions(ClangdServer &Server, StringRef TestCode,
+CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode,
                                Position point,
                                std::vector<Symbol> IndexSymbols = {},
                                clangd::CodeCompleteOptions Opts = {}) {
@@ -100,11 +100,12 @@
 
   auto File = testPath("foo.cpp");
   runAddDocument(Server, File, TestCode);
-  auto CompletionList = cantFail(runCodeComplete(Server, File, point, Opts));
+  auto CompletionList =
+      llvm::cantFail(runCodeComplete(Server, File, point, Opts));
   return CompletionList;
 }
 
-CodeCompleteResult completions(ClangdServer &Server, StringRef Text,
+CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef Text,
                                std::vector<Symbol> IndexSymbols = {},
                                clangd::CodeCompleteOptions Opts = {},
                                PathRef FilePath = "foo.cpp") {
@@ -119,13 +120,13 @@
   Annotations Test(Text);
   runAddDocument(Server, File, Test.code());
   auto CompletionList =
-      cantFail(runCodeComplete(Server, File, Test.point(), Opts));
+      llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts));
   return CompletionList;
 }
 
 // Builds a server and runs code completion.
 // If IndexSymbols is non-empty, an index will be built and passed to opts.
-CodeCompleteResult completions(StringRef Text,
+CodeCompleteResult completions(llvm::StringRef Text,
                                std::vector<Symbol> IndexSymbols = {},
                                clangd::CodeCompleteOptions Opts = {},
                                PathRef FilePath = "foo.cpp") {
@@ -137,51 +138,6 @@
                      FilePath);
 }
 
-std::string replace(StringRef Haystack, StringRef Needle, StringRef Repl) {
-  std::string Result;
-  raw_string_ostream OS(Result);
-  std::pair<StringRef, 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;
-}
-
-// 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(StringRef QName, index::SymbolKind Kind, 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 == 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 += 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(StringRef Name) { // Assumes the function has no args.
-  return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args
-}
-Symbol cls(StringRef Name) {
-  return sym(Name, index::SymbolKind::Class, "@S@\\0");
-}
-Symbol var(StringRef Name) {
-  return sym(Name, index::SymbolKind::Variable, "@\\0");
-}
-Symbol ns(StringRef Name) {
-  return sym(Name, index::SymbolKind::Namespace, "@N@\\0");
-}
 Symbol withReferences(int N, Symbol S) {
   S.References = N;
   return S;
@@ -195,7 +151,7 @@
   int AAA();
   int BBB();
   int CCC();
-}
+};
 int main() { ClassWithMembers().^ }
       )cpp",
                              /*IndexSymbols=*/{}, Opts);
@@ -516,7 +472,8 @@
 
 TEST(CompletionTest, ReferencesAffectRanking) {
   auto Results = completions("int main() { abs^ }", {ns("absl"), func("absb")});
-  EXPECT_THAT(Results.Completions, HasSubsequence(Named("absb"), Named("absl")));
+  EXPECT_THAT(Results.Completions,
+              HasSubsequence(Named("absb"), Named("absl")));
   Results = completions("int main() { abs^ }",
                         {withReferences(10000, ns("absl")), func("absb")});
   EXPECT_THAT(Results.Completions,
@@ -628,7 +585,7 @@
                              R"cpp(
           namespace ns {
             class X;
-            class Y {}
+            class Y {};
           }
           int main() { ns::^ }
       )cpp",
@@ -651,7 +608,7 @@
       #include "bar.h"
       namespace ns { int local; }
       void f() { ns::^; }
-      void f() { ns::preamble().$2^; }
+      void f2() { ns::preamble().$2^; }
   )cpp");
   runAddDocument(Server, File, Test.code());
   clangd::CodeCompleteOptions Opts = {};
@@ -688,6 +645,36 @@
   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(
+    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('"' + testPath("foo_header.h") + '"'),
+                        InsertInclude())));
+}
+
 TEST(CompletionTest, DynamicIndexMultiFile) {
   MockFSProvider FS;
   MockCompilationDatabase CDB;
@@ -861,7 +848,7 @@
 
   EXPECT_TRUE(Results.Completions.empty());
 }
-SignatureHelp signatures(StringRef Text, Position Point,
+SignatureHelp signatures(llvm::StringRef Text, Position Point,
                          std::vector<Symbol> IndexSymbols = {}) {
   std::unique_ptr<SymbolIndex> Index;
   if (!IndexSymbols.empty())
@@ -876,10 +863,10 @@
   ClangdServer Server(CDB, FS, DiagConsumer, Opts);
   auto File = testPath("foo.cpp");
   runAddDocument(Server, File, Text);
-  return cantFail(runSignatureHelp(Server, File, Point));
+  return llvm::cantFail(runSignatureHelp(Server, File, Point));
 }
 
-SignatureHelp signatures(StringRef Text,
+SignatureHelp signatures(llvm::StringRef Text,
                          std::vector<Symbol> IndexSymbols = {}) {
   Annotations Test(Text);
   return signatures(Test.code(), Test.point(), std::move(IndexSymbols));
@@ -997,18 +984,19 @@
 
 class IndexRequestCollector : public SymbolIndex {
 public:
-  bool fuzzyFind(const FuzzyFindRequest &Req,
-                 function_ref<void(const Symbol &)> Callback) const override {
+  bool
+  fuzzyFind(const FuzzyFindRequest &Req,
+            llvm::function_ref<void(const Symbol &)> Callback) const override {
     std::lock_guard<std::mutex> Lock(Mut);
     Requests.push_back(Req);
     return true;
   }
 
   void lookup(const LookupRequest &,
-              function_ref<void(const Symbol &)>) const override {}
+              llvm::function_ref<void(const Symbol &)>) const override {}
 
   void refs(const RefsRequest &,
-            function_ref<void(const Ref &)>) const override {}
+            llvm::function_ref<void(const Ref &)>) const override {}
 
   // This is incorrect, but IndexRequestCollector is not an actual index and it
   // isn't used in production code.
@@ -1027,7 +1015,7 @@
   mutable std::vector<FuzzyFindRequest> Requests;
 };
 
-std::vector<FuzzyFindRequest> captureIndexRequests(StringRef Code) {
+std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code) {
   clangd::CodeCompleteOptions Opts;
   IndexRequestCollector Requests;
   Opts.Index = &Requests;
@@ -1662,7 +1650,8 @@
     auto Results = completions(Server, TestCode.code(), TestCode.point());
 
     EXPECT_EQ(Results.Completions.size(), 1u);
-    EXPECT_THAT(Results.Completions.front().CompletionTokenRange, TestCode.range());
+    EXPECT_THAT(Results.Completions.front().CompletionTokenRange,
+                TestCode.range());
   }
 }
 
@@ -1787,6 +1776,37 @@
                         SigDoc("Doc from sema"))));
 }
 
+TEST(SignatureHelpTest, DynamicIndexDocumentation) {
+  MockFSProvider FS;
+  MockCompilationDatabase CDB;
+  IgnoreDiagnostics DiagConsumer;
+  ClangdServer::Options Opts = ClangdServer::optsForTest();
+  Opts.BuildDynamicSymbolIndex = true;
+  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
+
+  FS.Files[testPath("foo.h")] = R"cpp(
+    struct Foo {
+       // Member doc
+       int foo();
+    };
+  )cpp";
+  Annotations FileContent(R"cpp(
+    #include "foo.h"
+    void test() {
+      Foo f;
+      f.foo(^);
+    }
+  )cpp");
+  auto File = testPath("test.cpp");
+  Server.addDocument(File, FileContent.code());
+  // Wait for the dynamic index being built.
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  EXPECT_THAT(
+      llvm::cantFail(runSignatureHelp(Server, File, FileContent.point()))
+          .signatures,
+      ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Member doc"))));
+}
+
 TEST(CompletionTest, CompletionFunctionArgsDisabled) {
   CodeCompleteOptions Opts;
   Opts.EnableSnippets = true;
@@ -1927,7 +1947,7 @@
       namespace ns1 { int abc; }
       namespace ns2 { int abc; }
       void f() { ns1::ab$1^; ns1::ab$2^; }
-      void f() { ns2::ab$3^; }
+      void f2() { ns2::ab$3^; }
   )cpp");
   runAddDocument(Server, File, Test.code());
   clangd::CodeCompleteOptions Opts = {};
@@ -2095,11 +2115,10 @@
         A a_elem;
       };
     )cpp");
-    EXPECT_THAT(Results.signatures, UnorderedElementsAre(
-            Sig("A(int)", {"int"}),
-            Sig("A(A &&)", {"A &&"}),
-            Sig("A(const A &)", {"const A &"})
-        ));
+    EXPECT_THAT(Results.signatures,
+                UnorderedElementsAre(Sig("A(int)", {"int"}),
+                                     Sig("A(A &&)", {"A &&"}),
+                                     Sig("A(const A &)", {"const A &"})));
   }
   {
     const auto Results = signatures(R"cpp(
@@ -2115,11 +2134,10 @@
         C c_elem;
       };
     )cpp");
-    EXPECT_THAT(Results.signatures, UnorderedElementsAre(
-            Sig("A(int)", {"int"}),
-            Sig("A(A &&)", {"A &&"}),
-            Sig("A(const A &)", {"const A &"})
-        ));
+    EXPECT_THAT(Results.signatures,
+                UnorderedElementsAre(Sig("A(int)", {"int"}),
+                                     Sig("A(A &&)", {"A &&"}),
+                                     Sig("A(const A &)", {"const A &"})));
   }
 }
 
@@ -2134,10 +2152,9 @@
   IgnoreDiagnostics DiagConsumer;
   ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
   auto Results = completions(Server,
-      R"cpp(
+                             R"cpp(
         #include "^"
-      )cpp"
-      );
+      )cpp");
   EXPECT_THAT(Results.Completions,
               AllOf(Has("sub/", CompletionItemKind::Folder),
                     Has("bar.h\"", CompletionItemKind::File)));
@@ -2147,8 +2164,7 @@
   auto Results = completions(
       R"cpp(
         #include "./^"
-      )cpp"
-      );
+      )cpp");
   EXPECT_TRUE(Results.Completions.empty());
 }
 
@@ -2221,9 +2237,8 @@
       @end
       Foo *foo = [Foo new]; int y = [foo v^]
     )objc",
-    /*IndexSymbols=*/{},
-    /*Opts=*/{},
-    "Foo.m");
+                             /*IndexSymbols=*/{},
+                             /*Opts=*/{}, "Foo.m");
 
   auto C = Results.Completions;
   EXPECT_THAT(C, ElementsAre(Named("value")));
@@ -2240,9 +2255,8 @@
       @end
       Foo *foo = [Foo new]; int y = [foo v^]
     )objc",
-    /*IndexSymbols=*/{},
-    /*Opts=*/{},
-    "Foo.m");
+                             /*IndexSymbols=*/{},
+                             /*Opts=*/{}, "Foo.m");
 
   auto C = Results.Completions;
   EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:")));
@@ -2259,17 +2273,16 @@
       @end
       id val = [Foo foo^]
     )objc",
-    /*IndexSymbols=*/{},
-    /*Opts=*/{},
-    "Foo.m");
+                             /*IndexSymbols=*/{},
+                             /*Opts=*/{}, "Foo.m");
 
   auto C = Results.Completions;
   EXPECT_THAT(C, ElementsAre(Named("fooWithValue:")));
   EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method)));
   EXPECT_THAT(C, ElementsAre(ReturnType("id")));
   EXPECT_THAT(C, ElementsAre(Signature("(int) fooey:(unsigned int)")));
-  EXPECT_THAT(C,
-      ElementsAre(SnippetSuffix("${1:(int)} fooey:${2:(unsigned int)}")));
+  EXPECT_THAT(
+      C, ElementsAre(SnippetSuffix("${1:(int)} fooey:${2:(unsigned int)}")));
 }
 
 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
@@ -2279,9 +2292,8 @@
       @end
       id val = [Foo fooWithValue:10 f^]
     )objc",
-    /*IndexSymbols=*/{},
-    /*Opts=*/{},
-    "Foo.m");
+                             /*IndexSymbols=*/{},
+                             /*Opts=*/{}, "Foo.m");
 
   auto C = Results.Completions;
   EXPECT_THAT(C, ElementsAre(Named("fooey:")));
@@ -2291,6 +2303,17 @@
   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")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/CodeCompletionStringsTests.cpp b/unittests/clangd/CodeCompletionStringsTests.cpp
index eab35e1..43429c8 100644
--- a/unittests/clangd/CodeCompletionStringsTests.cpp
+++ b/unittests/clangd/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/unittests/clangd/ContextTests.cpp
index d5cb3ce..d760f4e 100644
--- a/unittests/clangd/ContextTests.cpp
+++ b/unittests/clangd/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/unittests/clangd/DexTests.cpp
index 7265730..cd52daa 100644
--- a/unittests/clangd/DexTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +26,6 @@
 using ::testing::ElementsAre;
 using ::testing::UnorderedElementsAre;
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace dex {
@@ -248,17 +246,17 @@
 
   // No token given, prints full posting list.
   auto I1 = L1.iterator();
-  EXPECT_EQ(to_string(*I1), "[1 3 5]");
+  EXPECT_EQ(llvm::to_string(*I1), "[1 3 5]");
 
   // Token given, uses token's string representation.
   Token Tok(Token::Kind::Trigram, "L2");
   auto I2 = L1.iterator(&Tok);
-  EXPECT_EQ(to_string(*I2), "T=L2");
+  EXPECT_EQ(llvm::to_string(*I2), "T=L2");
 
   auto Tree = C.limit(C.intersect(move(I1), move(I2)), 10);
   // AND reorders its children, we don't care which order it prints.
-  EXPECT_THAT(to_string(*Tree), AnyOf("(LIMIT 10 (& [1 3 5] T=L2))",
-                                      "(LIMIT 10 (& T=L2 [1 3 5]))"));
+  EXPECT_THAT(llvm::to_string(*Tree), AnyOf("(LIMIT 10 (& [1 3 5] T=L2))",
+                                            "(LIMIT 10 (& T=L2 [1 3 5]))"));
 }
 
 TEST(DexIterators, Limit) {
@@ -323,27 +321,28 @@
   const PostingList L3{3};
 
   // empty and/or yield true/false
-  EXPECT_EQ(to_string(*C.intersect()), "true");
-  EXPECT_EQ(to_string(*C.unionOf()), "false");
+  EXPECT_EQ(llvm::to_string(*C.intersect()), "true");
+  EXPECT_EQ(llvm::to_string(*C.unionOf()), "false");
 
   // true/false inside and/or short-circuit
-  EXPECT_EQ(to_string(*C.intersect(L1.iterator(), C.all())), "[1]");
-  EXPECT_EQ(to_string(*C.intersect(L1.iterator(), C.none())), "false");
+  EXPECT_EQ(llvm::to_string(*C.intersect(L1.iterator(), C.all())), "[1]");
+  EXPECT_EQ(llvm::to_string(*C.intersect(L1.iterator(), C.none())), "false");
   // Not optimized to avoid breaking boosts.
-  EXPECT_EQ(to_string(*C.unionOf(L1.iterator(), C.all())), "(| [1] true)");
-  EXPECT_EQ(to_string(*C.unionOf(L1.iterator(), C.none())), "[1]");
+  EXPECT_EQ(llvm::to_string(*C.unionOf(L1.iterator(), C.all())),
+            "(| [1] true)");
+  EXPECT_EQ(llvm::to_string(*C.unionOf(L1.iterator(), C.none())), "[1]");
 
   // and/or nested inside and/or are flattened
-  EXPECT_EQ(to_string(*C.intersect(L1.iterator(),
-                                   C.intersect(L1.iterator(), L1.iterator()))),
+  EXPECT_EQ(llvm::to_string(*C.intersect(
+                L1.iterator(), C.intersect(L1.iterator(), L1.iterator()))),
             "(& [1] [1] [1])");
-  EXPECT_EQ(to_string(*C.unionOf(L1.iterator(),
-                                 C.unionOf(L2.iterator(), L3.iterator()))),
+  EXPECT_EQ(llvm::to_string(*C.unionOf(
+                L1.iterator(), C.unionOf(L2.iterator(), L3.iterator()))),
             "(| [1] [2] [3])");
 
   // optimizations combine over multiple levels
-  EXPECT_EQ(to_string(*C.intersect(C.intersect(L1.iterator(), C.intersect()),
-                                   C.unionOf(C.all()))),
+  EXPECT_EQ(llvm::to_string(*C.intersect(
+                C.intersect(L1.iterator(), C.intersect()), C.unionOf(C.all()))),
             "[1]");
 }
 
@@ -657,9 +656,9 @@
 }
 
 TEST(DexTests, Refs) {
-  DenseMap<SymbolID, std::vector<Ref>> Refs;
+  llvm::DenseMap<SymbolID, std::vector<Ref>> Refs;
   auto AddRef = [&](const Symbol &Sym, const char *Filename, RefKind Kind) {
-    auto& SymbolRefs = Refs[Sym.ID];
+    auto &SymbolRefs = Refs[Sym.ID];
     SymbolRefs.emplace_back();
     SymbolRefs.back().Kind = Kind;
     SymbolRefs.back().Location.FileURI = Filename;
@@ -667,18 +666,48 @@
   auto Foo = symbol("foo");
   auto Bar = symbol("bar");
   AddRef(Foo, "foo.h", RefKind::Declaration);
+  AddRef(Foo, "foo.cc", RefKind::Definition);
   AddRef(Foo, "reffoo.h", RefKind::Reference);
   AddRef(Bar, "bar.h", RefKind::Declaration);
 
-  std::vector<std::string> Files;
   RefsRequest Req;
   Req.IDs.insert(Foo.ID);
   Req.Filter = RefKind::Declaration | RefKind::Definition;
+
+  std::vector<std::string> Files;
   Dex(std::vector<Symbol>{Foo, Bar}, Refs).refs(Req, [&](const Ref &R) {
     Files.push_back(R.Location.FileURI);
   });
+  EXPECT_THAT(Files, UnorderedElementsAre("foo.h", "foo.cc"));
 
-  EXPECT_THAT(Files, ElementsAre("foo.h"));
+  Req.Limit = 1;
+  Files.clear();
+  Dex(std::vector<Symbol>{Foo, Bar}, Refs).refs(Req, [&](const Ref &R) {
+    Files.push_back(R.Location.FileURI);
+  });
+  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"));
 }
 
 } // namespace
diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp
new file mode 100644
index 0000000..d9c9dfc
--- /dev/null
+++ b/unittests/clangd/DiagnosticsTests.cpp
@@ -0,0 +1,455 @@
+//===--- 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 "SourceCode.h"
+#include "TestIndex.h"
+#include "TestTU.h"
+#include "index/MemIndex.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 &> 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)) {
+  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.
+  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 [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 (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 =
+      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())));
+}
+
+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;
+}
+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("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;
+  $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"))),
+          AllOf(Diag(Test.range("unqualified2"),
+                     "use of undeclared identifier 'X'"),
+                WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
+                            "Add include \"x.h\" for symbol ns::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'")));
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
+
diff --git a/unittests/clangd/DraftStoreTests.cpp b/unittests/clangd/DraftStoreTests.cpp
index 44faa8b..ba1007b 100644
--- a/unittests/clangd/DraftStoreTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,29 +12,28 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 struct IncrementalTestStep {
-  StringRef Src;
-  StringRef Contents;
+  llvm::StringRef Src;
+  llvm::StringRef Contents;
 };
 
-int rangeLength(StringRef Code, const Range &Rng) {
-  Expected<size_t> Start = positionToOffset(Code, Rng.start);
-  Expected<size_t> End = positionToOffset(Code, Rng.end);
+int rangeLength(llvm::StringRef Code, const Range &Rng) {
+  llvm::Expected<size_t> Start = positionToOffset(Code, Rng.start);
+  llvm::Expected<size_t> End = positionToOffset(Code, Rng.end);
   assert(Start);
   assert(End);
   return *End - *Start;
 }
 
 /// Send the changes one by one to updateDraft, verify the intermediate results.
-void stepByStep(ArrayRef<IncrementalTestStep> Steps) {
+void stepByStep(llvm::ArrayRef<IncrementalTestStep> Steps) {
   DraftStore DS;
   Annotations InitialSrc(Steps.front().Src);
-  constexpr StringLiteral Path("/hello.cpp");
+  constexpr llvm::StringLiteral Path("/hello.cpp");
 
   // Set the initial content.
   DS.addDraft(Path, InitialSrc.code());
@@ -43,14 +41,14 @@
   for (size_t i = 1; i < Steps.size(); i++) {
     Annotations SrcBefore(Steps[i - 1].Src);
     Annotations SrcAfter(Steps[i].Src);
-    StringRef Contents = Steps[i - 1].Contents;
+    llvm::StringRef Contents = Steps[i - 1].Contents;
     TextDocumentContentChangeEvent Event{
         SrcBefore.range(),
         rangeLength(SrcBefore.code(), SrcBefore.range()),
         Contents.str(),
     };
 
-    Expected<std::string> Result = DS.updateDraft(Path, {Event});
+    llvm::Expected<std::string> Result = DS.updateDraft(Path, {Event});
     ASSERT_TRUE(!!Result);
     EXPECT_EQ(*Result, SrcAfter.code());
     EXPECT_EQ(*DS.getDraft(Path), SrcAfter.code());
@@ -58,16 +56,16 @@
 }
 
 /// Send all the changes at once to updateDraft, check only the final result.
-void allAtOnce(ArrayRef<IncrementalTestStep> Steps) {
+void allAtOnce(llvm::ArrayRef<IncrementalTestStep> Steps) {
   DraftStore DS;
   Annotations InitialSrc(Steps.front().Src);
   Annotations FinalSrc(Steps.back().Src);
-  constexpr StringLiteral Path("/hello.cpp");
+  constexpr llvm::StringLiteral Path("/hello.cpp");
   std::vector<TextDocumentContentChangeEvent> Changes;
 
   for (size_t i = 0; i < Steps.size() - 1; i++) {
     Annotations Src(Steps[i].Src);
-    StringRef Contents = Steps[i].Contents;
+    llvm::StringRef Contents = Steps[i].Contents;
 
     Changes.push_back({
         Src.range(),
@@ -79,9 +77,9 @@
   // Set the initial content.
   DS.addDraft(Path, InitialSrc.code());
 
-  Expected<std::string> Result = DS.updateDraft(Path, Changes);
+  llvm::Expected<std::string> Result = DS.updateDraft(Path, Changes);
 
-  ASSERT_TRUE(!!Result) << toString(Result.takeError());
+  ASSERT_TRUE(!!Result) << llvm::toString(Result.takeError());
   EXPECT_EQ(*Result, FinalSrc.code());
   EXPECT_EQ(*DS.getDraft(Path), FinalSrc.code());
 }
diff --git a/unittests/clangd/ExpectedTypeTest.cpp b/unittests/clangd/ExpectedTypeTest.cpp
index e739869..d109c79 100644
--- a/unittests/clangd/ExpectedTypeTest.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,8 +16,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
-
 namespace clang {
 namespace clangd {
 namespace {
@@ -30,21 +27,21 @@
 
 class ExpectedTypeConversionTest : public ::testing::Test {
 protected:
-  void build(StringRef Code) {
+  void build(llvm::StringRef Code) {
     assert(!AST && "AST built twice");
     AST = TestTU::withCode(Code).build();
   }
 
-  const ValueDecl *decl(StringRef Name) {
+  const ValueDecl *decl(llvm::StringRef Name) {
     return &cast<ValueDecl>(findDecl(*AST, Name));
   }
 
-  QualType typeOf(StringRef Name) {
+  QualType typeOf(llvm::StringRef Name) {
     return decl(Name)->getType().getCanonicalType();
   }
 
   /// An overload for convenience.
-  Optional<OpaqueType> fromCompletionResult(const ValueDecl *D) {
+  llvm::Optional<OpaqueType> fromCompletionResult(const ValueDecl *D) {
     return OpaqueType::fromCompletionResult(
         ASTCtx(), CodeCompletionResult(D, CCP_Declaration));
   }
@@ -54,7 +51,7 @@
   using EquivClass = std::set<std::string>;
 
   Matcher<std::map<std::string, EquivClass>>
-  ClassesAre(ArrayRef<EquivClass> Classes) {
+  ClassesAre(llvm::ArrayRef<EquivClass> Classes) {
     using MapEntry = std::map<std::string, EquivClass>::value_type;
 
     std::vector<Matcher<MapEntry>> Elements;
@@ -67,9 +64,9 @@
   // Groups \p Decls into equivalence classes based on the result of
   // 'OpaqueType::fromCompletionResult'.
   std::map<std::string, EquivClass>
-  buildEquivClasses(ArrayRef<StringRef> DeclNames) {
+  buildEquivClasses(llvm::ArrayRef<llvm::StringRef> DeclNames) {
     std::map<std::string, EquivClass> Classes;
-    for (StringRef Name : DeclNames) {
+    for (llvm::StringRef Name : DeclNames) {
       auto Type = OpaqueType::fromType(ASTCtx(), typeOf(Name));
       Classes[Type->raw()].insert(Name);
     }
@@ -80,7 +77,7 @@
 
 private:
   // Set after calling build().
-  Optional<ParsedAST> AST;
+  llvm::Optional<ParsedAST> AST;
 };
 
 TEST_F(ExpectedTypeConversionTest, BasicTypes) {
diff --git a/unittests/clangd/FSTests.cpp b/unittests/clangd/FSTests.cpp
index 74dde3b..044452c 100644
--- a/unittests/clangd/FSTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,13 +11,12 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 TEST(FSTests, PreambleStatusCache) {
-  StringMap<std::string> Files;
+  llvm::StringMap<std::string> Files;
   Files["x"] = "";
   Files["y"] = "";
   Files["main"] = "";
@@ -36,9 +34,10 @@
   // Main file is not cached.
   EXPECT_FALSE(StatCache.lookup(testPath("main")).hasValue());
 
-  vfs::Status S("fake", sys::fs::UniqueID(0, 0),
-                std::chrono::system_clock::now(), 0, 0, 1024,
-                sys::fs::file_type::regular_file, sys::fs::all_all);
+  llvm::vfs::Status S("fake", llvm::sys::fs::UniqueID(0, 0),
+                      std::chrono::system_clock::now(), 0, 0, 1024,
+                      llvm::sys::fs::file_type::regular_file,
+                      llvm::sys::fs::all_all);
   StatCache.update(*FS, S);
   auto ConsumeFS = StatCache.getConsumingFS(FS);
   auto Cached = ConsumeFS->status(testPath("fake"));
diff --git a/unittests/clangd/FileDistanceTests.cpp b/unittests/clangd/FileDistanceTests.cpp
index 6d7d477..3003582 100644
--- a/unittests/clangd/FileDistanceTests.cpp
+++ b/unittests/clangd/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/unittests/clangd/FileIndexTests.cpp
index cc5d260..5667cb8 100644
--- a/unittests/clangd/FileIndexTests.cpp
+++ b/unittests/clangd/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,6 +12,7 @@
 #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"
@@ -31,7 +31,6 @@
 using testing::IsEmpty;
 using testing::Pair;
 using testing::UnorderedElementsAre;
-using namespace llvm;
 
 MATCHER_P(RefRange, Range, "") {
   return std::make_tuple(arg.Location.Start.line(), arg.Location.Start.column(),
@@ -39,11 +38,13 @@
          std::make_tuple(Range.start.line, Range.start.character,
                          Range.end.line, Range.end.character);
 }
-MATCHER_P(FileURI, F, "") { return StringRef(arg.Location.FileURI) == F; }
+MATCHER_P(FileURI, F, "") { return llvm::StringRef(arg.Location.FileURI) == F; }
 MATCHER_P(DeclURI, U, "") {
-  return StringRef(arg.CanonicalDeclaration.FileURI) == U;
+  return llvm::StringRef(arg.CanonicalDeclaration.FileURI) == U;
 }
-MATCHER_P(DefURI, U, "") { return StringRef(arg.Definition.FileURI) == U; }
+MATCHER_P(DefURI, U, "") {
+  return llvm::StringRef(arg.Definition.FileURI) == U;
+}
 MATCHER_P(QName, N, "") { return (arg.Scope + arg.Name).str() == N; }
 
 namespace clang {
@@ -54,7 +55,7 @@
   return ElementsAre(testing::Pair(_, UnorderedElementsAreArray(Matchers)));
 }
 
-Symbol symbol(StringRef ID) {
+Symbol symbol(llvm::StringRef ID) {
   Symbol Sym;
   Sym.ID = SymbolID(ID);
   Sym.Name = ID;
@@ -103,7 +104,7 @@
   auto OneSymboSlab = [](Symbol Sym) {
     SymbolSlab::Builder S;
     S.insert(Sym);
-    return make_unique<SymbolSlab>(std::move(S).build());
+    return llvm::make_unique<SymbolSlab>(std::move(S).build());
   };
   auto X1 = symbol("x");
   X1.CanonicalDeclaration.FileURI = "file:///x1";
@@ -141,14 +142,14 @@
 }
 
 // Adds Basename.cpp, which includes Basename.h, which contains Code.
-void update(FileIndex &M, StringRef Basename, StringRef Code) {
+void update(FileIndex &M, llvm::StringRef Basename, llvm::StringRef Code) {
   TestTU File;
   File.Filename = (Basename + ".cpp").str();
   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) {
@@ -199,13 +200,49 @@
                                    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) {
+  FileIndex Index;
+  const std::string Header = R"cpp(
+    class Foo {};
+  )cpp";
+  auto MainFile = testPath("foo.cpp");
+  auto HeaderFile = testPath("algorithm");
+  std::vector<const char *> Cmd = {"clang", "-xc++", MainFile.c_str(),
+                                   "-include", HeaderFile.c_str()};
+  // Preparse ParseInputs.
+  ParseInputs PI;
+  PI.CompileCommand.Directory = testRoot();
+  PI.CompileCommand.Filename = MainFile;
+  PI.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
+  PI.Contents = "";
+  PI.FS = buildTestFS({{MainFile, ""}, {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,
+          const CanonicalIncludes &Includes) {
+        Index.updatePreamble(MainFile, Ctx, PP, Includes);
+      });
+  auto Symbols = runFuzzyFind(Index, "");
+  EXPECT_THAT(Symbols, ElementsAre(_));
+  EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader,
+              "<algorithm>");
 }
 
 TEST(FileIndexTest, TemplateParamsInLabel) {
@@ -246,7 +283,7 @@
   PI.CompileCommand.Filename = FooCpp;
   PI.CompileCommand.CommandLine = {"clang", "-xc++", FooCpp};
 
-  StringMap<std::string> Files;
+  llvm::StringMap<std::string> Files;
   Files[FooCpp] = "";
   Files[FooH] = R"cpp(
     namespace ns_in_header {
@@ -270,10 +307,11 @@
   buildPreamble(
       FooCpp, *CI, /*OldPreamble=*/nullptr, tooling::CompileCommand(), PI,
       std::make_shared<PCHContainerOperations>(), /*StoreInMemory=*/true,
-      [&](ASTContext &Ctx, std::shared_ptr<Preprocessor> PP) {
+      [&](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);
 
@@ -343,7 +381,7 @@
   )cpp");
   auto MainFile = testPath("foo.cpp");
   auto HeaderFile = testPath("foo.h");
-  std::vector<const char*> Cmd = {"clang", "-xc++", MainFile.c_str()};
+  std::vector<const char *> Cmd = {"clang", "-xc++", MainFile.c_str()};
   // Preparse ParseInputs.
   ParseInputs PI;
   PI.CompileCommand.Directory = testRoot();
@@ -355,22 +393,22 @@
   // 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) {});
+      MainFile, *buildCompilerInvocation(PI), /*OldPreamble=*/nullptr,
+      tooling::CompileCommand(), PI, std::make_shared<PCHContainerOperations>(),
+      /*StoreInMemory=*/true,
+      [&](ASTContext &Ctx, std::shared_ptr<Preprocessor> PP,
+          const CanonicalIncludes &) {});
   // Build AST for main file with preamble.
   auto AST =
       ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData,
-                       MemoryBuffer::getMemBufferCopy(Main.code()),
-                       std::make_shared<PCHContainerOperations>(), PI.FS);
+                       llvm::MemoryBuffer::getMemBufferCopy(Main.code()),
+                       std::make_shared<PCHContainerOperations>(), PI.FS,
+                       /*Index=*/nullptr, ParseOptions());
   ASSERT_TRUE(AST);
   FileIndex Index;
   Index.updateMain(MainFile, *AST);
 
-  auto Foo =
-      findSymbol(TestTU::withHeaderCode(Header).headerSymbols(), "Foo");
+  auto Foo = findSymbol(TestTU::withHeaderCode(Header).headerSymbols(), "Foo");
   RefsRequest Request;
   Request.IDs.insert(Foo.ID);
 
diff --git a/unittests/clangd/FindSymbolsTests.cpp b/unittests/clangd/FindSymbolsTests.cpp
index ec7865e..78447f3 100644
--- a/unittests/clangd/FindSymbolsTests.cpp
+++ b/unittests/clangd/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"
@@ -14,8 +13,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
-
 namespace clang {
 namespace clangd {
 
@@ -64,6 +61,7 @@
       : Server(CDB, FSProvider, DiagConsumer, optsForTests()) {
     // Make sure the test root directory is created.
     FSProvider.Files[testPath("unused")] = "";
+    CDB.ExtraClangFlags = {"-xc++"};
   }
 
 protected:
@@ -73,14 +71,14 @@
   ClangdServer Server;
   int Limit = 0;
 
-  std::vector<SymbolInformation> getSymbols(StringRef Query) {
+  std::vector<SymbolInformation> getSymbols(llvm::StringRef Query) {
     EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble";
     auto SymbolInfos = runWorkspaceSymbols(Server, Query, Limit);
     EXPECT_TRUE(bool(SymbolInfos)) << "workspaceSymbols returned an error";
     return *SymbolInfos;
   }
 
-  void addFile(StringRef FileName, StringRef Contents) {
+  void addFile(llvm::StringRef FileName, llvm::StringRef Contents) {
     auto Path = testPath(FileName);
     FSProvider.Files[Path] = Contents;
     Server.addDocument(Path, Contents);
@@ -89,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) {
@@ -143,10 +144,11 @@
 
 TEST_F(WorkspaceSymbolsTest, InMainFile) {
   addFile("foo.cpp", R"cpp(
-      int test() {
-      }
+      int test() {}
+      static test2() {}
       )cpp");
-  EXPECT_THAT(getSymbols("test"), IsEmpty());
+  EXPECT_THAT(getSymbols("test"), 
+              ElementsAre(QName("test"), QName("test2")));
 }
 
 TEST_F(WorkspaceSymbolsTest, Namespaces) {
@@ -186,7 +188,7 @@
   addFile("foo.cpp", R"cpp(
       #include "foo.h"
       )cpp");
-  EXPECT_THAT(getSymbols("test"), IsEmpty());
+  EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test")));
 }
 
 TEST_F(WorkspaceSymbolsTest, MultiFile) {
@@ -273,7 +275,7 @@
 TEST_F(WorkspaceSymbolsTest, Ranking) {
   addFile("foo.h", R"cpp(
       namespace ns{}
-      function func();
+      void func();
       )cpp");
   addFile("foo.cpp", R"cpp(
       #include "foo.h"
@@ -318,7 +320,7 @@
     return *SymbolInfos;
   }
 
-  void addFile(StringRef FilePath, StringRef Contents) {
+  void addFile(llvm::StringRef FilePath, llvm::StringRef Contents) {
     FSProvider.Files[FilePath] = Contents;
     Server.addDocument(FilePath, Contents);
   }
@@ -439,7 +441,7 @@
 TEST_F(DocumentSymbolsTest, ExternSymbol) {
   std::string FilePath = testPath("foo.cpp");
   addFile(testPath("foo.h"), R"cpp(
-      extern int var = 2;
+      extern int var;
       )cpp");
   addFile(FilePath, R"cpp(
       #include "foo.h"
diff --git a/unittests/clangd/FunctionTests.cpp b/unittests/clangd/FunctionTests.cpp
index 1311ee4..dc12186 100644
--- a/unittests/clangd/FunctionTests.cpp
+++ b/unittests/clangd/FunctionTests.cpp
@@ -1,9 +1,8 @@
 //===-- FunctionsTests.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
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,7 +10,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
diff --git a/unittests/clangd/FuzzyMatchTests.cpp b/unittests/clangd/FuzzyMatchTests.cpp
index b1981a6..d2ddbda 100644
--- a/unittests/clangd/FuzzyMatchTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -21,17 +19,18 @@
 
 struct ExpectedMatch {
   // Annotations are optional, and will not be asserted if absent.
-  ExpectedMatch(StringRef Match) : Word(Match), Annotated(Match) {
+  ExpectedMatch(llvm::StringRef Match) : Word(Match), Annotated(Match) {
     for (char C : "[]")
       Word.erase(std::remove(Word.begin(), Word.end(), C), Word.end());
     if (Word.size() == Annotated->size())
-      Annotated = None;
+      Annotated = llvm::None;
   }
-  bool accepts(StringRef ActualAnnotated) const {
+  bool accepts(llvm::StringRef ActualAnnotated) const {
     return !Annotated || ActualAnnotated == *Annotated;
   }
 
-  friend raw_ostream &operator<<(raw_ostream &OS, const ExpectedMatch &M) {
+  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                       const ExpectedMatch &M) {
     OS << "'" << M.Word;
     if (M.Annotated)
       OS << "' as " << *M.Annotated;
@@ -41,26 +40,27 @@
   std::string Word;
 
 private:
-  Optional<StringRef> Annotated;
+  llvm::Optional<llvm::StringRef> Annotated;
 };
 
-struct MatchesMatcher : public testing::MatcherInterface<StringRef> {
+struct MatchesMatcher : public testing::MatcherInterface<llvm::StringRef> {
   ExpectedMatch Candidate;
-  Optional<float> Score;
-  MatchesMatcher(ExpectedMatch Candidate, Optional<float> Score)
+  llvm::Optional<float> Score;
+  MatchesMatcher(ExpectedMatch Candidate, llvm::Optional<float> Score)
       : Candidate(std::move(Candidate)), Score(Score) {}
 
   void DescribeTo(::std::ostream *OS) const override {
-    raw_os_ostream(*OS) << "Matches " << Candidate;
+    llvm::raw_os_ostream(*OS) << "Matches " << Candidate;
     if (Score)
       *OS << " with score " << *Score;
   }
 
-  bool MatchAndExplain(StringRef Pattern,
+  bool MatchAndExplain(llvm::StringRef Pattern,
                        testing::MatchResultListener *L) const override {
-    std::unique_ptr<raw_ostream> OS(
-        L->stream() ? (raw_ostream *)(new raw_os_ostream(*L->stream()))
-                    : new raw_null_ostream());
+    std::unique_ptr<llvm::raw_ostream> OS(
+        L->stream()
+            ? (llvm::raw_ostream *)(new llvm::raw_os_ostream(*L->stream()))
+            : new llvm::raw_null_ostream());
     FuzzyMatcher Matcher(Pattern);
     auto Result = Matcher.match(Candidate.Word);
     auto AnnotatedMatch = Matcher.dumpLast(*OS << "\n");
@@ -71,8 +71,9 @@
 
 // Accepts patterns that match a given word, optionally requiring a score.
 // Dumps the debug tables on match failure.
-testing::Matcher<StringRef> matches(StringRef M, Optional<float> Score = {}) {
-  return testing::MakeMatcher<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) {
@@ -178,27 +179,28 @@
   EXPECT_THAT("std", Not(matches("pthread_condattr_setpshared")));
 }
 
-struct RankMatcher : public testing::MatcherInterface<StringRef> {
+struct RankMatcher : public testing::MatcherInterface<llvm::StringRef> {
   std::vector<ExpectedMatch> RankedStrings;
   RankMatcher(std::initializer_list<ExpectedMatch> RankedStrings)
       : RankedStrings(RankedStrings) {}
 
   void DescribeTo(::std::ostream *OS) const override {
-    raw_os_ostream O(*OS);
+    llvm::raw_os_ostream O(*OS);
     O << "Ranks strings in order: [";
     for (const auto &Str : RankedStrings)
       O << "\n\t" << Str;
     O << "\n]";
   }
 
-  bool MatchAndExplain(StringRef Pattern,
+  bool MatchAndExplain(llvm::StringRef Pattern,
                        testing::MatchResultListener *L) const override {
-    std::unique_ptr<raw_ostream> OS(
-        L->stream() ? (raw_ostream *)(new raw_os_ostream(*L->stream()))
-                    : new raw_null_ostream());
+    std::unique_ptr<llvm::raw_ostream> OS(
+        L->stream()
+            ? (llvm::raw_ostream *)(new llvm::raw_os_ostream(*L->stream()))
+            : new llvm::raw_null_ostream());
     FuzzyMatcher Matcher(Pattern);
     const ExpectedMatch *LastMatch;
-    Optional<float> LastScore;
+    llvm::Optional<float> LastScore;
     bool Ok = true;
     for (const auto &Str : RankedStrings) {
       auto Score = Matcher.match(Str.Word);
@@ -208,7 +210,7 @@
         Ok = false;
       } else {
         std::string Buf;
-        raw_string_ostream Info(Buf);
+        llvm::raw_string_ostream Info(Buf);
         auto AnnotatedMatch = Matcher.dumpLast(Info);
 
         if (!Str.accepts(AnnotatedMatch)) {
@@ -233,8 +235,9 @@
 
 // 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<StringRef> ranks(T... RankedStrings) {
-  return testing::MakeMatcher<StringRef>(
+template <typename... T>
+testing::Matcher<llvm::StringRef> ranks(T... RankedStrings) {
+  return testing::MakeMatcher<llvm::StringRef>(
       new RankMatcher{ExpectedMatch(RankedStrings)...});
 }
 
@@ -275,7 +278,7 @@
 
 // Returns pretty-printed segmentation of Text.
 // e.g. std::basic_string --> +--  +---- +-----
-std::string segment(StringRef Text) {
+std::string segment(llvm::StringRef Text) {
   std::vector<CharRole> Roles(Text.size());
   calculateRoles(Text, Roles);
   std::string Printed;
@@ -285,7 +288,7 @@
 }
 
 // this is a no-op hack so clang-format will vertically align our testcases.
-StringRef returns(StringRef Text) { return Text; }
+llvm::StringRef returns(llvm::StringRef Text) { return Text; }
 
 TEST(FuzzyMatch, Segmentation) {
   EXPECT_THAT(segment("std::basic_string"), //
diff --git a/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/unittests/clangd/GlobalCompilationDatabaseTests.cpp
index f391610..a1b696f 100644
--- a/unittests/clangd/GlobalCompilationDatabaseTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,34 +13,37 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 using ::testing::ElementsAre;
+using ::testing::EndsWith;
 
 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("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++.
   Cmd = DB.getFallbackCommand(testPath("foo/bar.h"));
-  EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-xobjective-c++-header",
-                                           testPath("foo/bar.h")));
+  EXPECT_THAT(Cmd.CommandLine,
+              ElementsAre(EndsWith("clang"), "-xobjective-c++-header",
+                          testPath("foo/bar.h")));
 }
 
-static tooling::CompileCommand cmd(StringRef File, StringRef Arg) {
+static tooling::CompileCommand cmd(llvm::StringRef File, llvm::StringRef Arg) {
   return tooling::CompileCommand(testRoot(), File, {"clang", Arg, File}, "");
 }
 
 class OverlayCDBTest : public ::testing::Test {
   class BaseCDB : public GlobalCompilationDatabase {
   public:
-    Optional<tooling::CompileCommand>
-    getCompileCommand(StringRef File, ProjectInfo *Project) const override {
+    llvm::Optional<tooling::CompileCommand>
+    getCompileCommand(llvm::StringRef File,
+                      ProjectInfo *Project) const override {
       if (File == testPath("foo.cc")) {
         if (Project)
           Project->SourceRoot = testRoot();
@@ -50,7 +52,8 @@
       return None;
     }
 
-    tooling::CompileCommand getFallbackCommand(StringRef File) const override {
+    tooling::CompileCommand
+    getFallbackCommand(llvm::StringRef File) const override {
       return cmd(File, "-DA=2");
     }
   };
@@ -61,7 +64,7 @@
 };
 
 TEST_F(OverlayCDBTest, GetCompileCommand) {
-  OverlayCDB CDB(Base.get());
+  OverlayCDB CDB(Base.get(), {}, std::string(""));
   EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")),
             Base->getCompileCommand(testPath("foo.cc")));
   EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None);
@@ -81,14 +84,14 @@
 }
 
 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.getFallbackCommand(testPath("foo.cc")).CommandLine,
-              ElementsAre("clang", testPath("foo.cc"), "-DA=6"));
+              ElementsAre(EndsWith("clang"), testPath("foo.cc"), "-DA=6"));
 }
 
 TEST_F(OverlayCDBTest, Watch) {
diff --git a/unittests/clangd/HeadersTests.cpp b/unittests/clangd/HeadersTests.cpp
index bd28f71..65bcb85 100644
--- a/unittests/clangd/HeadersTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,7 +18,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -53,7 +51,7 @@
     CI->getDiagnosticOpts().IgnoreWarnings = true;
     auto Clang = prepareCompilerInstance(
         std::move(CI), /*Preamble=*/nullptr,
-        MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile),
+        llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile),
         std::make_shared<PCHContainerOperations>(), VFS, IgnoreDiags);
 
     EXPECT_FALSE(Clang->getFrontendOpts().Inputs.empty());
@@ -85,9 +83,9 @@
 
     if (Preferred.empty())
       Preferred = Original;
-    auto ToHeaderFile = [](StringRef Header) {
+    auto ToHeaderFile = [](llvm::StringRef Header) {
       return HeaderFile{Header,
-                        /*Verbatim=*/!sys::path::is_absolute(Header)};
+                        /*Verbatim=*/!llvm::sys::path::is_absolute(Header)};
     };
 
     IncludeInserter Inserter(MainFile, /*Code=*/"", format::getLLVMStyle(),
@@ -104,7 +102,7 @@
     return Path;
   }
 
-  Optional<TextEdit> insert(StringRef VerbatimHeader) {
+  llvm::Optional<TextEdit> insert(llvm::StringRef VerbatimHeader) {
     auto Clang = setupClang();
     PreprocessOnlyAction Action;
     EXPECT_TRUE(
@@ -122,7 +120,7 @@
   MockCompilationDatabase CDB;
   std::string MainFile = testPath("main.cpp");
   std::string Subdir = testPath("sub");
-  std::string SearchDirArg = (Twine("-I") + Subdir).str();
+  std::string SearchDirArg = (llvm::Twine("-I") + Subdir).str();
   IgnoringDiagConsumer IgnoreDiags;
 };
 
diff --git a/unittests/clangd/IndexActionTests.cpp b/unittests/clangd/IndexActionTests.cpp
index 93f324b..55ec459 100644
--- a/unittests/clangd/IndexActionTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -68,7 +67,7 @@
   runIndexingAction(llvm::StringRef MainFilePath,
                     const std::vector<std::string> &ExtraArgs = {}) {
     IndexFileIn IndexFile;
-    IntrusiveRefCntPtr<FileManager> Files(
+    llvm::IntrusiveRefCntPtr<FileManager> Files(
         new FileManager(FileSystemOptions(), InMemoryFileSystem));
 
     auto Action = createStaticIndexingAction(
@@ -101,7 +100,7 @@
 
 protected:
   std::vector<std::string> FilePaths;
-  IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
+  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
 };
 
 TEST_F(IndexActionTest, CollectIncludeGraph) {
diff --git a/unittests/clangd/IndexTests.cpp b/unittests/clangd/IndexTests.cpp
index 6bfdf6a..7d60ede 100644
--- a/unittests/clangd/IndexTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,12 +18,12 @@
 
 using testing::_;
 using testing::AllOf;
+using testing::AnyOf;
 using testing::ElementsAre;
 using testing::Pair;
 using testing::Pointee;
 using testing::UnorderedElementsAre;
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -219,6 +218,7 @@
   R.Documentation = "--doc--";
   L.Origin = SymbolOrigin::Dynamic;
   R.Origin = SymbolOrigin::Static;
+  R.Type = "expectedType";
 
   Symbol M = mergeSymbol(L, R);
   EXPECT_EQ(M.Name, "Foo");
@@ -227,6 +227,7 @@
   EXPECT_EQ(M.Signature, "()");
   EXPECT_EQ(M.CompletionSnippetSuffix, "{$1:0}");
   EXPECT_EQ(M.Documentation, "--doc--");
+  EXPECT_EQ(M.Type, "expectedType");
   EXPECT_EQ(M.Origin,
             SymbolOrigin::Dynamic | SymbolOrigin::Static | SymbolOrigin::Merge);
 }
@@ -252,6 +253,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;
@@ -291,7 +308,6 @@
   Request.IDs = {Foo.ID};
   RefSlab::Builder Results;
   Merge.refs(Request, [&](const Ref &O) { Results.insert(Foo.ID, O); });
-
   EXPECT_THAT(
       std::move(Results).build(),
       ElementsAre(Pair(
@@ -299,9 +315,17 @@
                                         FileURI("unittest:///test.cc")),
                                   AllOf(RefRange(Test2Code.range("Foo")),
                                         FileURI("unittest:///test2.cc"))))));
+
+  Request.Limit = 1;
+  RefSlab::Builder Results2;
+  Merge.refs(Request, [&](const Ref &O) { Results2.insert(Foo.ID, O); });
+  EXPECT_THAT(std::move(Results2).build(),
+              ElementsAre(Pair(
+                  _, ElementsAre(AnyOf(FileURI("unittest:///test.cc"),
+                                       FileURI("unittest:///test2.cc"))))));
 }
 
-MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References,  "") {
+MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") {
   return (arg.IncludeHeader == IncludeHeader) && (arg.References == References);
 }
 
diff --git a/unittests/clangd/JSONTransportTests.cpp b/unittests/clangd/JSONTransportTests.cpp
index bc5a967..0498c81 100644
--- a/unittests/clangd/JSONTransportTests.cpp
+++ b/unittests/clangd/JSONTransportTests.cpp
@@ -1,32 +1,29 @@
 //===-- 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"
 #include "Transport.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include <stdio.h>
+#include <cstdio>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 // 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 {
   std::string InBuf, OutBuf, MirrorBuf;
-  raw_string_ostream Out, Mirror;
+  llvm::raw_string_ostream Out, Mirror;
   std::unique_ptr<FILE, int (*)(FILE *)> In;
 
 protected:
@@ -53,40 +50,43 @@
 class Echo : public Transport::MessageHandler {
   Transport &Target;
   std::string LogBuf;
-  raw_string_ostream Log;
+  llvm::raw_string_ostream Log;
 
 public:
   Echo(Transport &Target) : Target(Target), Log(LogBuf) {}
 
   std::string log() { return Log.str(); }
 
-  bool onNotify(StringRef Method, json::Value Params) override {
+  bool onNotify(llvm::StringRef Method, llvm::json::Value Params) override {
     Log << "Notification " << Method << ": " << Params << "\n";
     if (Method == "call")
       Target.call("echo call", std::move(Params), 42);
     return Method != "exit";
   }
 
-  bool onCall(StringRef Method, json::Value Params, json::Value ID) override {
+  bool onCall(llvm::StringRef Method, llvm::json::Value Params,
+              llvm::json::Value ID) override {
     Log << "Call " << Method << "(" << ID << "): " << Params << "\n";
     if (Method == "err")
-      Target.reply(ID, make_error<LSPError>("trouble at mill", ErrorCode(88)));
+      Target.reply(
+          ID, llvm::make_error<LSPError>("trouble at mill", ErrorCode(88)));
     else
       Target.reply(ID, std::move(Params));
     return true;
   }
 
-  bool onReply(json::Value ID, Expected<json::Value> Params) override {
+  bool onReply(llvm::json::Value ID,
+               llvm::Expected<llvm::json::Value> Params) override {
     if (Params)
       Log << "Reply(" << ID << "): " << *Params << "\n";
     else
-      Log << "Reply(" << ID << "): error = " << toString(Params.takeError())
-          << "\n";
+      Log << "Reply(" << ID
+          << "): error = " << llvm::toString(Params.takeError()) << "\n";
     return true;
   }
 };
 
-std::string trim(StringRef S) { return S.trim().str(); }
+std::string trim(llvm::StringRef S) { return S.trim().str(); }
 
 // Runs an Echo session using the standard JSON-RPC format we use in production.
 TEST_F(JSONTransportTest, StandardDense) {
diff --git a/unittests/clangd/Matchers.h b/unittests/clangd/Matchers.h
index d666de3..0ace970 100644
--- a/unittests/clangd/Matchers.h
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/unittests/clangd/QualityTests.cpp b/unittests/clangd/QualityTests.cpp
index f1a1fda..e2fe8f3 100644
--- a/unittests/clangd/QualityTests.cpp
+++ b/unittests/clangd/QualityTests.cpp
@@ -1,9 +1,8 @@
 //===-- SourceCodeTests.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,7 +29,6 @@
 #include "gtest/gtest.h"
 #include <vector>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -180,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?
@@ -253,7 +264,7 @@
 
   SymbolRelevanceSignals IndexProximate;
   IndexProximate.SymbolURI = "unittest:/foo/bar.h";
-  StringMap<SourceParams> ProxSources;
+  llvm::StringMap<SourceParams> ProxSources;
   ProxSources.try_emplace(testPath("foo/baz.h"));
   URIDistance Distance(ProxSources);
   IndexProximate.FileProximityMatch = &Distance;
@@ -266,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());
 
@@ -371,7 +382,7 @@
   Rel.merge(BarSym);
   EXPECT_TRUE(Rel.IsInstanceMember);
 
-  Rel.IsInstanceMember =false;
+  Rel.IsInstanceMember = false;
   const Symbol &TplSym = findSymbol(Symbols, "Foo::tpl");
   Rel.merge(TplSym);
   EXPECT_TRUE(Rel.IsInstanceMember);
@@ -429,7 +440,7 @@
   auto Header = TestTU::withHeaderCode(R"cpp(
     class Foo {
     public:
-      bool operator<(const Foo& f1, const Foo& f2);
+      bool operator<(const Foo& f1);
     };
   )cpp");
   auto AST = Header.build();
diff --git a/unittests/clangd/RIFFTests.cpp b/unittests/clangd/RIFFTests.cpp
index 6c5cebc..4cd54f4 100644
--- a/unittests/clangd/RIFFTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,7 +10,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -23,12 +21,12 @@
                       {riff::fourCC("even"), "abcd"},
                       {riff::fourCC("oddd"), "abcde"},
                   }};
-  StringRef Serialized = StringRef("RIFF\x1e\0\0\0test"
-                                   "even\x04\0\0\0abcd"
-                                   "oddd\x05\0\0\0abcde\0",
-                                   38);
+  llvm::StringRef Serialized = llvm::StringRef("RIFF\x1e\0\0\0test"
+                                               "even\x04\0\0\0abcd"
+                                               "oddd\x05\0\0\0abcde\0",
+                                               38);
 
-  EXPECT_EQ(to_string(File), Serialized);
+  EXPECT_EQ(llvm::to_string(File), Serialized);
   auto Parsed = riff::readFile(Serialized);
   ASSERT_TRUE(bool(Parsed)) << Parsed.takeError();
   EXPECT_EQ(*Parsed, File);
diff --git a/unittests/clangd/SelectionTests.cpp b/unittests/clangd/SelectionTests.cpp
new file mode 100644
index 0000000..2322a0e
--- /dev/null
+++ b/unittests/clangd/SelectionTests.cpp
@@ -0,0 +1,254 @@
+//===-- 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()) + 1)};
+}
+
+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",
+  };
+  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/unittests/clangd/SerializationTests.cpp
index a30369b..3260ac6 100644
--- a/unittests/clangd/SerializationTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,7 +19,6 @@
 using testing::UnorderedElementsAre;
 using testing::UnorderedElementsAreArray;
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -92,6 +90,10 @@
   return (arg.IncludeHeader == IncludeHeader) && (arg.References == References);
 }
 
+TEST(SerializationTest, NoCrashOnEmptyYAML) {
+  EXPECT_TRUE(bool(readIndexFile("")));
+}
+
 TEST(SerializationTest, YAMLConversions) {
   auto In = readIndexFile(YAML);
   EXPECT_TRUE(bool(In)) << In.takeError();
@@ -99,9 +101,9 @@
   auto ParsedYAML = readIndexFile(YAML);
   ASSERT_TRUE(bool(ParsedYAML)) << ParsedYAML.takeError();
   ASSERT_TRUE(bool(ParsedYAML->Symbols));
-  EXPECT_THAT(*ParsedYAML->Symbols,
-              UnorderedElementsAre(ID("057557CEBF6E6B2D"),
-                                   ID("057557CEBF6E6B2E")));
+  EXPECT_THAT(
+      *ParsedYAML->Symbols,
+      UnorderedElementsAre(ID("057557CEBF6E6B2D"), ID("057557CEBF6E6B2E")));
 
   auto Sym1 = *ParsedYAML->Symbols->find(
       cantFail(SymbolID::fromStr("057557CEBF6E6B2D")));
@@ -131,9 +133,8 @@
   ASSERT_TRUE(bool(ParsedYAML->Refs));
   EXPECT_THAT(
       *ParsedYAML->Refs,
-      UnorderedElementsAre(
-          Pair(cantFail(SymbolID::fromStr("057557CEBF6E6B2D")),
-               testing::SizeIs(1))));
+      UnorderedElementsAre(Pair(cantFail(SymbolID::fromStr("057557CEBF6E6B2D")),
+                                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");
@@ -159,7 +160,7 @@
   // Write to binary format, and parse again.
   IndexFileOut Out(*In);
   Out.Format = IndexFileFormat::RIFF;
-  std::string Serialized = to_string(Out);
+  std::string Serialized = llvm::to_string(Out);
 
   auto In2 = readIndexFile(Serialized);
   ASSERT_TRUE(bool(In2)) << In.takeError();
@@ -192,7 +193,7 @@
   Out.Format = IndexFileFormat::RIFF;
   Out.Sources = &Sources;
   {
-    std::string Serialized = to_string(Out);
+    std::string Serialized = llvm::to_string(Out);
 
     auto In = readIndexFile(Serialized);
     ASSERT_TRUE(bool(In)) << In.takeError();
diff --git a/unittests/clangd/SourceCodeTests.cpp b/unittests/clangd/SourceCodeTests.cpp
index 3148ccc..316a0d5 100644
--- a/unittests/clangd/SourceCodeTests.cpp
+++ b/unittests/clangd/SourceCodeTests.cpp
@@ -1,11 +1,11 @@
 //===-- SourceCodeTests.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"
 #include "SourceCode.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/raw_os_ostream.h"
@@ -13,11 +13,13 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
+using llvm::Failed;
+using llvm::HasValue;
+
 MATCHER_P2(Pos, Line, Col, "") {
   return arg.line == Line && arg.character == Col;
 }
@@ -54,63 +56,63 @@
 
 TEST(SourceCodeTests, PositionToOffset) {
   // line out of bounds
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(-1, 2)), llvm::Failed());
   // first line
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, -1)),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 0)),
-                       HasValue(0)); // first character
+                       llvm::HasValue(0)); // first character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 3)),
-                       HasValue(3)); // middle character
+                       llvm::HasValue(3)); // middle character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 6)),
-                       HasValue(6)); // last character
+                       llvm::HasValue(6)); // last character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7)),
-                       HasValue(7)); // the newline itself
+                       llvm::HasValue(7)); // the newline itself
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 7), false),
-                       HasValue(7));
+                       llvm::HasValue(7));
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8)),
-                       HasValue(7)); // out of range
+                       llvm::HasValue(7)); // out of range
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(0, 8), false),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   // middle line
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, -1)),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 0)),
-                       HasValue(8)); // first character
+                       llvm::HasValue(8)); // first character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3)),
-                       HasValue(11)); // middle character
+                       llvm::HasValue(11)); // middle character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 3), false),
-                       HasValue(11));
+                       llvm::HasValue(11));
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 6)),
-                       HasValue(16)); // last character
+                       llvm::HasValue(16)); // last character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 7)),
-                       HasValue(17)); // the newline itself
+                       llvm::HasValue(17)); // the newline itself
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8)),
-                       HasValue(17)); // out of range
+                       llvm::HasValue(17)); // out of range
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(1, 8), false),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   // last line
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, -1)),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 0)),
-                       HasValue(18)); // first character
+                       llvm::HasValue(18)); // first character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 3)),
-                       HasValue(21)); // middle character
+                       llvm::HasValue(21)); // middle character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5), false),
-                       Failed()); // middle of surrogate pair
+                       llvm::Failed()); // middle of surrogate pair
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 5)),
-                       HasValue(26)); // middle of surrogate pair
+                       llvm::HasValue(26)); // middle of surrogate pair
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 6), false),
-                       HasValue(26)); // end of surrogate pair
+                       llvm::HasValue(26)); // end of surrogate pair
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 8)),
-                       HasValue(28)); // last character
+                       llvm::HasValue(28)); // last character
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 9)),
-                       HasValue(29)); // EOF
+                       llvm::HasValue(29)); // EOF
   EXPECT_THAT_EXPECTED(positionToOffset(File, position(2, 10), false),
-                       Failed()); // out of range
+                       llvm::Failed()); // out of range
   // line out of bounds
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), Failed());
-  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 0)), llvm::Failed());
+  EXPECT_THAT_EXPECTED(positionToOffset(File, position(3, 1)), llvm::Failed());
 }
 
 TEST(SourceCodeTests, OffsetToPosition) {
@@ -135,11 +137,43 @@
 }
 
 TEST(SourceCodeTests, IsRangeConsecutive) {
-  EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4})));
+  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})));
+      isRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4})));
   EXPECT_FALSE(
-      IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5})));
+      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)));
+  }
 }
 
 } // namespace
diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp
index 952fcbe..258cfa9 100644
--- a/unittests/clangd/SymbolCollectorTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +26,6 @@
 #include <memory>
 #include <string>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -61,7 +59,7 @@
   return (arg.IncludeHeaders.size() == 1) &&
          (arg.IncludeHeaders.begin()->IncludeHeader == P);
 }
-MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References,  "") {
+MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") {
   return (arg.IncludeHeader == IncludeHeader) && (arg.References == References);
 }
 MATCHER_P(DeclRange, Pos, "") {
@@ -88,6 +86,9 @@
 MATCHER(ImplementationDetail, "") {
   return arg.Flags & Symbol::ImplementationDetail;
 }
+MATCHER(VisibleOutsideFile, "") {
+  return static_cast<bool>(arg.Flags & Symbol::VisibleOutsideFile);
+}
 MATCHER(RefRange, "") {
   const Ref &Pos = testing::get<0>(arg);
   const Range &Range = testing::get<1>(arg);
@@ -103,7 +104,7 @@
 
 class ShouldCollectSymbolTest : public ::testing::Test {
 public:
-  void build(StringRef HeaderCode, StringRef Code = "") {
+  void build(llvm::StringRef HeaderCode, llvm::StringRef Code = "") {
     File.HeaderFilename = HeaderName;
     File.Filename = FileName;
     File.HeaderCode = HeaderCode;
@@ -112,18 +113,22 @@
   }
 
   // build() must have been called.
-  bool shouldCollect(StringRef Name, bool Qualified = true) {
+  bool shouldCollect(llvm::StringRef Name, bool Qualified = true) {
     assert(AST.hasValue());
+    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()));
     return SymbolCollector::shouldCollectSymbol(
-        Qualified ? findDecl(*AST, Name) : findUnqualifiedDecl(*AST, Name),
-        AST->getASTContext(), SymbolCollector::Options());
+        ND, Ctx, SymbolCollector::Options(), MainFile);
   }
 
 protected:
   std::string HeaderName = "f.h";
   std::string FileName = "f.cpp";
   TestTU File;
-  Optional<ParsedAST> AST;  // Initialized after build.
+  llvm::Optional<ParsedAST> AST; // Initialized after build.
 };
 
 TEST_F(ShouldCollectSymbolTest, ShouldCollectSymbol) {
@@ -131,19 +136,23 @@
     namespace nx {
     class X{};
     auto f() { int Local; } // auto ensures function body is parsed.
-    struct { int x } var;
-    namespace { class InAnonymous {}; }
+    struct { int x; } var;
     }
   )",
-        "class InMain {};");
+        R"(
+    class InMain {};
+    namespace { class InAnonymous {}; }
+    static void g();
+  )");
   auto AST = File.build();
   EXPECT_TRUE(shouldCollect("nx"));
   EXPECT_TRUE(shouldCollect("nx::X"));
   EXPECT_TRUE(shouldCollect("nx::f"));
+  EXPECT_TRUE(shouldCollect("InMain"));
+  EXPECT_TRUE(shouldCollect("InAnonymous", /*Qualified=*/false));
+  EXPECT_TRUE(shouldCollect("g"));
 
-  EXPECT_FALSE(shouldCollect("InMain"));
   EXPECT_FALSE(shouldCollect("Local", /*Qualified=*/false));
-  EXPECT_FALSE(shouldCollect("InAnonymous", /*Qualified=*/false));
 }
 
 TEST_F(ShouldCollectSymbolTest, NoPrivateProtoSymbol) {
@@ -197,7 +206,7 @@
             PragmaHandler(PragmaHandler) {}
 
       std::unique_ptr<ASTConsumer>
-      CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
+      CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
         if (PragmaHandler)
           CI.getPreprocessor().addCommentHandler(PragmaHandler);
         return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
@@ -224,16 +233,16 @@
 class SymbolCollectorTest : public ::testing::Test {
 public:
   SymbolCollectorTest()
-      : InMemoryFileSystem(new vfs::InMemoryFileSystem),
+      : InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
         TestHeaderName(testPath("symbol.h")),
         TestFileName(testPath("symbol.cc")) {
     TestHeaderURI = URI::create(TestHeaderName).toString();
     TestFileURI = URI::create(TestFileName).toString();
   }
 
-  bool runSymbolCollector(StringRef HeaderCode, StringRef MainCode,
+  bool runSymbolCollector(llvm::StringRef HeaderCode, llvm::StringRef MainCode,
                           const std::vector<std::string> &ExtraArgs = {}) {
-    IntrusiveRefCntPtr<FileManager> Files(
+    llvm::IntrusiveRefCntPtr<FileManager> Files(
         new FileManager(FileSystemOptions(), InMemoryFileSystem));
 
     auto Factory = llvm::make_unique<SymbolIndexActionFactory>(
@@ -248,14 +257,13 @@
     Args.push_back(TestFileName);
 
     tooling::ToolInvocation Invocation(
-        Args,
-        Factory->create(), Files.get(),
+        Args, Factory->create(), Files.get(),
         std::make_shared<PCHContainerOperations>());
 
     InMemoryFileSystem->addFile(TestHeaderName, 0,
-                                MemoryBuffer::getMemBuffer(HeaderCode));
+                                llvm::MemoryBuffer::getMemBuffer(HeaderCode));
     InMemoryFileSystem->addFile(TestFileName, 0,
-                                MemoryBuffer::getMemBuffer(MainCode));
+                                llvm::MemoryBuffer::getMemBuffer(MainCode));
     Invocation.run();
     Symbols = Factory->Collector->takeSymbols();
     Refs = Factory->Collector->takeRefs();
@@ -263,7 +271,7 @@
   }
 
 protected:
-  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
+  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
   std::string TestHeaderName;
   std::string TestHeaderURI;
   std::string TestFileName;
@@ -349,6 +357,35 @@
                    AllOf(QName("foo::baz"), ForCodeCompletion(true))}));
 }
 
+TEST_F(SymbolCollectorTest, FileLocal) {
+  const std::string Header = R"(
+    class Foo {};
+    namespace {
+      class Ignored {};
+    }
+    void bar();
+  )";
+  const std::string Main = R"(
+    class ForwardDecl;
+    void bar() {}
+    static void a();
+    class B {};
+    namespace {
+      void c();
+    }
+  )";
+  runSymbolCollector(Header, Main);
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(
+                  AllOf(QName("Foo"), VisibleOutsideFile()),
+                  AllOf(QName("bar"), VisibleOutsideFile()),
+                  AllOf(QName("a"), Not(VisibleOutsideFile())),
+                  AllOf(QName("B"), Not(VisibleOutsideFile())),
+                  AllOf(QName("c"), Not(VisibleOutsideFile())),
+                  // FIXME: ForwardDecl likely *is* visible outside.
+                  AllOf(QName("ForwardDecl"), Not(VisibleOutsideFile()))));
+}
+
 TEST_F(SymbolCollectorTest, Template) {
   Annotations Header(R"(
     // Template is indexed, specialization and instantiation is not.
@@ -400,6 +437,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.
@@ -419,21 +473,20 @@
     void $printdef[[print]]() {}
 
     // Declared/defined in main only.
-    int Y;
+    int $ydecl[[Y]];
   )cpp");
   runSymbolCollector(Header.code(), Main.code());
-  EXPECT_THAT(
-      Symbols,
-      UnorderedElementsAre(
-          AllOf(QName("X"), DeclRange(Header.range("xdecl")),
-                DefRange(Main.range("xdef"))),
-          AllOf(QName("Cls"), DeclRange(Header.range("clsdecl")),
-                DefRange(Main.range("clsdef"))),
-          AllOf(QName("print"), DeclRange(Header.range("printdecl")),
-                DefRange(Main.range("printdef"))),
-          AllOf(QName("Z"), DeclRange(Header.range("zdecl"))),
-          AllOf(QName("foo"), DeclRange(Header.range("foodecl")))
-          ));
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(
+                  AllOf(QName("X"), DeclRange(Header.range("xdecl")),
+                        DefRange(Main.range("xdef"))),
+                  AllOf(QName("Cls"), DeclRange(Header.range("clsdecl")),
+                        DefRange(Main.range("clsdef"))),
+                  AllOf(QName("print"), DeclRange(Header.range("printdecl")),
+                        DefRange(Main.range("printdef"))),
+                  AllOf(QName("Z"), DeclRange(Header.range("zdecl"))),
+                  AllOf(QName("foo"), DeclRange(Header.range("foodecl"))),
+                  AllOf(QName("Y"), DeclRange(Main.range("ydecl")))));
 }
 
 TEST_F(SymbolCollectorTest, Refs) {
@@ -512,17 +565,25 @@
     W* w2 = nullptr; // only one usage counts
     X x();
     class V;
-    V* v = nullptr; // Used, but not eligible for indexing.
     class Y{}; // definition doesn't count as a reference
+    V* v = nullptr;
     GLOBAL_Z(z); // Not a reference to Z, we don't spell the type.
   )";
   CollectorOpts.CountReferences = true;
   runSymbolCollector(Header, Main);
   EXPECT_THAT(Symbols,
-              UnorderedElementsAre(AllOf(QName("W"), RefCount(1)),
-                                   AllOf(QName("X"), RefCount(1)),
-                                   AllOf(QName("Y"), RefCount(0)),
-                                   AllOf(QName("Z"), RefCount(0)), QName("y")));
+              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) {
@@ -537,8 +598,8 @@
   TestHeaderURI = URI::create(testPath(TestHeaderName)).toString();
   CollectorOpts.FallbackDir = testRoot();
   runSymbolCollector("class Foo {};", /*Main=*/"");
-  EXPECT_THAT(Symbols,
-              UnorderedElementsAre(AllOf(QName("Foo"), DeclURI(TestHeaderURI))));
+  EXPECT_THAT(Symbols, UnorderedElementsAre(
+                           AllOf(QName("Foo"), DeclURI(TestHeaderURI))));
 }
 
 TEST_F(SymbolCollectorTest, UnittestURIScheme) {
@@ -605,13 +666,12 @@
   )");
 
   runSymbolCollector(Header.code(), /*Main=*/"");
-  EXPECT_THAT(
-      Symbols,
-      UnorderedElementsAre(
-          AllOf(QName("abc_Test"), DeclRange(Header.range("expansion")),
-                DeclURI(TestHeaderURI)),
-          AllOf(QName("Test"), DeclRange(Header.range("spelling")),
-                DeclURI(TestHeaderURI))));
+  EXPECT_THAT(Symbols,
+              UnorderedElementsAre(
+                  AllOf(QName("abc_Test"), DeclRange(Header.range("expansion")),
+                        DeclURI(TestHeaderURI)),
+                  AllOf(QName("Test"), DeclRange(Header.range("spelling")),
+                        DeclURI(TestHeaderURI))));
 }
 
 TEST_F(SymbolCollectorTest, SymbolFormedByCLI) {
@@ -626,22 +686,28 @@
                            DeclURI(TestHeaderURI))));
 }
 
-TEST_F(SymbolCollectorTest, IgnoreSymbolsInMainFile) {
-  const std::string Header = R"(
+TEST_F(SymbolCollectorTest, SymbolsInMainFile) {
+  const std::string Main = R"(
     class Foo {};
     void f1();
     inline void f2() {}
-  )";
-  const std::string Main = R"(
+
     namespace {
-    void ff() {} // ignore
+    void ff() {}
     }
-    void main_f() {} // ignore
+    namespace foo {
+    namespace {
+    class Bar {};
+    }
+    }
+    void main_f() {}
     void f1() {}
   )";
-  runSymbolCollector(Header, Main);
+  runSymbolCollector(/*Header=*/"", Main);
   EXPECT_THAT(Symbols,
-              UnorderedElementsAre(QName("Foo"), QName("f1"), QName("f2")));
+              UnorderedElementsAre(QName("Foo"), QName("f1"), QName("f2"),
+                                   QName("ff"), QName("foo"), QName("foo::Bar"),
+                                   QName("main_f")));
 }
 
 TEST_F(SymbolCollectorTest, ClassMembers) {
@@ -659,10 +725,15 @@
     void Foo::ssf() {}
   )";
   runSymbolCollector(Header, Main);
-  EXPECT_THAT(Symbols,
-              UnorderedElementsAre(QName("Foo"), QName("Foo::f"),
-                                   QName("Foo::g"), QName("Foo::sf"),
-                                   QName("Foo::ssf"), QName("Foo::x")));
+  EXPECT_THAT(
+      Symbols,
+      UnorderedElementsAre(
+          QName("Foo"),
+          AllOf(QName("Foo::f"), ReturnType(""), ForCodeCompletion(false)),
+          AllOf(QName("Foo::g"), ReturnType(""), ForCodeCompletion(false)),
+          AllOf(QName("Foo::sf"), ReturnType(""), ForCodeCompletion(false)),
+          AllOf(QName("Foo::ssf"), ReturnType(""), ForCodeCompletion(false)),
+          AllOf(QName("Foo::x"), ReturnType(""), ForCodeCompletion(false))));
 }
 
 TEST_F(SymbolCollectorTest, Scopes) {
@@ -833,7 +904,7 @@
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
-                              MemoryBuffer::getMemBuffer("class X {};"));
+                              llvm::MemoryBuffer::getMemBuffer("class X {};"));
   runSymbolCollector("#include \"test.inc\"\nclass Y {};", /*Main=*/"",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols,
@@ -852,7 +923,7 @@
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
-                              MemoryBuffer::getMemBuffer("class X {};"));
+                              llvm::MemoryBuffer::getMemBuffer("class X {};"));
   runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
@@ -868,7 +939,7 @@
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
-                              MemoryBuffer::getMemBuffer("class X {};"));
+                              llvm::MemoryBuffer::getMemBuffer("class X {};"));
   runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
@@ -882,7 +953,7 @@
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
   InMemoryFileSystem->addFile(IncFile, 0,
-                              MemoryBuffer::getMemBuffer("class X {};"));
+                              llvm::MemoryBuffer::getMemBuffer("class X {};"));
   runSymbolCollector("", /*Main=*/"#include \"test.inc\"",
                      /*ExtraArgs=*/{"-I", testRoot()});
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), DeclURI(IncURI),
@@ -978,7 +1049,8 @@
   CollectorOpts.CountReferences = true;
   runSymbolCollector(Header, Main);
   EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(QName("X"), RefCount(1)),
-                                            AllOf(QName("Y"), RefCount(1))));
+                                            AllOf(QName("Y"), RefCount(1)),
+                                            AllOf(QName("C"), RefCount(0))));
 }
 
 TEST_F(SymbolCollectorTest, Origin) {
@@ -997,21 +1069,27 @@
 
     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"),
-                                   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) {
diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp
index 400a3aa..ed34c03 100644
--- a/unittests/clangd/SymbolInfoTests.cpp
+++ b/unittests/clangd/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"
@@ -21,7 +20,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -37,26 +35,24 @@
 TEST(SymbolInfoTests, All) {
   std::pair<const char *, std::vector<SymbolDetails>>
       TestInputExpectedOutput[] = {
-      {
-        R"cpp( // Simple function reference - declaration
+          {
+              R"cpp( // Simple function reference - declaration
           void foo();
           int bar() {
             fo^o();
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}
-      },
-      {
-        R"cpp( // Simple function reference - definition
+              {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
+          {
+              R"cpp( // Simple function reference - definition
           void foo() {}
           int bar() {
             fo^o();
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}
-      },
-      {
-        R"cpp( // Function in namespace reference
+              {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
+          {
+              R"cpp( // Function in namespace reference
           namespace bar {
             void foo();
             int baz() {
@@ -64,10 +60,9 @@
             }
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}
-      },
-      {
-        R"cpp( // Function in different namespace reference
+              {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
+          {
+              R"cpp( // Function in different namespace reference
           namespace bar {
             void foo();
           }
@@ -77,10 +72,9 @@
             }
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}
-      },
-      {
-        R"cpp( // Function in global namespace reference
+              {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#")}},
+          {
+              R"cpp( // Function in global namespace reference
           void foo();
           namespace Nbar {
             namespace Nbaz {
@@ -90,10 +84,9 @@
             }
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}
-      },
-      {
-        R"cpp( // Function in anonymous namespace reference
+              {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#")}},
+          {
+              R"cpp( // Function in anonymous namespace reference
           namespace {
             void foo();
           }
@@ -103,10 +96,10 @@
             }
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "(anonymous)", "c:TestTU.cpp@aN@F@foo#")}
-      },
-      {
-        R"cpp( // Function reference - ADL
+              {CreateExpectedSymbolDetails("foo", "(anonymous)",
+                                           "c:TestTU.cpp@aN@F@foo#")}},
+          {
+              R"cpp( // Function reference - ADL
           namespace bar {
             struct BarType {};
             void foo(const BarType&);
@@ -118,49 +111,53 @@
             }
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#")}
-      },
-      {
-        R"cpp( // Global value reference
+              {CreateExpectedSymbolDetails(
+                  "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#")}},
+          {
+              R"cpp( // Global value reference
           int value;
           void foo(int) { }
           void bar() {
             foo(val^ue);
           }
         )cpp",
-        {CreateExpectedSymbolDetails("value", "", "c:@value")}
-      },
-      {
-        R"cpp( // Local value reference
+              {CreateExpectedSymbolDetails("value", "", "c:@value")}},
+          {
+              R"cpp( // Local value reference
           void foo() { int aaa; int bbb = aa^a; }
         )cpp",
-        {CreateExpectedSymbolDetails("aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa")}
-      },
-      {
-        R"cpp( // Function param
+              {CreateExpectedSymbolDetails("aaa", "foo",
+                                           "c:TestTU.cpp@49@F@foo#@aaa")}},
+          {
+              R"cpp( // Function param
           void bar(int aaa) {
             int bbb = a^aa;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa")}
-      },
-      {
-        R"cpp( // Lambda capture
+              {CreateExpectedSymbolDetails("aaa", "bar",
+                                           "c:TestTU.cpp@38@F@bar#I#@aaa")}},
+          {
+              R"cpp( // Lambda capture
           int ii;
           auto lam = [ii]() {
             return i^i;
           };
         )cpp",
-        {CreateExpectedSymbolDetails("ii", "", "c:@ii")}
-      },
-      {
-        R"cpp( // Macro reference
+              {CreateExpectedSymbolDetails("ii", "", "c:@ii")}},
+          {
+              R"cpp( // Macro reference
           #define MACRO 5\nint i = MAC^RO;
         )cpp",
-        {CreateExpectedSymbolDetails("MACRO", "", "c:TestTU.cpp@55@macro@MACRO")}
-      },
-      {
-        R"cpp( // Multiple symbols returned - using overloaded function name
+              {CreateExpectedSymbolDetails("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() {}
           void foo(bool) {}
           void foo(int) {}
@@ -168,14 +165,11 @@
             using ::fo^o;
           }
         )cpp",
-        {
-          CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
-          CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
-          CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#")
-        }
-      },
-      {
-        R"cpp( // Multiple symbols returned - implicit conversion
+              {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"),
+               CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"),
+               CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#")}},
+          {
+              R"cpp( // Multiple symbols returned - implicit conversion
           struct foo {};
           struct bar {
             bar(const foo&) {}
@@ -186,53 +180,49 @@
             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#"),
-        }
-      },
-      {
-        R"cpp( // Type reference - declaration
+              {
+                  CreateExpectedSymbolDetails(
+                      "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff"),
+                  CreateExpectedSymbolDetails(
+                      "bar", "bar::", "c:@S@bar@F@bar#&1$@S@foo#"),
+              }},
+          {
+              R"cpp( // Type reference - declaration
           struct foo;
           void bar(fo^o*);
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}
-      },
-      {
-        R"cpp( // Type reference - definition
+              {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
+          {
+              R"cpp( // Type reference - definition
           struct foo {};
           void bar(fo^o*);
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}
-      },
-      {
-        R"cpp( // Type Reference - template argumen
+              {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
+          {
+              R"cpp( // Type Reference - template argumen
           struct foo {};
           template<class T> struct bar {};
           void baz() {
             bar<fo^o> b;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}
-      },
-      {
-        R"cpp( // Template parameter reference - type param
+              {CreateExpectedSymbolDetails("foo", "", "c:@S@foo")}},
+          {
+              R"cpp( // Template parameter reference - type param
           template<class TT> struct bar {
             T^T t;
           };
         )cpp",
-        { /* not implemented */ }
-      },
-      {
-        R"cpp( // Template parameter reference - type param
+              {/* not implemented */}},
+          {
+              R"cpp( // Template parameter reference - type param
           template<int NN> struct bar {
             int a = N^N;
           };
         )cpp",
-        { /* not implemented */ }
-      },
-      {
-        R"cpp( // Class member reference - objec
+              {/* not implemented */}},
+          {
+              R"cpp( // Class member reference - objec
           struct foo {
             int aa;
           };
@@ -241,10 +231,9 @@
             f.a^a;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}
-      },
-      {
-        R"cpp( // Class member reference - pointer
+              {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
+          {
+              R"cpp( // Class member reference - pointer
           struct foo {
             int aa;
           };
@@ -252,10 +241,9 @@
             &foo::a^a;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}
-      },
-      {
-        R"cpp( // Class method reference - objec
+              {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@FI@aa")}},
+          {
+              R"cpp( // Class method reference - objec
           struct foo {
             void aa() {}
           };
@@ -264,10 +252,9 @@
             f.a^a();
           }
         )cpp",
-        {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}
-      },
-      {
-        R"cpp( // Class method reference - pointer
+              {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
+          {
+              R"cpp( // Class method reference - pointer
           struct foo {
             void aa() {}
           };
@@ -275,72 +262,70 @@
             &foo::a^a;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}
-      },
-      {
-        R"cpp( // Typedef
+              {CreateExpectedSymbolDetails("aa", "foo::", "c:@S@foo@F@aa#")}},
+          {
+              R"cpp( // Typedef
           typedef int foo;
           void bar() {
             fo^o a;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@T@foo")}
-      },
-      {
-        R"cpp( // Type alias
+              {CreateExpectedSymbolDetails("foo", "", "c:TestTU.cpp@T@foo")}},
+          {
+              R"cpp( // Type alias
           using foo = int;
           void bar() {
             fo^o a;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@foo")}
-      },
-      {
-        R"cpp( // Namespace reference
+              {CreateExpectedSymbolDetails("foo", "", "c:@foo")}},
+          {
+              R"cpp( // Namespace reference
           namespace foo {}
           using namespace fo^o;
         )cpp",
-        {CreateExpectedSymbolDetails("foo", "", "c:@N@foo")}
-      },
-      {
-        R"cpp( // Enum value reference
+              {CreateExpectedSymbolDetails("foo", "", "c:@N@foo")}},
+          {
+              R"cpp( // Enum value reference
           enum foo { bar, baz };
           void f() {
             foo fff = ba^r;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("bar", "foo", "c:@E@foo@bar")}
-      },
-      {
-        R"cpp( // Enum class value reference
+              {CreateExpectedSymbolDetails("bar", "foo", "c:@E@foo@bar")}},
+          {
+              R"cpp( // Enum class value reference
           enum class foo { bar, baz };
           void f() {
             foo fff = foo::ba^r;
           }
         )cpp",
-        {CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}
-      },
-      {
-        R"cpp( // Type inferrence with auto keyword
+              {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{}; }
           void f() {
             au^to a = getfoo();
           }
         )cpp",
-        {/* not implemented */}
-      },
-      {
-        R"cpp( // decltype
+              {/* not implemented */}},
+          {
+              R"cpp( // decltype
           struct foo {};
           void f() {
             foo f;
             declt^ype(f);
           }
         )cpp",
-        {/* not implemented */}
-      },
-  };
+              {/* not implemented */}},
+      };
 
   for (const auto &T : TestInputExpectedOutput) {
     Annotations TestInput(T.first);
diff --git a/unittests/clangd/SyncAPI.cpp b/unittests/clangd/SyncAPI.cpp
index cebff42..91e7a91 100644
--- a/unittests/clangd/SyncAPI.cpp
+++ b/unittests/clangd/SyncAPI.cpp
@@ -1,21 +1,19 @@
 //===--- 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
 //
 //===----------------------------------------------------------------------===//
 
 #include "SyncAPI.h"
 #include "index/Index.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
-void runAddDocument(ClangdServer &Server, PathRef File, StringRef Contents,
-                    WantDiagnostics WantDiags) {
+void runAddDocument(ClangdServer &Server, PathRef File,
+                    llvm::StringRef Contents, WantDiagnostics WantDiags) {
   Server.addDocument(File, Contents, WantDiags);
   if (!Server.blockUntilIdleForTest())
     llvm_unreachable("not idle after addDocument");
@@ -27,7 +25,7 @@
 ///    T Result;
 ///    someAsyncFunc(Param1, Param2, /*Callback=*/capture(Result));
 template <typename T> struct CaptureProxy {
-  CaptureProxy(Optional<T> &Target) : Target(&Target) {
+  CaptureProxy(llvm::Optional<T> &Target) : Target(&Target) {
     assert(!Target.hasValue());
   }
 
@@ -39,7 +37,7 @@
   }
   CaptureProxy &operator=(CaptureProxy &&) = delete;
 
-  operator unique_function<void(T)>() && {
+  operator llvm::unique_function<void(T)>() && {
     assert(!Future.valid() && "conversion to callback called multiple times");
     Future = Promise.get_future();
     return Bind(
@@ -58,7 +56,7 @@
   }
 
 private:
-  Optional<T> *Target;
+  llvm::Optional<T> *Target;
   // Using shared_ptr to workaround compilation errors with MSVC.
   // MSVC only allows default-construcitble and copyable objects as future<>
   // arguments.
@@ -66,68 +64,69 @@
   std::future<std::shared_ptr<T>> Future;
 };
 
-template <typename T> CaptureProxy<T> capture(Optional<T> &Target) {
+template <typename T> CaptureProxy<T> capture(llvm::Optional<T> &Target) {
   return CaptureProxy<T>(Target);
 }
 } // namespace
 
-Expected<CodeCompleteResult> runCodeComplete(ClangdServer &Server, PathRef File,
-                                             Position Pos,
-                                             clangd::CodeCompleteOptions Opts) {
-  Optional<Expected<CodeCompleteResult>> Result;
+llvm::Expected<CodeCompleteResult>
+runCodeComplete(ClangdServer &Server, PathRef File, Position Pos,
+                clangd::CodeCompleteOptions Opts) {
+  llvm::Optional<llvm::Expected<CodeCompleteResult>> Result;
   Server.codeComplete(File, Pos, Opts, capture(Result));
   return std::move(*Result);
 }
 
-Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server, PathRef File,
-                                         Position Pos) {
-  Optional<Expected<SignatureHelp>> Result;
+llvm::Expected<SignatureHelp> runSignatureHelp(ClangdServer &Server,
+                                               PathRef File, Position Pos) {
+  llvm::Optional<llvm::Expected<SignatureHelp>> Result;
   Server.signatureHelp(File, Pos, capture(Result));
   return std::move(*Result);
 }
 
-Expected<std::vector<Location>> runFindDefinitions(ClangdServer &Server,
-                                                   PathRef File, Position Pos) {
-  Optional<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);
 }
 
-Expected<std::vector<DocumentHighlight>>
+llvm::Expected<std::vector<DocumentHighlight>>
 runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos) {
-  Optional<Expected<std::vector<DocumentHighlight>>> Result;
+  llvm::Optional<llvm::Expected<std::vector<DocumentHighlight>>> Result;
   Server.findDocumentHighlights(File, Pos, capture(Result));
   return std::move(*Result);
 }
 
-Expected<std::vector<tooling::Replacement>>
-runRename(ClangdServer &Server, PathRef File, Position Pos, StringRef NewName) {
-  Optional<Expected<std::vector<tooling::Replacement>>> 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;
   Server.rename(File, Pos, NewName, capture(Result));
   return std::move(*Result);
 }
 
 std::string runDumpAST(ClangdServer &Server, PathRef File) {
-  Optional<std::string> Result;
+  llvm::Optional<std::string> Result;
   Server.dumpAST(File, capture(Result));
   return std::move(*Result);
 }
 
-Expected<std::vector<SymbolInformation>>
-runWorkspaceSymbols(ClangdServer &Server, StringRef Query, int Limit) {
-  Optional<Expected<std::vector<SymbolInformation>>> Result;
+llvm::Expected<std::vector<SymbolInformation>>
+runWorkspaceSymbols(ClangdServer &Server, llvm::StringRef Query, int Limit) {
+  llvm::Optional<llvm::Expected<std::vector<SymbolInformation>>> Result;
   Server.workspaceSymbols(Query, Limit, capture(Result));
   return std::move(*Result);
 }
 
-Expected<std::vector<DocumentSymbol>> runDocumentSymbols(ClangdServer &Server,
-                                                         PathRef File) {
-  Optional<Expected<std::vector<DocumentSymbol>>> Result;
+llvm::Expected<std::vector<DocumentSymbol>>
+runDocumentSymbols(ClangdServer &Server, PathRef File) {
+  llvm::Optional<llvm::Expected<std::vector<DocumentSymbol>>> Result;
   Server.documentSymbols(File, capture(Result));
   return std::move(*Result);
 }
 
-SymbolSlab runFuzzyFind(const SymbolIndex &Index, StringRef Query) {
+SymbolSlab runFuzzyFind(const SymbolIndex &Index, llvm::StringRef Query) {
   FuzzyFindRequest Req;
   Req.Query = Query;
   Req.AnyScope = true;
@@ -148,6 +147,5 @@
   return std::move(Slab).build();
 }
 
-
 } // namespace clangd
 } // namespace clang
diff --git a/unittests/clangd/SyncAPI.h b/unittests/clangd/SyncAPI.h
index f336e61..8de9c05 100644
--- a/unittests/clangd/SyncAPI.h
+++ b/unittests/clangd/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,8 +32,8 @@
 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);
diff --git a/unittests/clangd/TUSchedulerTests.cpp b/unittests/clangd/TUSchedulerTests.cpp
index b26a7dd..6c71bf4 100644
--- a/unittests/clangd/TUSchedulerTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -12,13 +11,12 @@
 #include "Matchers.h"
 #include "TUScheduler.h"
 #include "TestFS.h"
-#include "gmock/gmock.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <algorithm>
 #include <utility>
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
@@ -28,7 +26,6 @@
 using ::testing::AnyOf;
 using ::testing::Each;
 using ::testing::ElementsAre;
-using ::testing::Pair;
 using ::testing::Pointee;
 using ::testing::UnorderedElementsAre;
 
@@ -39,12 +36,16 @@
 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, StringRef Contents,
-                          WantDiagnostics WD,
+  void updateWithCallback(TUScheduler &S, PathRef File,
+                          llvm::StringRef Contents, WantDiagnostics WD,
                           llvm::unique_function<void()> CB) {
     WithContextValue Ctx(llvm::make_scope_exit(std::move(CB)));
     S.update(File, getInputs(File, Contents), WD);
@@ -93,8 +94,8 @@
                            std::move(CB));
   }
 
-  StringMap<std::string> Files;
-  StringMap<time_t> Timestamps;
+  llvm::StringMap<std::string> Files;
+  llvm::StringMap<time_t> Timestamps;
   MockCompilationDatabase CDB;
 };
 
@@ -389,22 +390,20 @@
         }
         {
           WithContextValue WithNonce(NonceKey, ++Nonce);
-          S.runWithAST("CheckAST", File,
-                       [File, Inputs, Nonce, &Mut,
-                        &TotalASTReads](Expected<InputsAndAST> AST) {
-                         EXPECT_THAT(Context::current().get(NonceKey),
-                                     Pointee(Nonce));
+          S.runWithAST(
+              "CheckAST", File,
+              [File, Inputs, Nonce, &Mut,
+               &TotalASTReads](Expected<InputsAndAST> AST) {
+                EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce));
 
-                         ASSERT_TRUE((bool)AST);
-                         EXPECT_EQ(AST->Inputs.FS, Inputs.FS);
-                         EXPECT_EQ(AST->Inputs.Contents, Inputs.Contents);
+                ASSERT_TRUE((bool)AST);
+                EXPECT_EQ(AST->Inputs.FS, Inputs.FS);
+                EXPECT_EQ(AST->Inputs.Contents, Inputs.Contents);
 
-                         std::lock_guard<std::mutex> Lock(Mut);
-                         ++TotalASTReads;
-                         EXPECT_EQ(
-                             File,
-                             *TUScheduler::getFileBeingProcessedInContext());
-                       });
+                std::lock_guard<std::mutex> Lock(Mut);
+                ++TotalASTReads;
+                EXPECT_EQ(File, *TUScheduler::getFileBeingProcessedInContext());
+              });
         }
 
         {
@@ -505,14 +504,14 @@
   )cpp";
   auto WithEmptyPreamble = R"cpp(int main() {})cpp";
   S.update(Foo, getInputs(Foo, WithPreamble), WantDiagnostics::Auto);
-  S.runWithPreamble("getNonEmptyPreamble", Foo, TUScheduler::Stale,
-                    [&](Expected<InputsAndPreamble> Preamble) {
-                      // We expect to get a non-empty preamble.
-                      EXPECT_GT(cantFail(std::move(Preamble))
-                                    .Preamble->Preamble.getBounds()
-                                    .Size,
-                                0u);
-                    });
+  S.runWithPreamble(
+      "getNonEmptyPreamble", Foo, TUScheduler::Stale,
+      [&](Expected<InputsAndPreamble> Preamble) {
+        // We expect to get a non-empty preamble.
+        EXPECT_GT(
+            cantFail(std::move(Preamble)).Preamble->Preamble.getBounds().Size,
+            0u);
+      });
   // Wait for the preamble is being built.
   ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
 
@@ -520,14 +519,14 @@
   S.update(Foo, getInputs(Foo, WithEmptyPreamble), WantDiagnostics::Auto);
   // Wait for the preamble is being built.
   ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
-  S.runWithPreamble("getEmptyPreamble", Foo, TUScheduler::Stale,
-                    [&](Expected<InputsAndPreamble> Preamble) {
-                      // We expect to get an empty preamble.
-                      EXPECT_EQ(cantFail(std::move(Preamble))
-                                    .Preamble->Preamble.getBounds()
-                                    .Size,
-                                0u);
-                    });
+  S.runWithPreamble(
+      "getEmptyPreamble", Foo, TUScheduler::Stale,
+      [&](Expected<InputsAndPreamble> Preamble) {
+        // We expect to get an empty preamble.
+        EXPECT_EQ(
+            cantFail(std::move(Preamble)).Preamble->Preamble.getBounds().Size,
+            0u);
+      });
 }
 
 TEST_F(TUSchedulerTests, RunWaitsForPreamble) {
@@ -688,10 +687,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/unittests/clangd/TestFS.cpp
index 1c845b9..c5b2613 100644
--- a/unittests/clangd/TestFS.cpp
+++ b/unittests/clangd/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"
@@ -14,37 +13,36 @@
 
 namespace clang {
 namespace clangd {
-using namespace llvm;
 
-IntrusiveRefCntPtr<vfs::FileSystem>
-buildTestFS(StringMap<std::string> const &Files,
-            StringMap<time_t> const &Timestamps) {
-  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> MemFS(
-      new vfs::InMemoryFileSystem);
+llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+buildTestFS(llvm::StringMap<std::string> const &Files,
+            llvm::StringMap<time_t> const &Timestamps) {
+  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
+      new llvm::vfs::InMemoryFileSystem);
   MemFS->setCurrentWorkingDirectory(testRoot());
   for (auto &FileAndContents : Files) {
-    StringRef File = FileAndContents.first();
+    llvm::StringRef File = FileAndContents.first();
     MemFS->addFile(
         File, Timestamps.lookup(File),
-        MemoryBuffer::getMemBufferCopy(FileAndContents.second, File));
+        llvm::MemoryBuffer::getMemBufferCopy(FileAndContents.second, File));
   }
   return MemFS;
 }
 
-MockCompilationDatabase::MockCompilationDatabase(StringRef Directory,
-                                                 StringRef RelPathPrefix)
+MockCompilationDatabase::MockCompilationDatabase(llvm::StringRef Directory,
+                                                 llvm::StringRef RelPathPrefix)
     : ExtraClangFlags({"-ffreestanding"}), Directory(Directory),
       RelPathPrefix(RelPathPrefix) {
   // -ffreestanding avoids implicit stdc-predef.h.
 }
 
-Optional<tooling::CompileCommand>
+llvm::Optional<tooling::CompileCommand>
 MockCompilationDatabase::getCompileCommand(PathRef File,
                                            ProjectInfo *Project) const {
   if (ExtraClangFlags.empty())
     return None;
 
-  auto FileName = sys::path::filename(File);
+  auto FileName = llvm::sys::path::filename(File);
 
   // Build the compile command.
   auto CommandLine = ExtraClangFlags;
@@ -54,16 +52,17 @@
     CommandLine.push_back(File);
   } else {
     // Build a relative path using RelPathPrefix.
-    SmallString<32> RelativeFilePath(RelPathPrefix);
-    sys::path::append(RelativeFilePath, FileName);
+    llvm::SmallString<32> RelativeFilePath(RelPathPrefix);
+    llvm::sys::path::append(RelativeFilePath, FileName);
     CommandLine.push_back(RelativeFilePath.str());
   }
 
   if (Project)
     Project->SourceRoot = Directory;
-  return {tooling::CompileCommand(
-      Directory != StringRef() ? Directory : sys::path::parent_path(File),
-      FileName, std::move(CommandLine), "")};
+  return {tooling::CompileCommand(Directory != llvm::StringRef()
+                                      ? Directory
+                                      : llvm::sys::path::parent_path(File),
+                                  FileName, std::move(CommandLine), "")};
 }
 
 const char *testRoot() {
@@ -75,12 +74,12 @@
 }
 
 std::string testPath(PathRef File) {
-  assert(sys::path::is_relative(File) && "FileName should be relative");
+  assert(llvm::sys::path::is_relative(File) && "FileName should be relative");
 
-  SmallString<32> NativeFile = File;
-  sys::path::native(NativeFile);
-  SmallString<32> Path;
-  sys::path::append(Path, testRoot(), NativeFile);
+  llvm::SmallString<32> NativeFile = File;
+  llvm::sys::path::native(NativeFile);
+  llvm::SmallString<32> Path;
+  llvm::sys::path::append(Path, testRoot(), NativeFile);
   return Path.str();
 }
 
@@ -91,29 +90,32 @@
 public:
   static const char *Scheme;
 
-  Expected<std::string> getAbsolutePath(StringRef /*Authority*/, StringRef Body,
-                                        StringRef HintPath) const override {
+  llvm::Expected<std::string>
+  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+                  llvm::StringRef HintPath) const override {
     if (!HintPath.startswith(testRoot()))
-      return make_error<StringError>(
+      return llvm::make_error<llvm::StringError>(
           "Hint path doesn't start with test root: " + HintPath,
-          inconvertibleErrorCode());
+          llvm::inconvertibleErrorCode());
     if (!Body.consume_front("/"))
-      return make_error<StringError>(
+      return llvm::make_error<llvm::StringError>(
           "Body of an unittest: URI must start with '/'",
-          inconvertibleErrorCode());
-    SmallString<16> Path(Body.begin(), Body.end());
-    sys::path::native(Path);
+          llvm::inconvertibleErrorCode());
+    llvm::SmallString<16> Path(Body.begin(), Body.end());
+    llvm::sys::path::native(Path);
     return testPath(Path);
   }
 
-  Expected<URI> uriFromAbsolutePath(StringRef AbsolutePath) const override {
-    StringRef Body = AbsolutePath;
+  llvm::Expected<URI>
+  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
+    llvm::StringRef Body = AbsolutePath;
     if (!Body.consume_front(testRoot()))
-      return make_error<StringError>(AbsolutePath + "does not start with " +
-                                         testRoot(),
-                                     inconvertibleErrorCode());
+      return llvm::make_error<llvm::StringError>(
+          AbsolutePath + "does not start with " + testRoot(),
+          llvm::inconvertibleErrorCode());
 
-    return URI(Scheme, /*Authority=*/"", sys::path::convert_to_slash(Body));
+    return URI(Scheme, /*Authority=*/"",
+               llvm::sys::path::convert_to_slash(Body));
   }
 };
 
diff --git a/unittests/clangd/TestFS.h b/unittests/clangd/TestFS.h
index 0226fc3..eabdddf 100644
--- a/unittests/clangd/TestFS.h
+++ b/unittests/clangd/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/unittests/clangd/TestIndex.cpp b/unittests/clangd/TestIndex.cpp
index 2043f61..877bb75 100644
--- a/unittests/clangd/TestIndex.cpp
+++ b/unittests/clangd/TestIndex.cpp
@@ -1,23 +1,23 @@
 //===-- IndexHelpers.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 "TestIndex.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/Support/Regex.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
-Symbol symbol(StringRef QName) {
+Symbol symbol(llvm::StringRef QName) {
   Symbol Sym;
   Sym.ID = SymbolID(QName.str());
   size_t Pos = QName.rfind("::");
-  if (Pos == StringRef::npos) {
+  if (Pos == llvm::StringRef::npos) {
     Sym.Name = QName;
     Sym.Scope = "";
   } else {
@@ -27,9 +27,61 @@
   return Sym;
 }
 
+static 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;
+}
+
+// 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 (StringRef QName : QualifiedNames)
+  for (llvm::StringRef QName : QualifiedNames)
     Slab.insert(symbol(QName));
   return std::move(Slab).build();
 }
@@ -57,7 +109,8 @@
 }
 
 // Returns qualified names of symbols with any of IDs in the index.
-std::vector<std::string> lookup(const SymbolIndex &I, ArrayRef<SymbolID> IDs) {
+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;
diff --git a/unittests/clangd/TestIndex.h b/unittests/clangd/TestIndex.h
index 01dcc08..01de089 100644
--- a/unittests/clangd/TestIndex.h
+++ b/unittests/clangd/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/TestTU.cpp b/unittests/clangd/TestTU.cpp
index 4e14262..c2f0d89 100644
--- a/unittests/clangd/TestTU.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,7 +15,6 @@
 #include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Frontend/Utils.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -37,6 +35,11 @@
   Inputs.CompileCommand.Directory = testRoot();
   Inputs.Contents = Code;
   Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}});
+  Inputs.Opts = ParseOptions();
+  Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks;
+  Inputs.Index = ExternalIndex;
+  if (Inputs.Index)
+    Inputs.Opts.SuggestMissingIncludes = true;
   auto PCHs = std::make_shared<PCHContainerOperations>();
   auto CI = buildCompilerInvocation(Inputs);
   assert(CI && "Failed to build compilation invocation.");
@@ -56,18 +59,20 @@
 
 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);
 }
 
-const Symbol &findSymbol(const SymbolSlab &Slab, StringRef QName) {
+const Symbol &findSymbol(const SymbolSlab &Slab, llvm::StringRef QName) {
   const Symbol *Result = nullptr;
   for (const Symbol &S : Slab) {
     if (QName != (S.Scope + S.Name).str())
@@ -88,13 +93,13 @@
   return *Result;
 }
 
-const NamedDecl &findDecl(ParsedAST &AST, StringRef QName) {
-  SmallVector<StringRef, 4> Components;
+const NamedDecl &findDecl(ParsedAST &AST, llvm::StringRef QName) {
+  llvm::SmallVector<llvm::StringRef, 4> Components;
   QName.split(Components, "::");
 
   auto &Ctx = AST.getASTContext();
   auto LookupDecl = [&Ctx](const DeclContext &Scope,
-                           StringRef Name) -> const NamedDecl & {
+                           llvm::StringRef Name) -> const NamedDecl & {
     auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name)));
     assert(!LookupRes.empty() && "Lookup failed");
     assert(LookupRes.size() == 1 && "Lookup returned multiple results");
@@ -113,7 +118,7 @@
                           std::function<bool(const NamedDecl &)> Filter) {
   struct Visitor : RecursiveASTVisitor<Visitor> {
     decltype(Filter) F;
-    SmallVector<const NamedDecl *, 1> Decls;
+    llvm::SmallVector<const NamedDecl *, 1> Decls;
     bool VisitNamedDecl(const NamedDecl *ND) {
       if (F(*ND))
         Decls.push_back(ND);
@@ -129,7 +134,7 @@
   return *Visitor.Decls.front();
 }
 
-const NamedDecl &findUnqualifiedDecl(ParsedAST &AST, StringRef Name) {
+const NamedDecl &findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name) {
   return findDecl(AST, [Name](const NamedDecl &ND) {
     if (auto *ID = ND.getIdentifier())
       if (ID->getName() == Name)
diff --git a/unittests/clangd/TestTU.h b/unittests/clangd/TestTU.h
index ced612f..beed124 100644
--- a/unittests/clangd/TestTU.h
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 //
@@ -49,6 +48,10 @@
   // 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;
+
   ParsedAST build() const;
   SymbolSlab headerSymbols() const;
   std::unique_ptr<SymbolIndex> index() const;
diff --git a/unittests/clangd/ThreadingTests.cpp b/unittests/clangd/ThreadingTests.cpp
index dd27dcc..18b9146 100644
--- a/unittests/clangd/ThreadingTests.cpp
+++ b/unittests/clangd/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/unittests/clangd/TraceTests.cpp
index 0a2697f..1871e6a 100644
--- a/unittests/clangd/TraceTests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,32 +16,32 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 MATCHER_P(StringNode, Val, "") {
-  if (arg->getType() != yaml::Node::NK_Scalar) {
+  if (arg->getType() != llvm::yaml::Node::NK_Scalar) {
     *result_listener << "is a " << arg->getVerbatimTag();
     return false;
   }
-  SmallString<32> S;
-  return Val == static_cast<yaml::ScalarNode *>(arg)->getValue(S);
+  llvm::SmallString<32> S;
+  return Val == static_cast<llvm::yaml::ScalarNode *>(arg)->getValue(S);
 }
 
 // Checks that N is a Mapping (JS object) with the expected scalar properties.
 // The object must have all the Expected properties, but may have others.
-bool VerifyObject(yaml::Node &N, std::map<std::string, std::string> Expected) {
-  auto *M = dyn_cast<yaml::MappingNode>(&N);
+bool VerifyObject(llvm::yaml::Node &N,
+                  std::map<std::string, std::string> Expected) {
+  auto *M = llvm::dyn_cast<llvm::yaml::MappingNode>(&N);
   if (!M) {
     ADD_FAILURE() << "Not an object";
     return false;
   }
   bool Match = true;
-  SmallString<32> Tmp;
+  llvm::SmallString<32> Tmp;
   for (auto &Prop : *M) {
-    auto *K = dyn_cast_or_null<yaml::ScalarNode>(Prop.getKey());
+    auto *K = llvm::dyn_cast_or_null<llvm::yaml::ScalarNode>(Prop.getKey());
     if (!K)
       continue;
     std::string KS = K->getValue(Tmp).str();
@@ -50,7 +49,7 @@
     if (I == Expected.end())
       continue; // Ignore properties with no assertion.
 
-    auto *V = dyn_cast_or_null<yaml::ScalarNode>(Prop.getValue());
+    auto *V = llvm::dyn_cast_or_null<llvm::yaml::ScalarNode>(Prop.getValue());
     if (!V) {
       ADD_FAILURE() << KS << " is not a string";
       Match = false;
@@ -73,7 +72,7 @@
   // Capture some events.
   std::string JSON;
   {
-    raw_string_ostream OS(JSON);
+    llvm::raw_string_ostream OS(JSON);
     auto JSONTracer = trace::createJSONTracer(OS);
     trace::Session Session(*JSONTracer);
     {
@@ -83,15 +82,15 @@
   }
 
   // Get the root JSON object using the YAML parser.
-  SourceMgr SM;
-  yaml::Stream Stream(JSON, SM);
+  llvm::SourceMgr SM;
+  llvm::yaml::Stream Stream(JSON, SM);
   auto Doc = Stream.begin();
   ASSERT_NE(Doc, Stream.end());
-  auto *Root = dyn_cast_or_null<yaml::MappingNode>(Doc->getRoot());
+  auto *Root = llvm::dyn_cast_or_null<llvm::yaml::MappingNode>(Doc->getRoot());
   ASSERT_NE(Root, nullptr) << "Root should be an object";
 
   // Check whether we expect thread name events on this platform.
-  SmallString<32> ThreadName;
+  llvm::SmallString<32> ThreadName;
   get_thread_name(ThreadName);
   bool ThreadsHaveNames = !ThreadName.empty();
 
@@ -105,7 +104,8 @@
   EXPECT_THAT(Prop->getValue(), StringNode("ns"));
   ASSERT_NE(++Prop, Root->end()) << "Expected traceEvents property";
   EXPECT_THAT(Prop->getKey(), StringNode("traceEvents"));
-  auto *Events = dyn_cast_or_null<yaml::SequenceNode>(Prop->getValue());
+  auto *Events =
+      llvm::dyn_cast_or_null<llvm::yaml::SequenceNode>(Prop->getValue());
   ASSERT_NE(Events, nullptr) << "traceEvents should be an array";
   auto Event = Events->begin();
   ASSERT_NE(Event, Events->end()) << "Expected process name";
diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp
new file mode 100644
index 0000000..baa6029
--- /dev/null
+++ b/unittests/clangd/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/unittests/clangd/URITests.cpp b/unittests/clangd/URITests.cpp
index 302affd..52ca7b4 100644
--- a/unittests/clangd/URITests.cpp
+++ b/unittests/clangd/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
 //
 //===----------------------------------------------------------------------===//
 
@@ -13,7 +12,6 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 
@@ -29,14 +27,15 @@
 MATCHER_P(Authority, A, "") { return arg.authority() == A; }
 MATCHER_P(Body, B, "") { return arg.body() == B; }
 
-std::string createOrDie(StringRef AbsolutePath, StringRef Scheme = "file") {
+std::string createOrDie(llvm::StringRef AbsolutePath,
+                        llvm::StringRef Scheme = "file") {
   auto Uri = URI::create(AbsolutePath, Scheme);
   if (!Uri)
     llvm_unreachable(toString(Uri.takeError()).c_str());
   return Uri->toString();
 }
 
-URI parseOrDie(StringRef Uri) {
+URI parseOrDie(llvm::StringRef Uri) {
   auto U = URI::parse(Uri);
   if (!U)
     llvm_unreachable(toString(U.takeError()).c_str());
@@ -61,7 +60,7 @@
   EXPECT_EQ(parseOrDie("x:a:b%3bc").body(), "a:b;c");
 }
 
-std::string resolveOrDie(const URI &U, StringRef HintPath = "") {
+std::string resolveOrDie(const URI &U, llvm::StringRef HintPath = "") {
   auto Path = URI::resolve(U, HintPath);
   if (!Path)
     llvm_unreachable(toString(Path.takeError()).c_str());
@@ -137,7 +136,8 @@
             testPath("a"));
 }
 
-std::string resolvePathOrDie(StringRef AbsPath, StringRef HintPath = "") {
+std::string resolvePathOrDie(llvm::StringRef AbsPath,
+                             llvm::StringRef HintPath = "") {
   auto Path = URI::resolvePath(AbsPath, HintPath);
   if (!Path)
     llvm_unreachable(toString(Path.takeError()).c_str());
diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp
index ffb0d05..fea9013 100644
--- a/unittests/clangd/XRefsTests.cpp
+++ b/unittests/clangd/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,16 +17,15 @@
 #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"
 
-using namespace llvm;
 namespace clang {
 namespace clangd {
 namespace {
 
 using testing::ElementsAre;
-using testing::Field;
 using testing::IsEmpty;
 using testing::Matcher;
 using testing::UnorderedElementsAreArray;
@@ -88,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);
@@ -97,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]] {};
@@ -117,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.
@@ -128,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]]() {}
@@ -138,29 +165,50 @@
           ^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 $[[Proto]] {};
+      )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]];
+        P^roto* create();
+      )cpp");
+
+  auto AST = TestTU::withCode(Test.code()).build();
+  auto Locs = clangd::locateSymbolAt(AST, Test.point(), Index.get());
+  EXPECT_THAT(Locs, ElementsAre(Sym("Proto", SymbolHeader.range())));
+}
+
+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 +235,7 @@
       )cpp",
 
       R"cpp(// Function declaration via call
-        int [[foo]](int);
+        int $decl[[foo]](int);
         int main() {
           return ^foo(42);
         }
@@ -223,7 +271,7 @@
       )cpp",
 
       R"cpp(// Method call
-        struct Foo { int [[x]](); };
+        struct Foo { int $decl[[x]](); };
         int main() {
           Foo bar;
           bar.^x();
@@ -231,7 +279,7 @@
       )cpp",
 
       R"cpp(// Typedef
-        typedef int [[Foo]];
+        typedef int $decl[[Foo]];
         int main() {
           ^Foo bar;
         }
@@ -244,7 +292,7 @@
       )cpp", */
 
       R"cpp(// Namespace
-        namespace [[ns]] {
+        namespace $decl[[ns]] {
         struct Foo { static void bar(); }
         } // namespace ns
         int main() { ^ns::Foo::bar(); }
@@ -305,30 +353,45 @@
   };
   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();
@@ -337,26 +400,20 @@
     }
   )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"), Sym("Foo")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("3")),
+              ElementsAre(Sym("f"), Sym("Foo")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("5")),
+              ElementsAre(Sym("f"), Sym("Foo")));
+  EXPECT_THAT(locateSymbolAt(AST, T.point("6")),
+              ElementsAre(Sym("str"), Sym("Foo"), Sym("Foo")));
 }
 
-TEST(GoToDefinition, RelPathsInCompileCommand) {
+TEST(LocateSymbol, RelPathsInCompileCommand) {
   // The source is in "/clangd-test/src".
   // We build in "/clangd-test/build".
 
@@ -378,7 +435,7 @@
   // Make the compilation paths appear as ../src/foo.cpp in the compile
   // commands.
   SmallString<32> RelPathPrefix("..");
-  sys::path::append(RelPathPrefix, "src");
+  llvm::sys::path::append(RelPathPrefix, "src");
   std::string BuildDir = testPath("build");
   MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
 
@@ -398,24 +455,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) {
@@ -1062,46 +1118,39 @@
   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())));
 }
 
-TEST(GoToDefinition, WithPreamble) {
+TEST(LocateSymbol, WithPreamble) {
   // Test stragety: AST should always use the latest preamble instead of last
   // good preamble.
   MockFSProvider FS;
@@ -1121,18 +1170,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 +1189,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) {
@@ -1219,7 +1268,7 @@
     std::vector<Matcher<Location>> ExpectedLocations;
     for (const auto &R : T.ranges())
       ExpectedLocations.push_back(RangeIs(R));
-    EXPECT_THAT(findReferences(AST, T.point()),
+    EXPECT_THAT(findReferences(AST, T.point(), 0),
                 ElementsAreArray(ExpectedLocations))
         << Test;
   }
@@ -1266,7 +1315,7 @@
     std::vector<Matcher<Location>> ExpectedLocations;
     for (const auto &R : T.ranges())
       ExpectedLocations.push_back(RangeIs(R));
-    EXPECT_THAT(findReferences(AST, T.point()),
+    EXPECT_THAT(findReferences(AST, T.point(), 0),
                 ElementsAreArray(ExpectedLocations))
         << Test;
   }
@@ -1281,7 +1330,7 @@
   auto AST = TU.build();
 
   // References in main file are returned without index.
-  EXPECT_THAT(findReferences(AST, Main.point(), /*Index=*/nullptr),
+  EXPECT_THAT(findReferences(AST, Main.point(), 0, /*Index=*/nullptr),
               ElementsAre(RangeIs(Main.range())));
   Annotations IndexedMain(R"cpp(
     int main() { [[f^oo]](); }
@@ -1292,21 +1341,25 @@
   IndexedTU.Code = IndexedMain.code();
   IndexedTU.Filename = "Indexed.cpp";
   IndexedTU.HeaderCode = Header;
-  EXPECT_THAT(findReferences(AST, Main.point(), IndexedTU.index().get()),
+  EXPECT_THAT(findReferences(AST, Main.point(), 0, IndexedTU.index().get()),
               ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
 
+  EXPECT_EQ(1u, findReferences(AST, Main.point(), /*Limit*/ 1,
+                               IndexedTU.index().get())
+                    .size());
+
   // If the main file is in the index, we don't return duplicates.
   // (even if the references are in a different location)
   TU.Code = ("\n\n" + Main.code()).str();
-  EXPECT_THAT(findReferences(AST, Main.point(), TU.index().get()),
+  EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()),
               ElementsAre(RangeIs(Main.range())));
 }
 
 TEST(FindReferences, NoQueryForLocalSymbols) {
   struct RecordingIndex : public MemIndex {
-    mutable Optional<DenseSet<SymbolID>> RefIDs;
+    mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
     void refs(const RefsRequest &Req,
-              function_ref<void(const Ref &)>) const override {
+              llvm::function_ref<void(const Ref &)>) const override {
       RefIDs = Req.IDs;
     }
   };
@@ -1328,7 +1381,7 @@
     Annotations File(T.AnnotatedCode);
     RecordingIndex Rec;
     auto AST = TestTU::withCode(File.code()).build();
-    findReferences(AST, File.point(), &Rec);
+    findReferences(AST, File.point(), 0, &Rec);
     if (T.WantQuery)
       EXPECT_NE(Rec.RefIDs, None) << T.AnnotatedCode;
     else
diff --git a/unittests/clangd/xpc/CMakeLists.txt b/unittests/clangd/xpc/CMakeLists.txt
new file mode 100644
index 0000000..229ad5a
--- /dev/null
+++ b/unittests/clangd/xpc/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_LINK_COMPONENTS
+  support
+  )
+
+get_filename_component(CLANGD_SOURCE_DIR
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../clangd REALPATH)
+include_directories(
+  ${CLANGD_SOURCE_DIR}
+  )
+
+add_extra_unittest(ClangdXpcTests
+  ConversionTests.cpp
+  )
+
+target_link_libraries(ClangdXpcTests
+  PRIVATE
+  clangdXpcJsonConversions
+  clangDaemon
+  LLVMSupport
+  LLVMTestingSupport
+  )
diff --git a/unittests/clangd/xpc/ConversionTests.cpp b/unittests/clangd/xpc/ConversionTests.cpp
new file mode 100644
index 0000000..5d0efd8
--- /dev/null
+++ b/unittests/clangd/xpc/ConversionTests.cpp
@@ -0,0 +1,35 @@
+//===-- ConversionTests.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 "gtest/gtest.h"
+
+#include <limits>
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using namespace llvm;
+
+TEST(JsonXpcConversionTest, JsonToXpcToJson) {
+
+  for (auto &testcase :
+       {json::Value(false), json::Value(3.14), json::Value(42),
+        json::Value(-100), json::Value("foo"), json::Value(""),
+        json::Value("123"), json::Value(" "),
+        json::Value{true, "foo", nullptr, 42},
+        json::Value(json::Object{
+            {"a", true}, {"b", "foo"}, {"c", nullptr}, {"d", 42}})}) {
+    EXPECT_TRUE(testcase == xpcToJson(jsonToXpc(testcase))) << testcase;
+  }
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang
diff --git a/unittests/include-fixer/FuzzySymbolIndexTests.cpp b/unittests/include-fixer/FuzzySymbolIndexTests.cpp
index 17679c5..3886269 100644
--- a/unittests/include-fixer/FuzzySymbolIndexTests.cpp
+++ b/unittests/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/include-fixer/IncludeFixerTest.cpp
index 519c083..9b18748 100644
--- a/unittests/include-fixer/IncludeFixerTest.cpp
+++ b/unittests/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
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp b/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
index 1ad9e7f..179ad25 100644
--- a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
+++ b/unittests/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/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
 //
 //===----------------------------------------------------------------------===//
 ///