https://github.com/aengelke updated 
https://github.com/llvm/llvm-project/pull/173868

>From 937009a76c6af9799ccbf89d7d8a07dbb4917f86 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 10:15:51 +0000
Subject: [PATCH 1/7] [LLD][MachO] Avoid ambiguity between lld::Reloc and
 llvm::Reloc

---
 lld/MachO/EhFrame.cpp           | 15 +++++------
 lld/MachO/ICF.cpp               | 18 ++++++-------
 lld/MachO/InputSection.cpp      | 15 +++++------
 lld/MachO/ObjC.cpp              | 46 +++++++++++++++++----------------
 lld/MachO/Relocations.cpp       |  1 -
 lld/MachO/UnwindInfoSection.cpp | 19 +++++++-------
 6 files changed, 56 insertions(+), 58 deletions(-)

diff --git a/lld/MachO/EhFrame.cpp b/lld/MachO/EhFrame.cpp
index 2446b49b5098a..e6b473475c1fe 100644
--- a/lld/MachO/EhFrame.cpp
+++ b/lld/MachO/EhFrame.cpp
@@ -13,7 +13,6 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/Support/Endian.h"
 
-using namespace llvm;
 using namespace lld;
 using namespace lld::macho;
 using namespace llvm::support::endian;
@@ -24,7 +23,7 @@ uint64_t EhReader::readLength(size_t *off) const {
     failOn(errOff, "CIE/FDE too small");
   uint64_t len = read32le(data.data() + *off);
   *off += 4;
-  if (len == dwarf::DW_LENGTH_DWARF64) {
+  if (len == llvm::dwarf::DW_LENGTH_DWARF64) {
     // FIXME: test this DWARF64 code path
     if (*off + 8 > data.size())
       failOn(errOff, "CIE/FDE too small");
@@ -39,7 +38,7 @@ uint64_t EhReader::readLength(size_t *off) const {
 void EhReader::skipValidLength(size_t *off) const {
   uint32_t len = read32le(data.data() + *off);
   *off += 4;
-  if (len == dwarf::DW_LENGTH_DWARF64)
+  if (len == llvm::dwarf::DW_LENGTH_DWARF64)
     *off += 8;
 }
 
@@ -106,10 +105,10 @@ void EhReader::failOn(size_t errOff, const Twine &msg) 
const {
  *   `(a + offset) - b` if Invert == true
  */
 template <bool Invert = false>
-static void createSubtraction(PointerUnion<Symbol *, InputSection *> a,
-                              PointerUnion<Symbol *, InputSection *> b,
+static void createSubtraction(llvm::PointerUnion<Symbol *, InputSection *> a,
+                              llvm::PointerUnion<Symbol *, InputSection *> b,
                               uint64_t off, uint8_t length,
-                              SmallVectorImpl<Reloc> *newRelocs) {
+                              llvm::SmallVectorImpl<Reloc> *newRelocs) {
   auto subtrahend = a;
   auto minuend = b;
   if (Invert)
@@ -124,13 +123,13 @@ static void createSubtraction(PointerUnion<Symbol *, 
InputSection *> a,
 }
 
 void EhRelocator::makePcRel(uint64_t off,
-                            PointerUnion<Symbol *, InputSection *> target,
+                            llvm::PointerUnion<Symbol *, InputSection *> 
target,
                             uint8_t length) {
   createSubtraction(isec->symbols[0], target, off, length, &newRelocs);
 }
 
 void EhRelocator::makeNegativePcRel(
-    uint64_t off, PointerUnion<Symbol *, InputSection *> target,
+    uint64_t off, llvm::PointerUnion<Symbol *, InputSection *> target,
     uint8_t length) {
   createSubtraction</*Invert=*/true>(isec, target, off, length, &newRelocs);
 }
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index e0fc89782a419..aae5dfa1b03a4 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -20,7 +20,6 @@
 
 #include <atomic>
 
-using namespace llvm;
 using namespace lld;
 using namespace lld::macho;
 
@@ -374,10 +373,10 @@ void ICF::forEachClass(llvm::function_ref<void(size_t, 
size_t)> func) {
   size_t boundaries[shards + 1];
   boundaries[0] = 0;
   boundaries[shards] = icfInputs.size();
-  parallelFor(1, shards, [&](size_t i) {
+  llvm::parallelFor(1, shards, [&](size_t i) {
     boundaries[i] = findBoundary((i - 1) * step, icfInputs.size());
   });
-  parallelFor(1, shards + 1, [&](size_t i) {
+  llvm::parallelFor(1, shards + 1, [&](size_t i) {
     if (boundaries[i - 1] < boundaries[i]) {
       forEachClassRange(boundaries[i - 1], boundaries[i], func);
     }
@@ -388,7 +387,7 @@ void ICF::forEachClass(llvm::function_ref<void(size_t, 
size_t)> func) {
 void ICF::run() {
   // Into each origin-section hash, combine all reloc referent section hashes.
   for (icfPass = 0; icfPass < 2; ++icfPass) {
-    parallelForEach(icfInputs, [&](ConcatInputSection *isec) {
+    llvm::parallelForEach(icfInputs, [&](ConcatInputSection *isec) {
       uint32_t hash = isec->icfEqClass[icfPass % 2];
       for (const Reloc &r : isec->relocs) {
         if (auto *sym = r.referent.dyn_cast<Symbol *>()) {
@@ -507,7 +506,7 @@ void macho::markSymAsAddrSig(Symbol *s) {
 }
 
 void macho::markAddrSigSymbols() {
-  TimeTraceScope timeScope("Mark addrsig symbols");
+  llvm::TimeTraceScope timeScope("Mark addrsig symbols");
   for (InputFile *file : inputFiles) {
     ObjFile *obj = dyn_cast<ObjFile>(file);
     if (!obj)
@@ -550,7 +549,7 @@ Defined *macho::getBodyForThunkFoldedSym(Defined 
*foldedSym) {
   return cast<Defined>(targetSym);
 }
 void macho::foldIdenticalSections(bool onlyCfStrings) {
-  TimeTraceScope timeScope("Fold Identical Code Sections");
+  llvm::TimeTraceScope timeScope("Fold Identical Code Sections");
   // The ICF equivalence-class segregation algorithm relies on pre-computed
   // hashes of InputSection::data for the ConcatOutputSection::inputs and all
   // sections referenced by their relocs. We could recursively traverse the
@@ -575,8 +574,9 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
                                         isSelRefsSection(isec);
     // NOTE: __objc_selrefs is typically marked as no_dead_strip by MC, but we
     // can still fold it.
-    bool hasFoldableFlags = (isSelRefsSection(isec) ||
-                             sectionType(isec->getFlags()) == 
MachO::S_REGULAR);
+    bool hasFoldableFlags =
+        (isSelRefsSection(isec) ||
+         sectionType(isec->getFlags()) == llvm::MachO::S_REGULAR);
 
     bool isCodeSec = isCodeSection(isec);
 
@@ -620,7 +620,7 @@ void macho::foldIdenticalSections(bool onlyCfStrings) {
       isec->icfEqClass[0] = ++icfUniqueID;
     }
   }
-  parallelForEach(foldable, [](ConcatInputSection *isec) {
+  llvm::parallelForEach(foldable, [](ConcatInputSection *isec) {
     assert(isec->icfEqClass[0] == 0); // don't overwrite a unique ID!
     // Turn-on the top bit to guarantee that valid hashes have no collisions
     // with the small-integer unique IDs for ICF-ineligible sections
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index 2b2d28ef63e2d..81ec37ace93d2 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -21,7 +21,6 @@
 #include "lld/Common/Memory.h"
 #include "llvm/Support/xxhash.h"
 
-using namespace llvm;
 using namespace llvm::MachO;
 using namespace llvm::support;
 using namespace lld;
@@ -146,7 +145,7 @@ std::string InputSection::getSourceLocation(uint64_t off) 
const {
   }
 
   auto createMsg = [&](StringRef path, unsigned line) {
-    std::string filename = sys::path::filename(path).str();
+    std::string filename = llvm::sys::path::filename(path).str();
     std::string lineStr = (":" + Twine(line)).str();
     if (filename == path)
       return filename + lineStr;
@@ -154,8 +153,8 @@ std::string InputSection::getSourceLocation(uint64_t off) 
const {
   };
 
   // First, look up a function for a given offset.
-  if (std::optional<DILineInfo> li = dwarf->getDILineInfo(
-          section.addr + off, object::SectionedAddress::UndefSection))
+  if (std::optional<llvm::DILineInfo> li = dwarf->getDILineInfo(
+          section.addr + off, llvm::object::SectionedAddress::UndefSection))
     return createMsg(li->FileName, li->Line);
 
   // If it failed, look up again as a variable.
@@ -302,8 +301,8 @@ StringPiece &CStringInputSection::getStringPiece(uint64_t 
off) {
   if (off >= data.size())
     fatal(toString(this) + ": offset is outside the section");
 
-  auto it =
-      partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; 
});
+  auto it = llvm::partition_point(
+      pieces, [=](StringPiece p) { return p.inSecOff <= off; });
   return it[-1];
 }
 
@@ -315,8 +314,8 @@ size_t CStringInputSection::getStringPieceIndex(uint64_t 
off) const {
   if (off >= data.size())
     fatal(toString(this) + ": offset is outside the section");
 
-  auto it =
-      partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; 
});
+  auto it = llvm::partition_point(
+      pieces, [=](StringPiece p) { return p.inSecOff <= off; });
   return std::distance(pieces.begin(), it) - 1;
 }
 
diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index ab7f73c3a1df6..3ac27279905a7 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -17,10 +17,10 @@
 
 #include "lld/Common/ErrorHandler.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Support/TimeProfiler.h"
 
-using namespace llvm;
 using namespace llvm::MachO;
 using namespace lld;
 using namespace lld::macho;
@@ -38,10 +38,11 @@ template <class LP> static bool 
objectHasObjCSection(MemoryBufferRef mb) {
     auto sectionHeaders = ArrayRef<SectionHeader>{
         reinterpret_cast<const SectionHeader *>(c + 1), c->nsects};
     for (const SectionHeader &secHead : sectionHeaders) {
-      StringRef sectname(secHead.sectname,
-                         strnlen(secHead.sectname, sizeof(secHead.sectname)));
-      StringRef segname(secHead.segname,
-                        strnlen(secHead.segname, sizeof(secHead.segname)));
+      llvm::StringRef sectname(
+          secHead.sectname,
+          strnlen(secHead.sectname, sizeof(secHead.sectname)));
+      llvm::StringRef segname(
+          secHead.segname, strnlen(secHead.segname, sizeof(secHead.segname)));
       if ((segname == segment_names::data &&
            sectname == section_names::objcCatList) ||
           (segname == segment_names::text &&
@@ -62,9 +63,9 @@ static bool objectHasObjCSection(MemoryBufferRef mb) {
 
 bool macho::hasObjCSection(MemoryBufferRef mb) {
   switch (identify_magic(mb.getBuffer())) {
-  case file_magic::macho_object:
+  case llvm::file_magic::macho_object:
     return objectHasObjCSection(mb);
-  case file_magic::bitcode:
+  case llvm::file_magic::bitcode:
     return check(isBitcodeContainingObjCCategory(mb));
   default:
     return false;
@@ -153,8 +154,8 @@ enum MethodKind {
 };
 
 struct ObjcClass {
-  DenseMap<CachedHashStringRef, MethodContainer> instanceMethods;
-  DenseMap<CachedHashStringRef, MethodContainer> classMethods;
+  llvm::DenseMap<llvm::CachedHashStringRef, MethodContainer> instanceMethods;
+  llvm::DenseMap<llvm::CachedHashStringRef, MethodContainer> classMethods;
 };
 
 } // namespace
@@ -177,7 +178,7 @@ class ObjcCategoryChecker {
   ListHeaderLayout listHeaderLayout;
   MethodLayout methodLayout;
 
-  DenseMap<const Symbol *, ObjcClass> classMap;
+  llvm::DenseMap<const Symbol *, ObjcClass> classMap;
 };
 
 ObjcCategoryChecker::ObjcCategoryChecker()
@@ -196,7 +197,7 @@ void ObjcCategoryChecker::parseMethods(const 
ConcatInputSection *methodsIsec,
         methodLayout.nameOffset)
       continue;
 
-    CachedHashStringRef methodName(r.getReferentString());
+    llvm::CachedHashStringRef methodName(r.getReferentString());
     // +load methods are special: all implementations are called by the runtime
     // even if they are part of the same class. Thus there is no need to check
     // for duplicates.
@@ -311,7 +312,7 @@ void ObjcCategoryChecker::parseClass(const Defined 
*classSym) {
 }
 
 void objc::checkCategories() {
-  TimeTraceScope timeScope("ObjcCategoryChecker");
+  llvm::TimeTraceScope timeScope("ObjcCategoryChecker");
 
   ObjcCategoryChecker checker;
   for (const InputSection *isec : inputSections) {
@@ -420,7 +421,7 @@ class ObjcCategoryMerger {
   static void doCleanup();
 
 private:
-  DenseSet<const Symbol *> collectNlCategories();
+  llvm::DenseSet<const Symbol *> collectNlCategories();
   void collectAndValidateCategoriesData();
   bool
   mergeCategoriesIntoSingleCategory(std::vector<InfoInputCategory> 
&categories);
@@ -429,7 +430,7 @@ class ObjcCategoryMerger {
   void eraseMergedCategories();
 
   void generateCatListForNonErasedCategories(
-      MapVector<ConcatInputSection *, std::set<uint64_t>>
+      llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
           catListToErasedOffsets);
   void collectSectionWriteInfoFromIsec(const InputSection *isec,
                                        InfoWriteSection &catWriteInfo);
@@ -494,14 +495,14 @@ class ObjcCategoryMerger {
   InfoCategoryWriter infoCategoryWriter;
   std::vector<ConcatInputSection *> &allInputSections;
   // Map of base class Symbol to list of InfoInputCategory's for it
-  MapVector<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
+  llvm::MapVector<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
 
   // Normally, the binary data comes from the input files, but since we're
   // generating binary data ourselves, we use the below array to store it in.
   // Need this to be 'static' so the data survives past the ObjcCategoryMerger
   // object, as the data will be read by the Writer when the final binary is
   // generated.
-  static SmallVector<std::unique_ptr<SmallVector<uint8_t>>>
+  static llvm::SmallVector<std::unique_ptr<llvm::SmallVector<uint8_t>>>
       generatedSectionData;
 };
 
@@ -542,7 +543,7 @@ ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const 
ConcatInputSection *isec,
   if (!reloc)
     return nullptr;
 
-  Symbol *sym = dyn_cast_if_present<Symbol *>(reloc->referent);
+  Symbol *sym = llvm::dyn_cast_if_present<Symbol *>(reloc->referent);
 
   if (reloc->addend && sym) {
     assert(isa<Defined>(sym) && "Expected defined for non-zero addend");
@@ -1149,8 +1150,8 @@ void ObjcCategoryMerger::createSymbolReference(Defined 
*refFrom,
 // Get the list of categories in the '__objc_nlcatlist' section. We can't
 // optimize these as they have a '+load' method that has to be called at
 // runtime.
-DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() {
-  DenseSet<const Symbol *> nlCategories;
+llvm::DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() {
+  llvm::DenseSet<const Symbol *> nlCategories;
 
   for (InputSection *sec : allInputSections) {
     if (sec->getName() != section_names::objcNonLazyCatList)
@@ -1219,7 +1220,7 @@ void 
ObjcCategoryMerger::collectAndValidateCategoriesData() {
 // (not erased). For these not erased categories, we generate new 
__objc_catlist
 // entries since the parent __objc_catlist entry will be erased
 void ObjcCategoryMerger::generateCatListForNonErasedCategories(
-    const MapVector<ConcatInputSection *, std::set<uint64_t>>
+    const llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
         catListToErasedOffsets) {
 
   // Go through all offsets of all __objc_catlist's that we process and if 
there
@@ -1284,7 +1285,8 @@ void ObjcCategoryMerger::eraseISec(ConcatInputSection 
*isec) {
 // them.
 void ObjcCategoryMerger::eraseMergedCategories() {
   // Map of InputSection to a set of offsets of the categories that were merged
-  MapVector<ConcatInputSection *, std::set<uint64_t>> catListToErasedOffsets;
+  llvm::MapVector<ConcatInputSection *, std::set<uint64_t>>
+      catListToErasedOffsets;
 
   for (auto &mapEntry : categoryMap) {
     for (InfoInputCategory &catInfo : mapEntry.second) {
@@ -1374,7 +1376,7 @@ SmallVector<uint8_t> 
&ObjcCategoryMerger::newSectionData(uint32_t size) {
 } // namespace
 
 void objc::mergeCategories() {
-  TimeTraceScope timeScope("ObjcCategoryMerger");
+  llvm::TimeTraceScope timeScope("ObjcCategoryMerger");
 
   ObjcCategoryMerger merger(inputSections);
   merger.doMerge();
diff --git a/lld/MachO/Relocations.cpp b/lld/MachO/Relocations.cpp
index 78cc13388d6eb..f9b18305b5654 100644
--- a/lld/MachO/Relocations.cpp
+++ b/lld/MachO/Relocations.cpp
@@ -14,7 +14,6 @@
 
 #include "lld/Common/ErrorHandler.h"
 
-using namespace llvm;
 using namespace lld;
 using namespace lld::macho;
 
diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index bf01b12d11dfd..0d6a829cf21dc 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -27,7 +27,6 @@
 
 #include <numeric>
 
-using namespace llvm;
 using namespace llvm::MachO;
 using namespace llvm::support::endian;
 using namespace lld;
@@ -118,7 +117,7 @@ struct CompactUnwindEntry {
   InputSection *lsda;
 };
 
-using EncodingMap = DenseMap<compact_unwind_encoding_t, size_t>;
+using EncodingMap = llvm::DenseMap<compact_unwind_encoding_t, size_t>;
 
 struct SecondLevelPage {
   uint32_t kind;
@@ -146,7 +145,7 @@ class UnwindInfoSectionImpl final : public 
UnwindInfoSection {
   Symbol *canonicalizePersonality(Symbol *);
 
   uint64_t unwindInfoSize = 0;
-  SmallVector<decltype(symbols)::value_type, 0> symbolsVec;
+  llvm::SmallVector<decltype(symbols)::value_type, 0> symbolsVec;
   CompactUnwindLayout cuLayout;
   std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings;
   EncodingMap commonEncodingIndexes;
@@ -154,12 +153,13 @@ class UnwindInfoSectionImpl final : public 
UnwindInfoSection {
   // in symbolsVec.
   std::vector<CompactUnwindEntry> cuEntries;
   std::vector<Symbol *> personalities;
-  SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>, Symbol *>
+  llvm::SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>,
+                      Symbol *>
       personalityTable;
   // Indices into cuEntries for CUEs with a non-null LSDA.
   std::vector<size_t> entriesWithLsda;
   // Map of cuEntries index to an index within the LSDA array.
-  DenseMap<size_t, uint32_t> lsdaIndex;
+  llvm::DenseMap<size_t, uint32_t> lsdaIndex;
   std::vector<SecondLevelPage> secondLevelPages;
   uint64_t level2PagesOffset = 0;
   // The highest-address function plus its size. The unwinder needs this to
@@ -346,7 +346,7 @@ Symbol 
*UnwindInfoSectionImpl::canonicalizePersonality(Symbol *personality) {
 // is no source address to make a relative location meaningful.
 void UnwindInfoSectionImpl::relocateCompactUnwind(
     std::vector<CompactUnwindEntry> &cuEntries) {
-  parallelFor(0, symbolsVec.size(), [&](size_t i) {
+  llvm::parallelFor(0, symbolsVec.size(), [&](size_t i) {
     CompactUnwindEntry &cu = cuEntries[i];
     const Defined *d = symbolsVec[i].second;
     cu.functionAddress = d->getVA();
@@ -383,9 +383,8 @@ void UnwindInfoSectionImpl::relocateCompactUnwind(
     auto buf =
         reinterpret_cast<const uint8_t *>(d->unwindEntry()->data.data()) -
         target->wordSize;
-    cu.functionLength =
-        support::endian::read32le(buf + cuLayout.functionLengthOffset);
-    cu.encoding = support::endian::read32le(buf + cuLayout.encodingOffset);
+    cu.functionLength = read32le(buf + cuLayout.functionLengthOffset);
+    cu.encoding = read32le(buf + cuLayout.encodingOffset);
     for (const Reloc &r : d->unwindEntry()->relocs) {
       if (r.offset == cuLayout.personalityOffset)
         cu.personality = cast<Symbol *>(r.referent);
@@ -402,7 +401,7 @@ void UnwindInfoSectionImpl::encodePersonalities() {
     if (cu.personality == nullptr)
       continue;
     // Linear search is fast enough for a small array.
-    auto it = find(personalities, cu.personality);
+    auto it = llvm::find(personalities, cu.personality);
     uint32_t personalityIndex; // 1-based index
     if (it != personalities.end()) {
       personalityIndex = std::distance(personalities.begin(), it) + 1;

>From 8e38a6f850d685a437a5bf6a8823c7996ba484bd Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Mon, 29 Dec 2025 10:54:18 +0000
Subject: [PATCH 2/7] WIP use pch for component libs

---
 clang/lib/DirectoryWatcher/CMakeLists.txt   |   2 +-
 clang/lib/Format/CMakeLists.txt             |   2 +-
 clang/lib/Tooling/Core/CMakeLists.txt       |   2 +-
 clang/lib/Tooling/Inclusions/CMakeLists.txt |   2 +-
 flang/lib/Evaluate/CMakeLists.txt           |   2 +
 flang/lib/Frontend/CMakeLists.txt           |   2 +
 flang/lib/Lower/CMakeLists.txt              |   2 +
 flang/lib/Parser/CMakeLists.txt             |   2 +
 flang/lib/Semantics/CMakeLists.txt          |   2 +
 llvm/cmake/modules/AddLLVM.cmake            |  24 +++-
 llvm/include/llvm/CodeGen/pch.h             |  25 ++++
 llvm/include/llvm/IR/pch.h                  |  31 +++++
 llvm/include/llvm/Support/pch.h             | 130 ++++++++++++++++++++
 llvm/lib/CodeGen/CMakeLists.txt             |   6 +
 llvm/lib/IR/CMakeLists.txt                  |   6 +
 llvm/lib/Support/CMakeLists.txt             |   8 +-
 16 files changed, 240 insertions(+), 8 deletions(-)
 create mode 100644 llvm/include/llvm/CodeGen/pch.h
 create mode 100644 llvm/include/llvm/IR/pch.h
 create mode 100644 llvm/include/llvm/Support/pch.h

diff --git a/clang/lib/DirectoryWatcher/CMakeLists.txt 
b/clang/lib/DirectoryWatcher/CMakeLists.txt
index 5a87969821138..bbdd51b3afbaf 100644
--- a/clang/lib/DirectoryWatcher/CMakeLists.txt
+++ b/clang/lib/DirectoryWatcher/CMakeLists.txt
@@ -1,6 +1,6 @@
 include(CheckIncludeFiles)
 
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS Support)
 
 set(DIRECTORY_WATCHER_SOURCES DirectoryScanner.cpp)
 set(DIRECTORY_WATCHER_LINK_LIBS "")
diff --git a/clang/lib/Format/CMakeLists.txt b/clang/lib/Format/CMakeLists.txt
index 50c0683dc9b7f..9c622486a5214 100644
--- a/clang/lib/Format/CMakeLists.txt
+++ b/clang/lib/Format/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS Support)
 
 add_clang_library(clangFormat
   AffectedRangeManager.cpp
diff --git a/clang/lib/Tooling/Core/CMakeLists.txt 
b/clang/lib/Tooling/Core/CMakeLists.txt
index e523ca45301e2..f102c1cdfca7b 100644
--- a/clang/lib/Tooling/Core/CMakeLists.txt
+++ b/clang/lib/Tooling/Core/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS Support)
 
 add_clang_library(clangToolingCore
   Diagnostic.cpp
diff --git a/clang/lib/Tooling/Inclusions/CMakeLists.txt 
b/clang/lib/Tooling/Inclusions/CMakeLists.txt
index f9c2e6397ae72..aad5a745a8b5d 100644
--- a/clang/lib/Tooling/Inclusions/CMakeLists.txt
+++ b/clang/lib/Tooling/Inclusions/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS Support)
 
 add_clang_library(clangToolingInclusions
   HeaderAnalysis.cpp
diff --git a/flang/lib/Evaluate/CMakeLists.txt 
b/flang/lib/Evaluate/CMakeLists.txt
index 24a1c9004bc3b..6a658701262c2 100644
--- a/flang/lib/Evaluate/CMakeLists.txt
+++ b/flang/lib/Evaluate/CMakeLists.txt
@@ -66,6 +66,8 @@ add_flang_library(FortranEvaluate
   ${LIBPGMATH}
   ${QUADMATHLIB}
 
+  DISABLE_PCH_REUSE
+
   LINK_COMPONENTS
   Support
 
diff --git a/flang/lib/Frontend/CMakeLists.txt 
b/flang/lib/Frontend/CMakeLists.txt
index 4ebe497e65676..ee4c295e37762 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -13,6 +13,8 @@ add_flang_library(flangFrontend
   TextDiagnosticBuffer.cpp
   TextDiagnostic.cpp
 
+  DISABLE_PCH_REUSE
+
   DEPENDS
   CUFDialect
   FIRDialect
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index 230a56ab66ec5..a1022a598ae89 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -38,6 +38,8 @@ add_flang_library(FortranLower
   Support/Utils.cpp
   SymbolMap.cpp
   VectorSubscripts.cpp
+
+  DISABLE_PCH_REUSE
   
   DEPENDS
   CUFAttrs
diff --git a/flang/lib/Parser/CMakeLists.txt b/flang/lib/Parser/CMakeLists.txt
index 20c6c2a7c8f80..10f4765dbbaf4 100644
--- a/flang/lib/Parser/CMakeLists.txt
+++ b/flang/lib/Parser/CMakeLists.txt
@@ -25,6 +25,8 @@ add_flang_library(FortranParser
   unparse.cpp
   user-state.cpp
 
+  DISABLE_PCH_REUSE
+
   LINK_LIBS
   FortranSupport
 
diff --git a/flang/lib/Semantics/CMakeLists.txt 
b/flang/lib/Semantics/CMakeLists.txt
index 109bc2dbb8569..a6d6be8fac16c 100644
--- a/flang/lib/Semantics/CMakeLists.txt
+++ b/flang/lib/Semantics/CMakeLists.txt
@@ -53,6 +53,8 @@ add_flang_library(FortranSemantics
   type.cpp
   unparse-with-symbols.cpp
 
+  DISABLE_PCH_REUSE
+
   DEPENDS
   acc_gen
   omp_gen
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index 18c0ac7015efa..fa314ad97af84 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -68,6 +68,10 @@ function(llvm_update_compile_flags name)
 
   target_compile_options(${name} PRIVATE ${LLVM_COMPILE_FLAGS} 
$<$<COMPILE_LANGUAGE:CXX>:${LLVM_COMPILE_CXXFLAGS}>)
   target_compile_definitions(${name} PRIVATE ${LLVM_COMPILE_DEFINITIONS})
+  if(LLVM_REUSE_PCH)
+    message(STATUS "Using PCH ${LLVM_REUSE_PCH} for ${name}")
+    target_precompile_headers(${name} REUSE_FROM ${LLVM_REUSE_PCH})
+  endif()
 endfunction()
 
 function(add_llvm_symbol_exports target_name export_file)
@@ -495,11 +499,12 @@ endfunction(set_windows_version_resource_properties)
 #   )
 function(llvm_add_library name)
   cmake_parse_arguments(ARG
-    
"MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
+    
"MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB;DISABLE_PCH_REUSE"
     "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
     "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
     ${ARGN})
   list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
+  list(APPEND ARG_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
   if(ARG_ADDITIONAL_HEADERS)
     # Pass through ADDITIONAL_HEADERS.
     set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS})
@@ -531,6 +536,20 @@ function(llvm_add_library name)
     endif()
   endif()
 
+  if(LLVM_REQUIRES_RTTI OR LLVM_REQUIRES_EH)
+    # Non-default RTTI/EH results in incompatible flags, precluding PCH reuse.
+    set(ARG_DISABLE_PCH_REUSE TRUE)
+  endif()
+  if(NOT ARG_DISABLE_PCH_REUSE)
+    if("CodeGen" IN_LIST ARG_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMCodeGen)
+    elseif("Core" IN_LIST ARG_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMCore)
+    elseif("Support" IN_LIST ARG_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMSupport)
+    endif()
+  endif()
+
   get_subproject_title(subproject_title)
 
   # Generate objlib
@@ -750,7 +769,6 @@ function(llvm_add_library name)
       endif()
       llvm_map_components_to_libnames(llvm_libs
        ${ARG_LINK_COMPONENTS}
-       ${LLVM_LINK_COMPONENTS}
        )
     endif()
   else()
@@ -761,7 +779,7 @@ function(llvm_add_library name)
     # It would be nice to verify that we have the dependencies for this library
     # name, but using get_property(... SET) doesn't suffice to determine if a
     # property has been set to an empty value.
-    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS 
${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})
+    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS 
${ARG_LINK_COMPONENTS})
 
     # This property is an internal property only used to make sure the
     # link step applied in LLVMBuildResolveComponentsLink uses the same
diff --git a/llvm/include/llvm/CodeGen/pch.h b/llvm/include/llvm/CodeGen/pch.h
new file mode 100644
index 0000000000000..36eb560b3c003
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/pch.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMCodeGen.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/IR/pch.h"
+#include "llvm/Support/pch.h"
diff --git a/llvm/include/llvm/IR/pch.h b/llvm/include/llvm/IR/pch.h
new file mode 100644
index 0000000000000..b2fa937076d77
--- /dev/null
+++ b/llvm/include/llvm/IR/pch.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMCore.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/pch.h"
diff --git a/llvm/include/llvm/Support/pch.h b/llvm/include/llvm/Support/pch.h
new file mode 100644
index 0000000000000..b1ff8698827ff
--- /dev/null
+++ b/llvm/include/llvm/Support/pch.h
@@ -0,0 +1,130 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Precompiled header for LLVMSupport.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ADL.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <any>
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <cassert>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <charconv>
+#include <chrono>
+#include <cinttypes>
+#include <climits>
+#include <cmath>
+#include <complex.h>
+#include <complex>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <ctype.h>
+#include <cuchar>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <errno.h>
+#include <exception>
+#include <execution>
+#include <fenv.h>
+#include <filesystem>
+#include <float.h>
+#include <forward_list>
+#include <fstream>
+#include <functional>
+#include <initializer_list>
+#include <iostream>
+#include <istream>
+#include <iterator>
+#include <limits>
+#include <list>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <memory_resource>
+#include <mutex>
+#include <new>
+#include <numeric>
+#include <optional>
+#include <ostream>
+#include <queue>
+#include <random>
+#include <ratio>
+#include <regex>
+#include <scoped_allocator>
+#include <set>
+#include <shared_mutex>
+#include <sstream>
+#include <stack>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdexcept>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <streambuf>
+#include <string.h>
+#include <string>
+#include <string_view>
+#include <system_error>
+#include <tgmath.h>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#include <typeindex>
+#include <typeinfo>
+#include <uchar.h>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <variant>
+#include <vector>
+#include <wchar.h>
+#include <wctype.h>
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 871934ea4b76e..15300aab240db 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -262,6 +262,8 @@ add_llvm_component_library(LLVMCodeGen
   LiveDebugValues/VarLocBasedImpl.cpp
   LiveDebugValues/InstrRefBasedImpl.cpp
 
+  DISABLE_PCH_REUSE
+
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/CodeGen
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/CodeGen/PBQP
@@ -290,6 +292,10 @@ add_llvm_component_library(LLVMCodeGen
   TransformUtils
   )
 
+target_precompile_headers(LLVMCodeGen PRIVATE
+  "$<$<COMPILE_LANGUAGE:CXX>:\"llvm/CodeGen/pch.h\">"
+)
+
 add_subdirectory(SelectionDAG)
 add_subdirectory(AsmPrinter)
 add_subdirectory(MIRParser)
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 31821a2d6b208..68c54b0fc3524 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -80,6 +80,8 @@ add_llvm_component_library(LLVMCore
   VFABIDemangler.cpp
   RuntimeLibcalls.cpp
 
+  DISABLE_PCH_REUSE
+
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR
 
@@ -96,3 +98,7 @@ add_llvm_component_library(LLVMCore
   Support
   TargetParser
   )
+
+target_precompile_headers(LLVMCore PRIVATE
+  "$<$<COMPILE_LANGUAGE:CXX>:\"llvm/IR/pch.h\">"
+)
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 1c397e8c0b766..ff36206488186 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -135,7 +135,6 @@ if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
 endif()
 
 add_subdirectory(BLAKE3)
-add_subdirectory(LSP)
 
 add_llvm_component_library(LLVMSupport
   ABIBreak.cpp
@@ -395,3 +394,10 @@ target_include_directories(LLVMSupport
   PRIVATE
   ${LLVM_THIRD_PARTY_DIR}/siphash/include
 )
+
+target_precompile_headers(LLVMSupport PRIVATE
+  "$<$<COMPILE_LANGUAGE:CXX>:\"llvm/Support/pch.h\">"
+)
+
+# SupportLSP depends on Support and therefore must be included afterwards.
+add_subdirectory(LSP)

>From eb292123e654bce29b772c45c67ca91dc698dd4f Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 11:10:43 +0000
Subject: [PATCH 3/7] pch for unittests

---
 clang/unittests/Basic/CharInfoTest.cpp            |  1 -
 .../Interpreter/ExceptionTests/CMakeLists.txt     |  2 +-
 llvm/cmake/modules/AddLLVM.cmake                  | 13 ++++++++++---
 llvm/unittests/Support/raw_sha1_ostream_test.cpp  | 15 +--------------
 third-party/unittest/CMakeLists.txt               | 12 +++++++++++-
 5 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/clang/unittests/Basic/CharInfoTest.cpp 
b/clang/unittests/Basic/CharInfoTest.cpp
index 491c9afceb6f8..09b827be35397 100644
--- a/clang/unittests/Basic/CharInfoTest.cpp
+++ b/clang/unittests/Basic/CharInfoTest.cpp
@@ -9,7 +9,6 @@
 #include "clang/Basic/CharInfo.h"
 #include "gtest/gtest.h"
 
-using namespace llvm;
 using namespace clang;
 
 // Check that the CharInfo table has been constructed reasonably.
diff --git a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt 
b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
index dfd94d8e6442c..5ea752b77f6f9 100644
--- a/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
+++ b/clang/unittests/Interpreter/ExceptionTests/CMakeLists.txt
@@ -1,7 +1,7 @@
 # The interpreter can throw an exception from user input. The test binary needs
 # to be compiled with exception support to catch the thrown exception.
 set(LLVM_REQUIRES_EH ON)
-set(LLVM_REQUIRES_RTTI ON)
+set(LLVM_REQUIRES_RTTI OFF)
 
 add_distinct_clang_unittest(ClangReplInterpreterExceptionTests
   InterpreterExceptionTest.cpp
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index fa314ad97af84..b1af424a9643a 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -26,8 +26,9 @@ function(llvm_update_compile_flags name)
   # force EH
   if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
     if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
-      message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI 
for ${name}")
-      set(LLVM_REQUIRES_RTTI ON)
+      # XXX: still required?
+      #message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI 
for ${name}")
+      #set(LLVM_REQUIRES_RTTI ON)
     endif()
     if(MSVC)
       list(APPEND LLVM_COMPILE_CXXFLAGS "/EHsc")
@@ -68,7 +69,7 @@ function(llvm_update_compile_flags name)
 
   target_compile_options(${name} PRIVATE ${LLVM_COMPILE_FLAGS} 
$<$<COMPILE_LANGUAGE:CXX>:${LLVM_COMPILE_CXXFLAGS}>)
   target_compile_definitions(${name} PRIVATE ${LLVM_COMPILE_DEFINITIONS})
-  if(LLVM_REUSE_PCH)
+  if(LLVM_REUSE_PCH AND TARGET ${LLVM_REUSE_PCH})
     message(STATUS "Using PCH ${LLVM_REUSE_PCH} for ${name}")
     target_precompile_headers(${name} REUSE_FROM ${LLVM_REUSE_PCH})
   endif()
@@ -1804,8 +1805,14 @@ function(add_unittest test_suite test_name)
   # If it is not defined, fall back to llvm_gtest.
   if(TARGET default_gtest)
     target_link_libraries(${test_name} PRIVATE default_gtest_main 
default_gtest ${LLVM_PTHREAD_LIB})
+    if(NOT LLVM_REQUIRES_RTTI AND NOT LLVM_REQUIRES_EH)
+      target_precompile_headers(${test_name} REUSE_FROM default_gtest)
+    endif()
   else ()
     target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest 
${LLVM_PTHREAD_LIB})
+    if(NOT LLVM_REQUIRES_RTTI AND NOT LLVM_REQUIRES_EH)
+      target_precompile_headers(${test_name} REUSE_FROM llvm_gtest)
+    endif()
   endif ()
 
   add_dependencies(${test_suite} ${test_name})
diff --git a/llvm/unittests/Support/raw_sha1_ostream_test.cpp 
b/llvm/unittests/Support/raw_sha1_ostream_test.cpp
index a3cb6f58d3e29..be8333237d81d 100644
--- a/llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ b/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -6,6 +6,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_sha1_ostream.h"
 #include "gtest/gtest.h"
@@ -14,20 +15,6 @@
 
 using namespace llvm;
 
-static std::string toHex(ArrayRef<uint8_t> Input) {
-  static const char *const LUT = "0123456789ABCDEF";
-  size_t Length = Input.size();
-
-  std::string Output;
-  Output.reserve(2 * Length);
-  for (size_t i = 0; i < Length; ++i) {
-    const unsigned char c = Input[i];
-    Output.push_back(LUT[c >> 4]);
-    Output.push_back(LUT[c & 15]);
-  }
-  return Output;
-}
-
 TEST(raw_sha1_ostreamTest, Basic) {
   llvm::raw_sha1_ostream Sha1Stream;
   Sha1Stream << "Hello World!";
diff --git a/third-party/unittest/CMakeLists.txt 
b/third-party/unittest/CMakeLists.txt
index 79535a1de4616..ac2c1038e7d97 100644
--- a/third-party/unittest/CMakeLists.txt
+++ b/third-party/unittest/CMakeLists.txt
@@ -13,6 +13,8 @@
 
 set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test")
 
+set(GTEST_PCH [["gtest/gtest.h"]])
+
 if(LLVM_RUNTIMES_BUILD)
   # This instance of GTest is use for unittests for the runtime libraries. It
   # must not link to LLVMSupport (used for llvm::raw_ostream and llvm::cl
@@ -37,6 +39,7 @@ else()
   set(GTEST_LLVM_COMPONENTS "Support")
   set(gtest_name "llvm_gtest")
   set(gtest_main_src UnitTestMain/TestMain.cpp)
+  list(APPEND GTEST_PCH [["llvm/Support/pch.h"]])
 endif()
 
 if(WIN32)
@@ -59,7 +62,6 @@ if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
   add_definitions("-Wno-covered-switch-default")
 endif()
 
-set(LLVM_REQUIRES_RTTI 1)
 add_definitions( -DGTEST_HAS_RTTI=0 )
 
 if (HAVE_LIBPTHREAD)
@@ -76,6 +78,8 @@ add_llvm_library("${gtest_name}"
   googletest/src/gtest-all.cc
   googlemock/src/gmock-all.cc
 
+  DISABLE_PCH_REUSE
+
   LINK_LIBS
   ${LIBS}
 
@@ -121,10 +125,14 @@ else()
     )
 endif()
 
+target_precompile_headers("${gtest_name}" PRIVATE ${GTEST_PCH})
+
 
 add_llvm_library("${gtest_name}_main"
   ${gtest_main_src}
 
+  DISABLE_PCH_REUSE
+
   LINK_LIBS
   "${gtest_name}"
 
@@ -134,6 +142,8 @@ add_llvm_library("${gtest_name}_main"
   ${BUILDTREE_ONLY}
 )
 
+target_precompile_headers("${gtest_name}_main" REUSE_FROM "${gtest_name}")
+
 if (LLVM_INSTALL_GTEST)
   install(DIRECTORY googletest/include/gtest/ DESTINATION 
"${CMAKE_INSTALL_INCLUDEDIR}/llvm-gtest/gtest/" COMPONENT "${gtest_name}")
   install(DIRECTORY googlemock/include/gmock/ DESTINATION 
"${CMAKE_INSTALL_INCLUDEDIR}/llvm-gmock/gmock/" COMPONENT "${gtest_name}")

>From 29abb8c676aca1b65b68ef1534ca20cff65f5ffe Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 12:07:07 +0000
Subject: [PATCH 4/7] fix MLIR ambiguity

---
 mlir/lib/Support/TypeID.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/lib/Support/TypeID.cpp b/mlir/lib/Support/TypeID.cpp
index 304253cc6daa7..3526a0d49cc79 100644
--- a/mlir/lib/Support/TypeID.cpp
+++ b/mlir/lib/Support/TypeID.cpp
@@ -49,7 +49,7 @@ struct ImplicitTypeIDRegistry {
                    "`MLIR_DEFINE_EXPLICIT_TYPE_ID` or "
                    "`MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID`.\n";
       }
-      llvm::report_fatal_error(errorStr);
+      llvm::report_fatal_error(llvm::StringRef(errorStr));
     }
 #endif
 

>From 28aa16a9772f0bb4aa99045671f2be73d275cc68 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 14:21:24 +0000
Subject: [PATCH 5/7] [llvm-objdump][NFC] Use EnumEntry from Support

Avoid colliding name for same functionality
---
 llvm/tools/llvm-objdump/COFFDump.cpp | 32 ++++++++++++----------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/llvm/tools/llvm-objdump/COFFDump.cpp 
b/llvm/tools/llvm-objdump/COFFDump.cpp
index de825612c089d..9147414408381 100644
--- a/llvm/tools/llvm-objdump/COFFDump.cpp
+++ b/llvm/tools/llvm-objdump/COFFDump.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Object/COFFImportFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/Win64EH.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
@@ -32,11 +33,6 @@ using namespace llvm::object;
 using namespace llvm::Win64EH;
 
 namespace {
-template <typename T> struct EnumEntry {
-  T Value;
-  StringRef Name;
-};
-
 class COFFDumper : public Dumper {
 public:
   explicit COFFDumper(const llvm::object::COFFObjectFile &O)
@@ -67,22 +63,22 @@ objdump::createCOFFDumper(const object::COFFObjectFile 
&Obj) {
 }
 
 constexpr EnumEntry<uint16_t> PEHeaderMagic[] = {
-    {uint16_t(COFF::PE32Header::PE32), "PE32"},
-    {uint16_t(COFF::PE32Header::PE32_PLUS), "PE32+"},
+    {"PE32", uint16_t(COFF::PE32Header::PE32)},
+    {"PE32+", uint16_t(COFF::PE32Header::PE32_PLUS)},
 };
 
 constexpr EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = {
-    {COFF::IMAGE_SUBSYSTEM_UNKNOWN, "unspecified"},
-    {COFF::IMAGE_SUBSYSTEM_NATIVE, "NT native"},
-    {COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, "Windows GUI"},
-    {COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, "Windows CUI"},
-    {COFF::IMAGE_SUBSYSTEM_POSIX_CUI, "POSIX CUI"},
-    {COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, "Wince CUI"},
-    {COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION, "EFI application"},
-    {COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, "EFI boot service driver"},
-    {COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, "EFI runtime driver"},
-    {COFF::IMAGE_SUBSYSTEM_EFI_ROM, "SAL runtime driver"},
-    {COFF::IMAGE_SUBSYSTEM_XBOX, "XBOX"},
+    {"unspecified", COFF::IMAGE_SUBSYSTEM_UNKNOWN},
+    {"NT native", COFF::IMAGE_SUBSYSTEM_NATIVE},
+    {"Windows GUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI},
+    {"Windows CUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI},
+    {"POSIX CUI", COFF::IMAGE_SUBSYSTEM_POSIX_CUI},
+    {"Wince CUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI},
+    {"EFI application", COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION},
+    {"EFI boot service driver", COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER},
+    {"EFI runtime driver", COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER},
+    {"SAL runtime driver", COFF::IMAGE_SUBSYSTEM_EFI_ROM},
+    {"XBOX", COFF::IMAGE_SUBSYSTEM_XBOX},
 };
 
 template <typename T, typename TEnum>

>From 36f4a4b4d20e082719ea9c74928716b76b6cd3e1 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 14:22:25 +0000
Subject: [PATCH 6/7] pch for executables

---
 llvm/cmake/modules/AddLLVM.cmake              | 19 +++++++++++++++++--
 .../CMakeLists.txt                            |  2 ++
 .../OrcV2CBindingsBasicUsage/CMakeLists.txt   |  2 ++
 .../OrcV2CBindingsDumpObjects/CMakeLists.txt  |  2 ++
 .../OrcV2CBindingsIRTransforms/CMakeLists.txt |  2 ++
 .../OrcV2CBindingsLazy/CMakeLists.txt         |  2 ++
 .../CMakeLists.txt                            |  2 ++
 .../CMakeLists.txt                            |  2 ++
 .../OrcV2CBindingsVeryLazy/CMakeLists.txt     |  2 ++
 llvm/tools/llvm-c-test/CMakeLists.txt         |  2 ++
 10 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index b1af424a9643a..b1acc2768132b 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -1042,10 +1042,25 @@ endmacro()
 
 macro(add_llvm_executable name)
   cmake_parse_arguments(ARG
-    
"DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;EXPORT_SYMBOLS"
+    
"DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;EXPORT_SYMBOLS;DISABLE_PCH_REUSE"
     "ENTITLEMENTS;BUNDLE_PATH"
     ""
     ${ARGN})
+  # TODO: deduplicate
+  if(LLVM_REQUIRES_RTTI OR LLVM_REQUIRES_EH)
+    # Non-default RTTI/EH results in incompatible flags, precluding PCH reuse.
+    set(ARG_DISABLE_PCH_REUSE TRUE)
+  endif()
+  if(NOT ARG_DISABLE_PCH_REUSE)
+    if("CodeGen" IN_LIST LLVM_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMCodeGen)
+    elseif("Core" IN_LIST LLVM_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMCore)
+    elseif("Support" IN_LIST LLVM_LINK_COMPONENTS)
+      set(LLVM_REUSE_PCH LLVMSupport)
+    endif()
+  endif()
+
   generate_llvm_objects(${name} ${ARG_UNPARSED_ARGUMENTS})
   add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
 
@@ -1790,7 +1805,7 @@ function(add_unittest test_suite test_name)
   endif()
 
   list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream
-  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO 
NO_INSTALL_RPATH ${ARGN})
+  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO 
NO_INSTALL_RPATH DISABLE_PCH_REUSE ${ARGN})
   get_subproject_title(subproject_title)
   set_target_properties(${test_name} PROPERTIES FOLDER 
"${subproject_title}/Tests/Unit")
 
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
index cc50112f326ea..9a82cc0ed0916 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsAddObjectFile/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsAddObjectFile
   OrcV2CBindingsAddObjectFile.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
index 0f18d6c24912f..1a738f60d15e1 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsBasicUsage/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsBasicUsage
   OrcV2CBindingsBasicUsage.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
index 8e2c97d782062..c7f748a12bf35 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsDumpObjects/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsDumpObjects
   OrcV2CBindingsDumpObjects.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
index af1b43e43e111..b152faf1e3527 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsIRTransforms/CMakeLists.txt
@@ -13,4 +13,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsIRTransforms
   OrcV2CBindingsIRTransforms.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
index 52eb2d496fc23..c46700d9b2576 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsLazy/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsLazy
   OrcV2CBindingsLazy.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
index 4cdc2b114e9a5..d4a06104120c8 100644
--- 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
+++ 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsMCJITLikeMemoryManager/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsMCJITLikeMemoryManager
   OrcV2CBindingsMCJITLikeMemoryManager.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git 
a/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
index 5b737557bb1ef..441814054d9d1 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsRemovableCode/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsRemovableCode
   OrcV2CBindingsRemovableCode.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git a/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt 
b/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
index 0bc9610b1ad7e..6ec22f63875b9 100644
--- a/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
+++ b/llvm/examples/OrcV2Examples/OrcV2CBindingsVeryLazy/CMakeLists.txt
@@ -12,4 +12,6 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_example(OrcV2CBindingsVeryLazy
   OrcV2CBindingsVeryLazy.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
diff --git a/llvm/tools/llvm-c-test/CMakeLists.txt 
b/llvm/tools/llvm-c-test/CMakeLists.txt
index 939164e636216..8dd42b48e39a2 100644
--- a/llvm/tools/llvm-c-test/CMakeLists.txt
+++ b/llvm/tools/llvm-c-test/CMakeLists.txt
@@ -53,6 +53,8 @@ add_llvm_tool(llvm-c-test
   metadata.c
   object.c
   targets.c
+
+  DISABLE_PCH_REUSE # no C++ files, prevent CMake error.
   )
 
 if(USE_LLVM_DYLIB)

>From b47e426812a42d31dbd4ce1645aa9141d7d36285 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <[email protected]>
Date: Tue, 30 Dec 2025 14:22:45 +0000
Subject: [PATCH 7/7] [Support][NFC] Drop unnecessary default lambdas

These must be instantiated and code-generated in multiple CUs; instead
use the null/default state of std::function as default state.
---
 llvm/include/llvm/Support/CommandLine.h | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/Support/CommandLine.h 
b/llvm/include/llvm/Support/CommandLine.h
index d737fbcf891b3..168bbff65342b 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -1463,7 +1463,8 @@ class opt
       return true; // Parse error!
     this->setValue(Val);
     this->setPosition(pos);
-    Callback(Val);
+    if (Callback)
+      Callback(Val);
     return false;
   }
 
@@ -1518,13 +1519,15 @@ class opt
 
   template <class T> DataType &operator=(const T &Val) {
     this->setValue(Val);
-    Callback(Val);
+    if (Callback)
+      Callback(Val);
     return this->getValue();
   }
 
   template <class T> DataType &operator=(T &&Val) {
     this->getValue() = std::forward<T>(Val);
-    Callback(this->getValue());
+    if (Callback)
+      Callback(this->getValue());
     return this->getValue();
   }
 
@@ -1540,8 +1543,7 @@ class opt
     Callback = CB;
   }
 
-  std::function<void(const typename ParserClass::parser_data_type &)> Callback 
=
-      [](const typename ParserClass::parser_data_type &) {};
+  std::function<void(const typename ParserClass::parser_data_type &)> Callback;
 };
 
 #if !(defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && defined(_MSC_VER))
@@ -1718,7 +1720,8 @@ class list : public Option, public list_storage<DataType, 
StorageClass> {
     list_storage<DataType, StorageClass>::addValue(Val);
     setPosition(pos);
     Positions.push_back(pos);
-    Callback(Val);
+    if (Callback)
+      Callback(Val);
     return false;
   }
 
@@ -1787,8 +1790,7 @@ class list : public Option, public list_storage<DataType, 
StorageClass> {
     Callback = CB;
   }
 
-  std::function<void(const typename ParserClass::parser_data_type &)> Callback 
=
-      [](const typename ParserClass::parser_data_type &) {};
+  std::function<void(const typename ParserClass::parser_data_type &)> Callback;
 };
 
 // Modifier to set the number of additional values.
@@ -1895,7 +1897,8 @@ class bits : public Option, public bits_storage<DataType, 
Storage> {
     this->addValue(Val);
     setPosition(pos);
     Positions.push_back(pos);
-    Callback(Val);
+    if (Callback)
+      Callback(Val);
     return false;
   }
 
@@ -1943,8 +1946,7 @@ class bits : public Option, public bits_storage<DataType, 
Storage> {
     Callback = CB;
   }
 
-  std::function<void(const typename ParserClass::parser_data_type &)> Callback 
=
-      [](const typename ParserClass::parser_data_type &) {};
+  std::function<void(const typename ParserClass::parser_data_type &)> Callback;
 };
 
 
//===----------------------------------------------------------------------===//

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to