diff --git a/.github/workflows/sync-release-repo.yml b/.github/workflows/sync-release-repo.yml
new file mode 100644
index 0000000000000..4643294cd7ca2
--- /dev/null
+++ b/.github/workflows/sync-release-repo.yml
@@ -0,0 +1,17 @@
+name: Sync Release Repositories
+permissions:
+ contents: write
+on:
+ workflow_dispatch
+env:
+ RELEASE_BRANCH: release/17.x
+ GH_TOKEN: ${{ secrets.RELEASE_WORKFLOW_PUSH_SECRET }}
+jobs:
+ sync:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Fetch LLVM sources
+ uses: actions/checkout@v3
+ - name: Run Sync Script
+ run: |
+ llvm/utils/git/sync-release-repo.sh
diff --git a/bolt/README.md b/bolt/README.md
index eed46fff848f1..fe54bd82a356a 100644
--- a/bolt/README.md
+++ b/bolt/README.md
@@ -30,14 +30,6 @@ compiler option. Since GCC8 enables this option by default, you have to
explicitly disable it by adding `-fno-reorder-blocks-and-partition` flag if
you are compiling with GCC8 or above.
-NOTE2: DWARF v5 is the new debugging format generated by the latest LLVM and GCC
-compilers. It offers several benefits over the previous DWARF v4. Currently, the
-support for v5 is a work in progress for BOLT. While you will be able to
-optimize binaries produced by the latest compilers, until the support is
-complete, you will not be able to update the debug info with
-`-update-debug-sections`. To temporarily work around the issue, we recommend
-compiling binaries with `-gdwarf-4` option that forces DWARF v4 output.
-
PIE and .so support has been added recently. Please report bugs if you
encounter any issues.
diff --git a/bolt/include/bolt/Core/AddressMap.h b/bolt/include/bolt/Core/AddressMap.h
new file mode 100644
index 0000000000000..16c2727b6943f
--- /dev/null
+++ b/bolt/include/bolt/Core/AddressMap.h
@@ -0,0 +1,59 @@
+//===- bolt/Core/AddressMap.h - Input-output address map --------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Helper class to create a mapping from input to output addresses needed for
+// updating debugging symbols and BAT. We emit an MCSection containing
+// pairs to the object file and JITLink will
+// transform this in pairs. The linker output
+// can then be parsed and used to establish the mapping.
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef BOLT_CORE_ADDRESS_MAP_H
+#define BOLT_CORE_ADDRESS_MAP_H
+
+#include "llvm/ADT/StringRef.h"
+
+#include
+#include
+
+namespace llvm {
+
+class MCStreamer;
+
+namespace bolt {
+
+class BinaryContext;
+
+class AddressMap {
+ using MapTy = std::unordered_multimap;
+ MapTy Map;
+
+public:
+ static const char *const SectionName;
+
+ static void emit(MCStreamer &Streamer, BinaryContext &BC);
+ static AddressMap parse(StringRef Buffer, const BinaryContext &BC);
+
+ std::optional lookup(uint64_t InputAddress) const {
+ auto It = Map.find(InputAddress);
+ if (It != Map.end())
+ return It->second;
+ return std::nullopt;
+ }
+
+ std::pair
+ lookupAll(uint64_t InputAddress) const {
+ return Map.equal_range(InputAddress);
+ }
+};
+
+} // namespace bolt
+} // namespace llvm
+
+#endif
diff --git a/bolt/include/bolt/Core/BinaryBasicBlock.h b/bolt/include/bolt/Core/BinaryBasicBlock.h
index 02be9c1d4f118..bc95e2c4de3a1 100644
--- a/bolt/include/bolt/Core/BinaryBasicBlock.h
+++ b/bolt/include/bolt/Core/BinaryBasicBlock.h
@@ -100,16 +100,6 @@ class BinaryBasicBlock {
using LocSymsTy = std::vector>;
std::unique_ptr LocSyms;
- /// After output/codegen, map output offsets of instructions in this basic
- /// block to instruction offsets in the original function. Note that the
- /// output basic block could be different from the input basic block.
- /// We only map instruction of interest, such as calls and markers.
- ///
- /// We store the offset array in a basic block to facilitate BAT tables
- /// generation. Otherwise, the mapping could be done at function level.
- using OffsetTranslationTableTy = std::vector>;
- std::unique_ptr OffsetTranslationTable;
-
/// Alignment requirements for the block.
uint32_t Alignment{1};
@@ -828,8 +818,7 @@ class BinaryBasicBlock {
return OutputAddressRange;
}
- /// Update addresses of special instructions inside this basic block.
- void updateOutputValues(const MCAsmLayout &Layout);
+ bool hasLocSyms() const { return LocSyms != nullptr; }
/// Return mapping of input offsets to symbols in the output.
LocSymsTy &getLocSyms() {
@@ -841,19 +830,6 @@ class BinaryBasicBlock {
return const_cast(this)->getLocSyms();
}
- /// Return offset translation table for the basic block.
- OffsetTranslationTableTy &getOffsetTranslationTable() {
- return OffsetTranslationTable
- ? *OffsetTranslationTable
- : *(OffsetTranslationTable =
- std::make_unique());
- }
-
- /// Return offset translation table for the basic block.
- const OffsetTranslationTableTy &getOffsetTranslationTable() const {
- return const_cast(this)->getOffsetTranslationTable();
- }
-
/// Return size of the basic block in the output binary.
uint64_t getOutputSize() const {
return OutputAddressRange.second - OutputAddressRange.first;
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 7bbfb2fc33eef..ef57ff3541dc8 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -13,6 +13,7 @@
#ifndef BOLT_CORE_BINARY_CONTEXT_H
#define BOLT_CORE_BINARY_CONTEXT_H
+#include "bolt/Core/AddressMap.h"
#include "bolt/Core/BinaryData.h"
#include "bolt/Core/BinarySection.h"
#include "bolt/Core/DebugData.h"
@@ -221,6 +222,9 @@ class BinaryContext {
bool ContainsDwarf5{false};
bool ContainsDwarfLegacy{false};
+ /// Mapping from input to output addresses.
+ std::optional IOAddressMap;
+
/// Preprocess DWO debug information.
void preprocessDWODebugInfo();
@@ -1343,6 +1347,12 @@ class BinaryContext {
/* DWARFMustBeAtTheEnd */ false));
return Streamer;
}
+
+ void setIOAddressMap(AddressMap Map) { IOAddressMap = std::move(Map); }
+ const AddressMap &getIOAddressMap() const {
+ assert(IOAddressMap && "Address map not set yet");
+ return *IOAddressMap;
+ }
};
template >
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index bbb5f99556d9c..9b45467a6a8fb 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -366,14 +366,15 @@ class BinaryFunction {
std::string ColdCodeSectionName;
/// Parent function fragment for split function fragments.
- SmallPtrSet ParentFragments;
+ using FragmentsSetTy = SmallPtrSet;
+ FragmentsSetTy ParentFragments;
/// Indicate if the function body was folded into another function.
/// Used by ICF optimization.
BinaryFunction *FoldedIntoFunction{nullptr};
/// All fragments for a parent function.
- SmallPtrSet Fragments;
+ FragmentsSetTy Fragments;
/// The profile data for the number of times the function was executed.
uint64_t ExecutionCount{COUNT_NO_PROFILE};
@@ -576,9 +577,6 @@ class BinaryFunction {
/// Count the number of functions created.
static uint64_t Count;
- /// Map offsets of special instructions to addresses in the output.
- InputOffsetToAddressMapTy InputOffsetToAddressMap;
-
/// Register alternative function name.
void addAlternativeName(std::string NewName) {
Aliases.push_back(std::move(NewName));
@@ -1225,13 +1223,6 @@ class BinaryFunction {
/// Update output values of the function based on the final \p Layout.
void updateOutputValues(const MCAsmLayout &Layout);
- /// Return mapping of input to output addresses. Most users should call
- /// translateInputToOutputAddress() for address translation.
- InputOffsetToAddressMapTy &getInputOffsetToAddressMap() {
- assert(isEmitted() && "cannot use address mapping before code emission");
- return InputOffsetToAddressMap;
- }
-
/// Register relocation type \p RelType at a given \p Address in the function
/// against \p Symbol.
/// Assert if the \p Address is not inside this function.
@@ -1779,6 +1770,15 @@ class BinaryFunction {
return llvm::is_contained(Fragments, &Other);
}
+ /// Return the child fragment form parent function
+ iterator_range getFragments() const {
+ return iterator_range(Fragments.begin(),
+ Fragments.end());
+ }
+
+ /// Return the parent function for split function fragments.
+ FragmentsSetTy *getParentFragments() { return &ParentFragments; }
+
/// Returns if this function is a parent or child of \p Other function.
bool isParentOrChildOf(const BinaryFunction &Other) const {
return isChildOf(Other) || isParentOf(Other);
@@ -2170,6 +2170,11 @@ class BinaryFunction {
/// its code emission.
bool requiresAddressTranslation() const;
+ /// Return true if the linker needs to generate an address map for this
+ /// function. Used for keeping track of the mapping from input to out
+ /// addresses of basic blocks.
+ bool requiresAddressMap() const;
+
/// Adjust branch instructions to match the CFG.
///
/// As it comes to internal branches, the CFG represents "the ultimate source
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index f1041777926fd..326d088d1f046 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -97,6 +97,8 @@ class BinarySection {
mutable bool IsReordered{false}; // Have the contents been reordered?
bool IsAnonymous{false}; // True if the name should not be included
// in the output file.
+ bool IsLinkOnly{false}; // True if the section should not be included
+ // in the output file.
uint64_t hash(const BinaryData &BD,
std::map &Cache) const;
@@ -452,6 +454,8 @@ class BinarySection {
void setIndex(uint32_t I) { Index = I; }
void setOutputName(const Twine &Name) { OutputName = Name.str(); }
void setAnonymous(bool Flag) { IsAnonymous = Flag; }
+ bool isLinkOnly() const { return IsLinkOnly; }
+ void setLinkOnly() { IsLinkOnly = true; }
/// Emit the section as data, possibly with relocations.
/// Use name \p SectionName for the section during the emission.
diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index 4034cb4ac118a..fb86e59468b83 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -21,12 +21,12 @@
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
#include
#include
#include
#include
+#include
#include
namespace llvm {
@@ -113,6 +113,7 @@ class DIEBuilder {
std::vector LocWithReferencesToProcess;
BumpPtrAllocator DIEAlloc;
ProcessingType Type;
+ std::unordered_set DWARFDieAddressesParsed;
};
std::unique_ptr BuilderState;
diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index d4611e8f6ca4a..3fdc0534c000a 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -313,9 +313,6 @@ class DebugAddrWriter {
/// Adds Address to map.
uint32_t getIndexFromAddress(uint64_t Address, DWARFUnit &CU);
- /// Adds {\p Address, \p Index} to \p CU.
- void addIndexAddress(uint64_t Address, uint32_t Index, DWARFUnit &CU);
-
/// Write out entries in to .debug_addr section for CUs.
virtual void update(DIEBuilder &DIEBlder, DWARFUnit &CUs);
diff --git a/bolt/lib/Core/AddressMap.cpp b/bolt/lib/Core/AddressMap.cpp
new file mode 100644
index 0000000000000..76c5378a3eb15
--- /dev/null
+++ b/bolt/lib/Core/AddressMap.cpp
@@ -0,0 +1,63 @@
+#include "bolt/Core/AddressMap.h"
+#include "bolt/Core/BinaryContext.h"
+#include "bolt/Core/BinaryFunction.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/DataExtractor.h"
+
+namespace llvm {
+namespace bolt {
+
+const char *const AddressMap::SectionName = ".bolt.address_map";
+
+static void emitLabel(MCStreamer &Streamer, uint64_t InputAddress,
+ const MCSymbol *OutputLabel) {
+ Streamer.emitIntValue(InputAddress, 8);
+ Streamer.emitSymbolValue(OutputLabel, 8);
+}
+
+void AddressMap::emit(MCStreamer &Streamer, BinaryContext &BC) {
+ Streamer.switchSection(BC.getDataSection(SectionName));
+
+ for (const auto &[BFAddress, BF] : BC.getBinaryFunctions()) {
+ if (!BF.requiresAddressMap())
+ continue;
+
+ for (const auto &BB : BF) {
+ if (!BB.getLabel()->isDefined())
+ continue;
+
+ emitLabel(Streamer, BFAddress + BB.getInputAddressRange().first,
+ BB.getLabel());
+
+ if (!BB.hasLocSyms())
+ continue;
+
+ for (auto [Offset, Symbol] : BB.getLocSyms())
+ emitLabel(Streamer, BFAddress + Offset, Symbol);
+ }
+ }
+}
+
+AddressMap AddressMap::parse(StringRef Buffer, const BinaryContext &BC) {
+ const auto EntrySize = 2 * BC.AsmInfo->getCodePointerSize();
+ assert(Buffer.size() % EntrySize == 0 && "Unexpected address map size");
+
+ DataExtractor DE(Buffer, BC.AsmInfo->isLittleEndian(),
+ BC.AsmInfo->getCodePointerSize());
+ DataExtractor::Cursor Cursor(0);
+
+ AddressMap Parsed;
+ Parsed.Map.reserve(Buffer.size() / EntrySize);
+
+ while (Cursor && !DE.eof(Cursor)) {
+ const auto Input = DE.getAddress(Cursor);
+ const auto Output = DE.getAddress(Cursor);
+ Parsed.Map.insert({Input, Output});
+ }
+
+ assert(Cursor && "Error reading address map section");
+ return Parsed;
+}
+
+} // namespace bolt
+} // namespace llvm
diff --git a/bolt/lib/Core/BinaryBasicBlock.cpp b/bolt/lib/Core/BinaryBasicBlock.cpp
index b271b86ec6992..d764a874d08ce 100644
--- a/bolt/lib/Core/BinaryBasicBlock.cpp
+++ b/bolt/lib/Core/BinaryBasicBlock.cpp
@@ -613,27 +613,5 @@ BinaryBasicBlock *BinaryBasicBlock::splitAt(iterator II) {
return NewBlock;
}
-void BinaryBasicBlock::updateOutputValues(const MCAsmLayout &Layout) {
- if (!LocSyms)
- return;
-
- const uint64_t BBAddress = getOutputAddressRange().first;
- const uint64_t BBOffset = Layout.getSymbolOffset(*getLabel());
- for (const auto &LocSymKV : *LocSyms) {
- const uint32_t InputFunctionOffset = LocSymKV.first;
- const uint32_t OutputOffset = static_cast(
- Layout.getSymbolOffset(*LocSymKV.second) - BBOffset);
- getOffsetTranslationTable().emplace_back(
- std::make_pair(OutputOffset, InputFunctionOffset));
-
- // Update reverse (relative to BAT) address lookup table for function.
- if (getFunction()->requiresAddressTranslation()) {
- getFunction()->getInputOffsetToAddressMap().emplace(
- std::make_pair(InputFunctionOffset, OutputOffset + BBAddress));
- }
- }
- LocSyms.reset(nullptr);
-}
-
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index c4129615ac32d..63446575f4b27 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -214,6 +214,10 @@ void BinaryEmitter::emitAll(StringRef OrgSecPrefix) {
}
emitDataSections(OrgSecPrefix);
+
+ // TODO Enable for Mach-O once BinaryContext::getDataSection supports it.
+ if (BC.isELF())
+ AddressMap::emit(Streamer, BC);
}
void BinaryEmitter::emitFunctions() {
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index f6146d9749f59..9ae0c63031082 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -182,9 +182,9 @@ static SMLoc findDebugLineInformationForInstructionAt(
// We use the pointer in SMLoc to store an instance of DebugLineTableRowRef,
// which occupies 64 bits. Thus, we can only proceed if the struct fits into
// the pointer itself.
- assert(sizeof(decltype(SMLoc().getPointer())) >=
- sizeof(DebugLineTableRowRef) &&
- "Cannot fit instruction debug line information into SMLoc's pointer");
+ static_assert(
+ sizeof(decltype(SMLoc().getPointer())) >= sizeof(DebugLineTableRowRef),
+ "Cannot fit instruction debug line information into SMLoc's pointer");
SMLoc NullResult = DebugLineTableRowRef::NULL_ROW.toSMLoc();
uint32_t RowIndex = LineTable->lookupAddress(
@@ -2855,6 +2855,14 @@ bool BinaryFunction::requiresAddressTranslation() const {
return opts::EnableBAT || hasSDTMarker() || hasPseudoProbe();
}
+bool BinaryFunction::requiresAddressMap() const {
+ if (isInjected())
+ return false;
+
+ return opts::UpdateDebugSections || isMultiEntry() ||
+ requiresAddressTranslation();
+}
+
uint64_t BinaryFunction::getInstructionCount() const {
uint64_t Count = 0;
for (const BinaryBasicBlock &BB : blocks())
@@ -4120,15 +4128,13 @@ void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) {
assert(FragmentBaseAddress == getOutputAddress());
}
- const uint64_t BBOffset = Layout.getSymbolOffset(*BB->getLabel());
- const uint64_t BBAddress = FragmentBaseAddress + BBOffset;
+ const uint64_t BBAddress =
+ *BC.getIOAddressMap().lookup(BB->getInputOffset() + getAddress());
BB->setOutputStartAddress(BBAddress);
if (PrevBB)
PrevBB->setOutputEndAddress(BBAddress);
PrevBB = BB;
-
- BB->updateOutputValues(Layout);
}
PrevBB->setOutputEndAddress(PrevBB->isSplit()
@@ -4181,9 +4187,8 @@ uint64_t BinaryFunction::translateInputToOutputAddress(uint64_t Address) const {
// Check if the address is associated with an instruction that is tracked
// by address translation.
- auto KV = InputOffsetToAddressMap.find(Address - getAddress());
- if (KV != InputOffsetToAddressMap.end())
- return KV->second;
+ if (auto OutputAddress = BC.getIOAddressMap().lookup(Address))
+ return *OutputAddress;
// FIXME: #18950828 - we rely on relative offsets inside basic blocks to stay
// intact. Instead we can use pseudo instructions and/or annotations.
diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index a4612fb93f8c3..c913179ebcc51 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_library(LLVMBOLTCore
+ AddressMap.cpp
BinaryBasicBlock.cpp
BinaryContext.cpp
BinaryData.cpp
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index 90405680acf73..223ae714440d9 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -39,6 +39,9 @@
#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
+namespace opts {
+extern cl::opt Verbosity;
+}
namespace llvm {
namespace bolt {
@@ -105,6 +108,14 @@ uint32_t DIEBuilder::allocDIE(const DWARFUnit &DU, const DWARFDie &DDie,
return DWARFUnitInfo.DIEIDMap[DDieOffset];
DIE *Die = DIE::get(Alloc, dwarf::Tag(DDie.getTag()));
+ // This handles the case where there is a DIE ref which points to
+ // invalid DIE. This prevents assert when IR is written out.
+ // Also it makes debugging easier.
+ // DIE dump is not very useful.
+ // It's nice to know original offset from which this DIE was constructed.
+ Die->setOffset(DDie.getOffset());
+ if (opts::Verbosity >= 1)
+ getState().DWARFDieAddressesParsed.insert(DDie.getOffset());
const uint32_t DId = DWARFUnitInfo.DieInfoVector.size();
DWARFUnitInfo.DIEIDMap[DDieOffset] = DId;
DWARFUnitInfo.DieInfoVector.emplace_back(
@@ -290,10 +301,6 @@ DIE *DIEBuilder::constructDIEFast(DWARFDie &DDie, DWARFUnit &U,
DIEInfo &DieInfo = getDIEInfo(UnitId, *Idx);
uint64_t Offset = DDie.getOffset();
- // Just for making debugging easier.
- // DIE dump is not very useful.
- // It's nice to know original offset from which this DIE was constructed.
- DieInfo.Die->setOffset(Offset);
uint64_t NextOffset = Offset;
DWARFDataExtractor Data = U.getDebugInfoExtractor();
DWARFDebugInfoEntry DDIEntry;
@@ -369,6 +376,7 @@ getUnitForOffset(DIEBuilder &Builder, DWARFContext &DWCtx,
uint32_t DIEBuilder::computeDIEOffset(const DWARFUnit &CU, DIE &Die,
uint32_t &CurOffset) {
+ getState().DWARFDieAddressesParsed.erase(Die.getOffset());
uint32_t CurSize = 0;
Die.setOffset(CurOffset);
for (DIEValue &Val : Die.values())
@@ -421,6 +429,13 @@ void DIEBuilder::finish() {
continue;
computeOffset(*CU, UnitSize);
}
+ if (opts::Verbosity >= 1) {
+ if (!getState().DWARFDieAddressesParsed.empty())
+ dbgs() << "Referenced DIE offsets not in .debug_info\n";
+ for (const uint64_t Address : getState().DWARFDieAddressesParsed) {
+ dbgs() << Twine::utohexstr(Address) << "\n";
+ }
+ }
updateReferences();
}
@@ -457,11 +472,20 @@ DWARFDie DIEBuilder::resolveDIEReference(
allocDIE(*RefCU, RefDie, getState().DIEAlloc, *UnitId);
return RefDie;
}
+ errs() << "BOLT-WARNING: [internal-dwarf-error]: invalid referenced DIE "
+ "at offset: "
+ << Twine::utohexstr(RefOffset) << ".\n";
+
+ } else {
+ errs() << "BOLT-WARNING: [internal-dwarf-error]: could not parse "
+ "referenced DIE at offset: "
+ << Twine::utohexstr(RefOffset) << ".\n";
}
+ } else {
+ errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
+ "CU. Referenced DIE offset: "
+ << Twine::utohexstr(RefOffset) << ".\n";
}
-
- errs() << "BOLT-WARNING: [internal-dwarf-error]: could not find referenced "
- "CU.\n";
return DWARFDie();
}
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 28b3977c6edc5..8d24c9281b8f2 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -414,25 +414,6 @@ uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
return Entry->second;
}
-// Case1) Address is not in map insert in to AddresToIndex and IndexToAddres
-// Case2) Address is in the map but Index is higher or equal. Need to update
-// IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
-// update AddressToIndex and IndexToAddress
-void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
- DWARFUnit &CU) {
- std::lock_guard Lock(WriterMutex);
- const uint64_t CUID = getCUID(CU);
- AddressForDWOCU &Map = AddressMaps[CUID];
- auto Entry = Map.find(Address);
- if (Entry != Map.end()) {
- if (Entry->second > Index)
- Map.updateAddressToIndex(Address, Index);
- Map.updateIndexToAddrss(Address, Index);
- } else {
- Map.insert(Address, Index);
- }
-}
-
static void updateAddressBase(DIEBuilder &DIEBlder, DebugAddrWriter &AddrWriter,
DWARFUnit &CU, const uint64_t Offset) {
DIE *Die = DIEBlder.getUnitDIEbyUnit(CU);
diff --git a/bolt/lib/Passes/RegReAssign.cpp b/bolt/lib/Passes/RegReAssign.cpp
index 19e1a84c48d1b..0efd27f0910b4 100644
--- a/bolt/lib/Passes/RegReAssign.cpp
+++ b/bolt/lib/Passes/RegReAssign.cpp
@@ -140,7 +140,7 @@ void RegReAssign::rankRegisters(BinaryFunction &Function) {
std::fill(RegScore.begin(), RegScore.end(), 0);
std::fill(RankedRegs.begin(), RankedRegs.end(), 0);
- for (BinaryBasicBlock &BB : Function) {
+ auto countRegScore = [&](BinaryBasicBlock &BB) {
for (MCInst &Inst : BB) {
const bool CannotUseREX = BC.MIB->cannotUseREX(Inst);
const MCInstrDesc &Desc = BC.MII->get(Inst.getOpcode());
@@ -191,7 +191,15 @@ void RegReAssign::rankRegisters(BinaryFunction &Function) {
RegScore[RegEC] += BB.getKnownExecutionCount();
}
}
+ };
+ for (BinaryBasicBlock &BB : Function)
+ countRegScore(BB);
+
+ for (BinaryFunction *ChildFrag : Function.getFragments()) {
+ for (BinaryBasicBlock &BB : *ChildFrag)
+ countRegScore(BB);
}
+
std::iota(RankedRegs.begin(), RankedRegs.end(), 0); // 0, 1, 2, 3...
llvm::sort(RankedRegs,
[&](size_t A, size_t B) { return RegScore[A] > RegScore[B]; });
@@ -213,6 +221,17 @@ void RegReAssign::aggressivePassOverFunction(BinaryFunction &Function) {
BinaryContext &BC = Function.getBinaryContext();
rankRegisters(Function);
+ // If there is a situation where function:
+ // A() -> A.cold()
+ // A.localalias() -> A.cold()
+ // simply swapping these two calls can cause issues.
+ for (BinaryFunction *ChildFrag : Function.getFragments()) {
+ if (ChildFrag->getParentFragments()->size() > 1)
+ return;
+ if (ChildFrag->empty())
+ return;
+ }
+
// Bail early if our registers are all black listed, before running expensive
// analysis passes
bool Bail = true;
@@ -304,6 +323,10 @@ void RegReAssign::aggressivePassOverFunction(BinaryFunction &Function) {
<< " with " << BC.MRI->getName(ExtReg) << "\n\n");
swap(Function, ClassicReg, ExtReg);
FuncsChanged.insert(&Function);
+ for (BinaryFunction *ChildFrag : Function.getFragments()) {
+ swap(*ChildFrag, ClassicReg, ExtReg);
+ FuncsChanged.insert(ChildFrag);
+ }
++Begin;
if (Begin == End)
break;
@@ -315,6 +338,13 @@ bool RegReAssign::conservativePassOverFunction(BinaryFunction &Function) {
BinaryContext &BC = Function.getBinaryContext();
rankRegisters(Function);
+ for (BinaryFunction *ChildFrag : Function.getFragments()) {
+ if (ChildFrag->getParentFragments()->size() > 1)
+ return false;
+ if (ChildFrag->empty())
+ return false;
+ }
+
// Try swapping R12, R13, R14 or R15 with RBX (we work with all callee-saved
// regs except RBP)
MCPhysReg Candidate = 0;
@@ -345,6 +375,10 @@ bool RegReAssign::conservativePassOverFunction(BinaryFunction &Function) {
(void)BC;
swap(Function, RBX, Candidate);
FuncsChanged.insert(&Function);
+ for (BinaryFunction *ChildFrag : Function.getFragments()) {
+ swap(*ChildFrag, RBX, Candidate);
+ FuncsChanged.insert(ChildFrag);
+ }
return true;
}
@@ -404,7 +438,7 @@ void RegReAssign::runOnFunctions(BinaryContext &BC) {
for (auto &I : BC.getBinaryFunctions()) {
BinaryFunction &Function = I.second;
- if (!Function.isSimple() || Function.isIgnored())
+ if (!Function.isSimple() || Function.isIgnored() || Function.isFragment())
continue;
LLVM_DEBUG(dbgs() << "====================================\n");
diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp
index 678c3d8fe6a90..72d58a4327eb8 100644
--- a/bolt/lib/Passes/ReorderFunctions.cpp
+++ b/bolt/lib/Passes/ReorderFunctions.cpp
@@ -284,27 +284,37 @@ void ReorderFunctions::runOnFunctions(BinaryContext &BC) {
break;
case RT_EXEC_COUNT: {
std::vector SortedFunctions(BFs.size());
- uint32_t Index = 0;
llvm::transform(llvm::make_second_range(BFs), SortedFunctions.begin(),
[](BinaryFunction &BF) { return &BF; });
- llvm::stable_sort(SortedFunctions, [&](const BinaryFunction *A,
- const BinaryFunction *B) {
- if (A->isIgnored())
- return false;
- const size_t PadA = opts::padFunction(*A);
- const size_t PadB = opts::padFunction(*B);
- if (!PadA || !PadB) {
- if (PadA)
- return true;
- if (PadB)
- return false;
- }
- return !A->hasProfile() && (B->hasProfile() || (A->getExecutionCount() >
- B->getExecutionCount()));
- });
+ llvm::stable_sort(SortedFunctions,
+ [&](const BinaryFunction *A, const BinaryFunction *B) {
+ if (A->isIgnored())
+ return false;
+ if (B->isIgnored())
+ return true;
+ const size_t PadA = opts::padFunction(*A);
+ const size_t PadB = opts::padFunction(*B);
+ if (!PadA || !PadB) {
+ if (PadA)
+ return true;
+ if (PadB)
+ return false;
+ }
+ if (!A->hasProfile())
+ return false;
+ if (!B->hasProfile())
+ return true;
+ return A->getExecutionCount() > B->getExecutionCount();
+ });
+ uint32_t Index = 0;
for (BinaryFunction *BF : SortedFunctions)
- if (BF->hasProfile())
+ if (BF->hasProfile()) {
BF->setIndex(Index++);
+ LLVM_DEBUG(if (opts::Verbosity > 1) {
+ dbgs() << "BOLT-INFO: hot func " << BF->getPrintName() << " ("
+ << BF->getExecutionCount() << ")\n";
+ });
+ }
} break;
case RT_HFSORT:
Clusters = clusterize(Cg);
diff --git a/bolt/lib/Profile/BoltAddressTranslation.cpp b/bolt/lib/Profile/BoltAddressTranslation.cpp
index 57a850eb17234..e004309e0e213 100644
--- a/bolt/lib/Profile/BoltAddressTranslation.cpp
+++ b/bolt/lib/Profile/BoltAddressTranslation.cpp
@@ -46,9 +46,14 @@ void BoltAddressTranslation::writeEntriesForBB(MapTy &Map,
// allowing it to overwrite the previously inserted key in the map.
Map[BBOutputOffset] = BBInputOffset;
- for (const auto &IOPair : BB.getOffsetTranslationTable()) {
- const uint64_t OutputOffset = IOPair.first + BBOutputOffset;
- const uint32_t InputOffset = IOPair.second;
+ const auto &IOAddressMap =
+ BB.getFunction()->getBinaryContext().getIOAddressMap();
+
+ for (const auto &[InputOffset, Sym] : BB.getLocSyms()) {
+ const auto InputAddress = BB.getFunction()->getAddress() + InputOffset;
+ const auto OutputAddress = IOAddressMap.lookup(InputAddress);
+ assert(OutputAddress && "Unknown instruction address");
+ const auto OutputOffset = *OutputAddress - FuncAddress;
// Is this the first instruction in the BB? No need to duplicate the entry.
if (OutputOffset == BBOutputOffset)
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 2262115d97000..a638d97fdb030 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -57,7 +57,6 @@
#undef DEBUG_TYPE
#define DEBUG_TYPE "bolt"
-LLVM_ATTRIBUTE_UNUSED
static void printDie(const DWARFDie &DIE) {
DIDumpOptions DumpOpts;
DumpOpts.ShowForm = true;
@@ -67,6 +66,28 @@ static void printDie(const DWARFDie &DIE) {
DIE.dump(dbgs(), 0, DumpOpts);
}
+/// Lazily parse DWARF DIE and print it out.
+LLVM_ATTRIBUTE_UNUSED
+static void printDie(DWARFUnit &DU, uint64_t DIEOffset) {
+ uint64_t OriginalOffsets = DIEOffset;
+ uint64_t NextCUOffset = DU.getNextUnitOffset();
+ DWARFDataExtractor DebugInfoData = DU.getDebugInfoExtractor();
+ DWARFDebugInfoEntry DIEEntry;
+ if (DIEEntry.extractFast(DU, &DIEOffset, DebugInfoData, NextCUOffset, 0)) {
+ if (const DWARFAbbreviationDeclaration *AbbrDecl =
+ DIEEntry.getAbbreviationDeclarationPtr()) {
+ DWARFDie DDie(&DU, &DIEEntry);
+ printDie(DDie);
+ } else {
+ dbgs() << "Failed to extract abbreviation for"
+ << Twine::utohexstr(OriginalOffsets) << "\n";
+ }
+ } else {
+ dbgs() << "Failed to extract DIE for " << Twine::utohexstr(OriginalOffsets)
+ << " \n";
+ }
+}
+
namespace llvm {
namespace bolt {
/// Emits debug information into .debug_info or .debug_types section.
@@ -521,32 +542,34 @@ void DWARFRewriter::updateDebugInfo() {
DebugLoclistWriter::setAddressWriter(AddrWriter.get());
- size_t CUIndex = 0;
- for (std::unique_ptr &CU : BC.DwCtx->compile_units()) {
- const uint16_t DwarfVersion = CU->getVersion();
+ uint32_t CUIndex = 0;
+ std::mutex AccessMutex;
+ // Needs to be invoked in the same order as CUs are processed.
+ auto createRangeLocList = [&](DWARFUnit &CU) -> DebugLocWriter * {
+ std::lock_guard Lock(AccessMutex);
+ const uint16_t DwarfVersion = CU.getVersion();
if (DwarfVersion >= 5) {
LocListWritersByCU[CUIndex] =
- std::make_unique(*CU.get(), DwarfVersion, false);
+ std::make_unique(CU, DwarfVersion, false);
- if (std::optional DWOId = CU->getDWOId()) {
+ if (std::optional DWOId = CU.getDWOId()) {
assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
"RangeLists writer for DWO unit already exists.");
auto RangeListsSectionWriter =
std::make_unique();
- RangeListsSectionWriter->initSection(*CU.get());
+ RangeListsSectionWriter->initSection(CU);
RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter);
}
} else {
LocListWritersByCU[CUIndex] = std::make_unique();
}
- ++CUIndex;
- }
+ return LocListWritersByCU[CUIndex++].get();
+ };
// Unordered maps to handle name collision if output DWO directory is
// specified.
std::unordered_map NameToIndexMap;
- std::mutex AccessMutex;
auto updateDWONameCompDir = [&](DWARFUnit &Unit, DIEBuilder &DIEBldr,
DIE &UnitDIE) -> std::string {
@@ -576,8 +599,7 @@ void DWARFRewriter::updateDebugInfo() {
DWPState State;
if (opts::WriteDWP)
initDWPState(State);
- auto processUnitDIE = [&](size_t CUIndex, DWARFUnit *Unit,
- DIEBuilder *DIEBlder) {
+ auto processUnitDIE = [&](DWARFUnit *Unit, DIEBuilder *DIEBlder) {
// Check if the unit is a skeleton and we need special updates for it and
// its matching split/DWO CU.
std::optional SplitCU;
@@ -587,8 +609,7 @@ void DWARFRewriter::updateDebugInfo() {
Unit->getStringOffsetsTableContribution());
if (DWOId)
SplitCU = BC.getDWOCU(*DWOId);
-
- DebugLocWriter *DebugLocWriter = nullptr;
+ DebugLocWriter *DebugLocWriter = createRangeLocList(*Unit);
DebugRangesSectionWriter *RangesSectionWriter =
Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
: LegacyRangesSectionWriter.get();
@@ -624,12 +645,6 @@ void DWARFRewriter::updateDebugInfo() {
DebugLocDWoWriter);
}
- {
- std::lock_guard Lock(AccessMutex);
- auto LocListWriterIter = LocListWritersByCU.find(CUIndex);
- if (LocListWriterIter != LocListWritersByCU.end())
- DebugLocWriter = LocListWriterIter->second.get();
- }
if (Unit->getVersion() >= 5) {
RangesBase = RangesSectionWriter->getSectionOffset() +
getDWARF5RngListLocListHeaderSize();
@@ -645,7 +660,6 @@ void DWARFRewriter::updateDebugInfo() {
AddrWriter->update(*DIEBlder, *Unit);
};
- CUIndex = 0;
DIEBuilder DIEBlder(BC.DwCtx.get());
DIEBlder.buildTypeUnits();
SmallVector OutBuffer;
@@ -666,17 +680,15 @@ void DWARFRewriter::updateDebugInfo() {
for (std::vector &Vec : PartVec) {
DIEBlder.buildCompileUnits(Vec);
for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
- processUnitDIE(CUIndex++, CU, &DIEBlder);
+ processUnitDIE(CU, &DIEBlder);
finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
DIEBlder.getProcessedCUs());
}
} else {
// Update unit debug info in parallel
ThreadPool &ThreadPool = ParallelUtilities::getThreadPool();
- for (std::unique_ptr &CU : BC.DwCtx->compile_units()) {
- ThreadPool.async(processUnitDIE, CUIndex, CU.get(), &DIEBlder);
- CUIndex++;
- }
+ for (std::unique_ptr &CU : BC.DwCtx->compile_units())
+ ThreadPool.async(processUnitDIE, CU.get(), &DIEBlder);
ThreadPool.wait();
}
@@ -1102,46 +1114,31 @@ void DWARFRewriter::updateUnitDebugInfo(
DIEBldr.addValue(NewAttr, *Itr);
std::advance(Itr, 1);
}
- PrevOffset = CurEndOffset;
- continue;
- }
-
- const uint64_t Index = Expr.getRawOperand(0);
- std::optional EntryAddress =
- Unit.getAddrOffsetSectionItem(Index);
- assert(EntryAddress && "Address is not found.");
- assert(Index <= std::numeric_limits::max() &&
- "Invalid Operand Index.");
- if (Expr.getCode() == dwarf::DW_OP_addrx) {
- const uint32_t Index = AddrWriter->getIndexFromAddress(
+ } else {
+ const uint64_t Index = Expr.getRawOperand(0);
+ std::optional EntryAddress =
+ Unit.getAddrOffsetSectionItem(Index);
+ assert(EntryAddress && "Address is not found.");
+ assert(Index <= std::numeric_limits::max() &&
+ "Invalid Operand Index.");
+ const uint32_t AddrIndex = AddrWriter->getIndexFromAddress(
EntryAddress->Address, Unit);
- // update Index for DW_AT_location. The Size field is not stored
- // in IR, we need to minus 1 in offset for each expr.
+ // update Index into .debug_address section for DW_AT_location.
+ // The Size field is not stored in IR, we need to minus 1 in
+ // offset for each expr.
SmallString<8> Tmp;
raw_svector_ostream OSE(Tmp);
- encodeULEB128(Index, OSE);
+ encodeULEB128(AddrIndex, OSE);
DIEBldr.addValue(NewAttr, static_cast(0),
dwarf::DW_FORM_data1,
- DIEInteger(dwarf::DW_OP_addrx));
+ DIEInteger(Expr.getCode()));
NewExprSize += 1;
for (uint8_t Byte : Tmp) {
DIEBldr.addValue(NewAttr, static_cast(0),
dwarf::DW_FORM_data1, DIEInteger(Byte));
NewExprSize += 1;
}
- } else {
- // TODO: Re-do this as DWARF5.
- auto Itr = AttrLocValList->values().begin();
- std::advance(Itr, PrevOffset);
- uint32_t CopyNum = CurEndOffset - PrevOffset;
- NewExprSize += CopyNum;
- while (CopyNum--) {
- DIEBldr.addValue(NewAttr, *Itr);
- std::advance(Itr, 1);
- }
- AddrWriter->addIndexAddress(EntryAddress->Address,
- static_cast(Index), Unit);
}
PrevOffset = CurEndOffset;
}
@@ -1175,18 +1172,8 @@ void DWARFRewriter::updateUnitDebugInfo(
assert(Form != dwarf::DW_FORM_LLVM_addrx_offset &&
"DW_FORM_LLVM_addrx_offset is not supported");
std::lock_guard Lock(DWARFRewriterMutex);
- if (Form == dwarf::DW_FORM_GNU_addr_index) {
- // If there is no new address, storing old address.
- // Re-using Index to make implementation easier.
- // DW_FORM_GNU_addr_index is variable lenght encoding
- // so we either have to create indices of same sizes, or use same
- // index.
- // TODO: We can now re-write .debug_info. This can be simplified to
- // just getting a new index and creating a patch.
- const uint64_t Index = *Result;
- AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address,
- Index, Unit);
- } else if (Form == dwarf::DW_FORM_addrx) {
+ if (Form == dwarf::DW_FORM_addrx ||
+ Form == dwarf::DW_FORM_GNU_addr_index) {
const uint32_t Index = AddrWriter->getIndexFromAddress(
NewAddress ? NewAddress : Address, Unit);
DIEBldr.replaceValue(Die, LowPCAttrInfo.getAttribute(),
diff --git a/bolt/lib/Rewrite/PseudoProbeRewriter.cpp b/bolt/lib/Rewrite/PseudoProbeRewriter.cpp
index 64b8a8b6d400f..316b83cfbd38a 100644
--- a/bolt/lib/Rewrite/PseudoProbeRewriter.cpp
+++ b/bolt/lib/Rewrite/PseudoProbeRewriter.cpp
@@ -183,9 +183,7 @@ void PseudoProbeRewriter::updatePseudoProbes() {
// A call probe may be duplicated due to ICP
// Go through output of InputOffsetToAddressMap to collect all related
// probes
- const InputOffsetToAddressMapTy &Offset2Addr =
- F->getInputOffsetToAddressMap();
- auto CallOutputAddresses = Offset2Addr.equal_range(Offset);
+ auto CallOutputAddresses = BC.getIOAddressMap().lookupAll(AP.first);
auto CallOutputAddress = CallOutputAddresses.first;
if (CallOutputAddress == CallOutputAddresses.second) {
Probe->setAddress(INT64_MAX);
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 551527f4c678f..31babd2de802c 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "bolt/Rewrite/RewriteInstance.h"
+#include "bolt/Core/AddressMap.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryEmitter.h"
#include "bolt/Core/BinaryFunction.h"
@@ -3170,6 +3171,9 @@ void RewriteInstance::preregisterSections() {
ROFlags);
BC->registerOrUpdateSection(getNewSecPrefix() + ".rodata.cold",
ELF::SHT_PROGBITS, ROFlags);
+ BC->registerOrUpdateSection(AddressMap::SectionName, ELF::SHT_PROGBITS,
+ ROFlags)
+ .setLinkOnly();
}
void RewriteInstance::emitAndLink() {
@@ -3575,6 +3579,9 @@ void RewriteInstance::mapAllocatableSections(
}
for (BinarySection &Section : BC->allocatableSections()) {
+ if (Section.isLinkOnly())
+ continue;
+
if (!Section.hasValidSectionID())
continue;
@@ -3637,6 +3644,12 @@ void RewriteInstance::mapAllocatableSections(
}
void RewriteInstance::updateOutputValues(const MCAsmLayout &Layout) {
+ if (auto MapSection = BC->getUniqueSectionByName(AddressMap::SectionName)) {
+ auto Map = AddressMap::parse(MapSection->getOutputContents(), *BC);
+ BC->setIOAddressMap(std::move(Map));
+ BC->deregisterSection(*MapSection);
+ }
+
for (BinaryFunction *Function : BC->getAllBinaryFunctions())
Function->updateOutputValues(Layout);
}
@@ -5282,6 +5295,8 @@ void RewriteInstance::rewriteFile() {
for (BinarySection &Section : BC->allocatableSections()) {
if (!Section.isFinalized() || !Section.getOutputData())
continue;
+ if (Section.isLinkOnly())
+ continue;
if (opts::Verbosity >= 1)
outs() << "BOLT: writing new section " << Section.getName()
diff --git a/bolt/test/X86/Inputs/dwarf4-cross-cu-with-loclist.s b/bolt/test/X86/Inputs/dwarf4-cross-cu-with-loclist.s
new file mode 100644
index 0000000000000..3d3b43103bded
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf4-cross-cu-with-loclist.s
@@ -0,0 +1,550 @@
+# clang++ main.cpp -O1 -g2 -gdwarf-4 -emit-llvm -c -o mainLL.o
+# clang++ helper1.cpp -O1 -g2 -gdwarf-4 -emit-llvm -c -o helper1LL.o
+# llvm-link mainLL.o helper1LL.o -S -o linked.ll
+# clang++ -O1 linked.ll -g2 -gdwarf-4 -S -o combinedTest.s
+
+# main.cpp
+# struct Foo {
+# int x;
+# int y;
+# };
+# inline __attribute__((always_inline))
+# static int helper(Foo &f) {
+# return f.x + 3;
+# }
+# int main(int argc, char *argv[]) {
+# Foo foo;
+# foo.x = argc;
+# foo.y = 3;
+# return helper(foo) + foo.x + foo.y;
+# }
+# helper1.cpp
+# struct Foo2 {
+# int x;
+# int y;
+# };
+# inline __attribute__((always_inline))
+# static int helper(Foo2 &f) {
+# return f.x + 3;
+# }
+# int foo2(int i) {
+# Foo2 foo;
+# foo.x = i;
+# foo.y = 3;
+# return helper(foo);
+# }
+
+ .text
+ .file "llvm-link"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: main:argc <- $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ #DEBUG_VALUE: main:foo <- [DW_OP_LLVM_fragment 0 32] $edi
+ # kill: def $edi killed $edi def $rdi
+ #DEBUG_VALUE: main:foo <- [DW_OP_LLVM_fragment 32 32] 3
+ .file 1 "/dwarf4CrossCULocList" "main.cpp"
+ .loc 1 13 30 prologue_end # main.cpp:13:30
+ leal 6(,%rdi,2), %eax
+ .loc 1 13 3 is_stmt 0 # main.cpp:13:3
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .globl _Z4foo2i # -- Begin function _Z4foo2i
+ .p2align 4, 0x90
+ .type _Z4foo2i,@function
+_Z4foo2i: # @_Z4foo2i
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: foo2:i <- $edi
+ #DEBUG_VALUE: foo2:foo <- [DW_OP_LLVM_fragment 0 32] $edi
+ # kill: def $edi killed $edi def $rdi
+ #DEBUG_VALUE: foo2:foo <- [DW_OP_LLVM_fragment 32 32] 3
+ .file 2 "/dwarf4CrossCULocList" "helper1.cpp"
+ .loc 2 7 14 prologue_end is_stmt 1 # helper1.cpp:7:14
+ leal 3(%rdi), %eax
+.Ltmp1:
+ .loc 2 13 3 # helper1.cpp:13:3
+ retq
+.Ltmp2:
+.Lfunc_end1:
+ .size _Z4foo2i, .Lfunc_end1-_Z4foo2i
+ .cfi_endproc
+ # -- End function
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+ .quad .Lfunc_begin0-.Lfunc_begin0
+ .quad .Lfunc_end0-.Lfunc_begin0
+ .short 7 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .byte 51 # DW_OP_lit3
+ .byte 159 # DW_OP_stack_value
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .quad 0
+ .quad 0
+.Ldebug_loc1:
+ .quad .Lfunc_begin1-.Lfunc_begin1
+ .quad .Lfunc_end1-.Lfunc_begin1
+ .short 7 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .byte 51 # DW_OP_lit3
+ .byte 159 # DW_OP_stack_value
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .quad 0
+ .quad 0
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 32 # DW_AT_inline
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 12 # Abbreviation Code
+ .byte 16 # DW_TAG_reference_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 13 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 14 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 15 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x96 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 2 # Abbrev [2] 0x2a:0x43 DW_TAG_subprogram
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string11 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long .debug_info+231 # DW_AT_type
+ # DW_AT_external
+ .byte 3 # Abbrev [3] 0x43:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .long .Linfo_string14 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long .debug_info+231 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x50:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string15 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 109 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x5d:0xf DW_TAG_variable
+ .long .Ldebug_loc0 # DW_AT_location
+ .long .Linfo_string17 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 126 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x6d:0x5 DW_TAG_pointer_type
+ .long 114 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x72:0x5 DW_TAG_pointer_type
+ .long 119 # DW_AT_type
+ .byte 7 # Abbrev [7] 0x77:0x7 DW_TAG_base_type
+ .long .Linfo_string16 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 8 # Abbrev [8] 0x7e:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .long .Linfo_string18 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 9 # Abbrev [9] 0x87:0xc DW_TAG_member
+ .long .Linfo_string8 # DW_AT_name
+ .long .debug_info+231 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 9 # Abbrev [9] 0x93:0xc DW_TAG_member
+ .long .Linfo_string9 # DW_AT_name
+ .long .debug_info+231 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+.Lcu_begin1:
+ .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xb8 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string3 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 10 # Abbrev [10] 0x2a:0x1c DW_TAG_subprogram
+ .long .Linfo_string4 # DW_AT_linkage_name
+ .long .Linfo_string5 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 70 # DW_AT_type
+ .byte 1 # DW_AT_inline
+ .byte 11 # Abbrev [11] 0x3a:0xb DW_TAG_formal_parameter
+ .long .Linfo_string7 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 77 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 7 # Abbrev [7] 0x46:0x7 DW_TAG_base_type
+ .long .Linfo_string6 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 12 # Abbrev [12] 0x4d:0x5 DW_TAG_reference_type
+ .long 82 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x52:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .long .Linfo_string10 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 2 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 13 # Abbrev [13] 0x5b:0xc DW_TAG_member
+ .long .Linfo_string8 # DW_AT_name
+ .long 70 # DW_AT_type
+ .byte 2 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 13 # Abbrev [13] 0x67:0xc DW_TAG_member
+ .long .Linfo_string9 # DW_AT_name
+ .long 70 # DW_AT_type
+ .byte 2 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 14 # Abbrev [14] 0x74:0x4e DW_TAG_subprogram
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string12 # DW_AT_linkage_name
+ .long .Linfo_string13 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 70 # DW_AT_type
+ # DW_AT_external
+ .byte 4 # Abbrev [4] 0x91:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .long .Linfo_string19 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 70 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x9e:0xf DW_TAG_variable
+ .long .Ldebug_loc1 # DW_AT_location
+ .long .Linfo_string17 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 82 # DW_AT_type
+ .byte 15 # Abbrev [15] 0xad:0x14 DW_TAG_inlined_subroutine
+ .long 42 # DW_AT_abstract_origin
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Ltmp1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 2 # DW_AT_call_file
+ .byte 13 # DW_AT_call_line
+ .byte 10 # DW_AT_call_column
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end1:
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/dwarf4CrossCULocList" # string offset=110
+.Linfo_string3:
+ .asciz "helper1.cpp" # string offset=169
+.Linfo_string4:
+ .asciz "_ZL6helperR4Foo2" # string offset=181
+.Linfo_string5:
+ .asciz "helper" # string offset=198
+.Linfo_string6:
+ .asciz "int" # string offset=205
+.Linfo_string7:
+ .asciz "f" # string offset=209
+.Linfo_string8:
+ .asciz "x" # string offset=211
+.Linfo_string9:
+ .asciz "y" # string offset=213
+.Linfo_string10:
+ .asciz "Foo2" # string offset=215
+.Linfo_string11:
+ .asciz "main" # string offset=220
+.Linfo_string12:
+ .asciz "_Z4foo2i" # string offset=225
+.Linfo_string13:
+ .asciz "foo2" # string offset=234
+.Linfo_string14:
+ .asciz "argc" # string offset=239
+.Linfo_string15:
+ .asciz "argv" # string offset=244
+.Linfo_string16:
+ .asciz "char" # string offset=249
+.Linfo_string17:
+ .asciz "foo" # string offset=254
+.Linfo_string18:
+ .asciz "Foo" # string offset=258
+.Linfo_string19:
+ .asciz "i" # string offset=262
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-helper.s b/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-helper.s
new file mode 100644
index 0000000000000..75ffbf00d6fca
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-helper.s
@@ -0,0 +1,352 @@
+# clang++ -O2 -g -gdwarf-4 -gsplit-dwarf
+# int z = 0;
+# int d = 0;
+# int helper(int z_, int d_) {
+# z += z_;
+# d += d_;
+# return z * d;
+# }
+
+ .text
+ .file "helper.cpp"
+ .file 1 "." "helper.cpp"
+ .globl _Z6helperii # -- Begin function _Z6helperii
+ .p2align 4, 0x90
+ .type _Z6helperii,@function
+_Z6helperii: # @_Z6helperii
+.Lfunc_begin0:
+ .loc 1 3 0 # helper.cpp:3:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: helper:z_ <- $edi
+ #DEBUG_VALUE: helper:d_ <- $esi
+ movl %esi, %eax
+.Ltmp0:
+ .loc 1 4 4 prologue_end # helper.cpp:4:4
+ addl z(%rip), %edi
+.Ltmp1:
+ #DEBUG_VALUE: helper:z_ <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 1 5 4 # helper.cpp:5:4
+ addl d(%rip), %eax
+ .loc 1 4 4 # helper.cpp:4:4
+ movl %edi, z(%rip)
+ .loc 1 5 4 # helper.cpp:5:4
+ movl %eax, d(%rip)
+ .loc 1 6 11 # helper.cpp:6:11
+ imull %edi, %eax
+ .loc 1 6 2 is_stmt 0 # helper.cpp:6:2
+ retq
+.Ltmp2:
+.Lfunc_end0:
+ .size _Z6helperii, .Lfunc_end0-_Z6helperii
+ .cfi_endproc
+ # -- End function
+ .type z,@object # @z
+ .bss
+ .globl z
+ .p2align 2, 0x0
+z:
+ .long 0 # 0x0
+ .size z, 4
+
+ .type d,@object # @d
+ .globl d
+ .p2align 2, 0x0
+d:
+ .long 0 # 0x0
+ .size d, 4
+
+ .section .debug_loc.dwo,"e",@progbits
+.Ldebug_loc0:
+ .byte 3
+ .byte 2
+ .long .Ltmp1-.Lfunc_begin0
+ .short 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 3
+ .byte 3
+ .long .Lfunc_end0-.Ltmp1
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .byte 14 # DW_FORM_strp
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .ascii "\263B" # DW_AT_GNU_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lskel_string0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .long .Lskel_string1 # DW_AT_GNU_dwo_name
+ .quad -7229095317601456558 # DW_AT_GNU_dwo_id
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_GNU_addr_base
+.Ldebug_info_end0:
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "helper.dwo" # string offset=47
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "z" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=2
+.Linfo_string2:
+ .asciz "d" # string offset=6
+.Linfo_string3:
+ .asciz "_Z6helperii" # string offset=8
+.Linfo_string4:
+ .asciz "helper" # string offset=20
+.Linfo_string5:
+ .asciz "z_" # string offset=27
+.Linfo_string6:
+ .asciz "d_" # string offset=30
+.Linfo_string7:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=33
+.Linfo_string8:
+ .asciz "helper.cpp" # string offset=134
+.Linfo_string9:
+ .asciz "helper.dwo" # string offset=145
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 2
+ .long 6
+ .long 8
+ .long 20
+ .long 27
+ .long 30
+ .long 33
+ .long 134
+ .long 145
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x50 DW_TAG_compile_unit
+ .byte 7 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 8 # DW_AT_name
+ .byte 9 # DW_AT_GNU_dwo_name
+ .quad -7229095317601456558 # DW_AT_GNU_dwo_id
+ .byte 2 # Abbrev [2] 0x19:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 0
+ .byte 3 # Abbrev [3] 0x24:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 2 # Abbrev [2] 0x28:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 1
+ .byte 4 # Abbrev [4] 0x33:0x27 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x43:0xc DW_TAG_formal_parameter
+ .long .Ldebug_loc0-.debug_loc.dwo # DW_AT_location
+ .byte 5 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x4f:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .byte 6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"",@progbits
+.Laddr_table_base0:
+ .quad z
+ .quad d
+ .quad .Lfunc_begin0
+ .quad .Ltmp1
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 48 # Compilation Unit Length
+ .long 25 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "z" # External Name
+ .long 40 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "d" # External Name
+ .long 51 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "helper" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 48 # Compilation Unit Length
+ .long 36 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-main.s b/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-main.s
new file mode 100644
index 0000000000000..36cb91b4d276a
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf4-df-call-site-change-low-pc-main.s
@@ -0,0 +1,513 @@
+# clang++ -O2 -g -gdwarf-4 -gsplit-dwarf
+# void use(int * x, int * y) {
+# *x += 4;
+# *y -= 2;
+# }
+#
+# int helper(int z_, int d_);
+# int x = 0;
+# int y = 1;
+# int main(int argc, char *argv[]) {
+# x = argc;
+# y = argc + 3;
+# //use(&x, &y);
+# return helper(x, y);
+# }
+
+ .text
+ .file "main.cpp"
+ .file 1 "." "main.cpp"
+ .globl _Z3usePiS_ # -- Begin function _Z3usePiS_
+ .p2align 4, 0x90
+ .type _Z3usePiS_,@function
+_Z3usePiS_: # @_Z3usePiS_
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: use:x <- $rdi
+ #DEBUG_VALUE: use:y <- $rsi
+ .loc 1 2 5 prologue_end # main.cpp:2:5
+ addl $4, (%rdi)
+ .loc 1 3 5 # main.cpp:3:5
+ addl $-2, (%rsi)
+ .loc 1 4 1 # main.cpp:4:1
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: main:argc <- $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ # kill: def $edi killed $edi def $rdi
+ .loc 1 10 6 prologue_end # main.cpp:10:6
+ movl %edi, x(%rip)
+ .loc 1 11 13 # main.cpp:11:13
+ leal 3(%rdi), %esi
+.Ltmp1:
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 1 11 6 is_stmt 0 # main.cpp:11:6
+ movl %esi, y(%rip)
+ # kill: def $edi killed $edi killed $rdi
+.Ltmp2:
+ .loc 1 13 11 is_stmt 1 # main.cpp:13:11
+ jmp _Z6helperii@PLT # TAILCALL
+.Ltmp3:
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .type x,@object # @x
+ .bss
+ .globl x
+ .p2align 2, 0x0
+x:
+ .long 0 # 0x0
+ .size x, 4
+
+ .type y,@object # @y
+ .data
+ .globl y
+ .p2align 2, 0x0
+y:
+ .long 1 # 0x1
+ .size y, 4
+
+ .section .debug_loc.dwo,"e",@progbits
+.Ldebug_loc0:
+ .byte 3
+ .byte 3
+ .long .Ltmp1-.Lfunc_begin1
+ .short 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 3
+ .byte 5
+ .long .Lfunc_end1-.Ltmp1
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .byte 14 # DW_FORM_strp
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .ascii "\263B" # DW_AT_GNU_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lskel_string0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .long .Lskel_string1 # DW_AT_GNU_dwo_name
+ .quad -3308548803209949056 # DW_AT_GNU_dwo_id
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_GNU_addr_base
+.Ldebug_info_end0:
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main.dwo" # string offset=47
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "x" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=2
+.Linfo_string2:
+ .asciz "y" # string offset=6
+.Linfo_string3:
+ .asciz "_Z6helperii" # string offset=8
+.Linfo_string4:
+ .asciz "helper" # string offset=20
+.Linfo_string5:
+ .asciz "_Z3usePiS_" # string offset=27
+.Linfo_string6:
+ .asciz "use" # string offset=38
+.Linfo_string7:
+ .asciz "main" # string offset=42
+.Linfo_string8:
+ .asciz "argc" # string offset=47
+.Linfo_string9:
+ .asciz "argv" # string offset=52
+.Linfo_string10:
+ .asciz "char" # string offset=57
+.Linfo_string11:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=62
+.Linfo_string12:
+ .asciz "main.cpp" # string offset=163
+.Linfo_string13:
+ .asciz "main.dwo" # string offset=172
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 2
+ .long 6
+ .long 8
+ .long 20
+ .long 27
+ .long 38
+ .long 42
+ .long 47
+ .long 52
+ .long 57
+ .long 62
+ .long 163
+ .long 172
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x9d DW_TAG_compile_unit
+ .byte 11 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 12 # DW_AT_name
+ .byte 13 # DW_AT_GNU_dwo_name
+ .quad -3308548803209949056 # DW_AT_GNU_dwo_id
+ .byte 2 # Abbrev [2] 0x19:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 0
+ .byte 3 # Abbrev [3] 0x24:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 2 # Abbrev [2] 0x28:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 1
+ .byte 4 # Abbrev [4] 0x33:0x21 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .byte 5 # DW_AT_linkage_name
+ .byte 6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x3f:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .byte 0 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 148 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x49:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .byte 2 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 148 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x54:0x2c DW_TAG_subprogram
+ .byte 3 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .byte 7 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x63:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .byte 8 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ .byte 7 # Abbrev [7] 0x6d:0xc DW_TAG_formal_parameter
+ .long .Ldebug_loc0-.debug_loc.dwo # DW_AT_location
+ .byte 9 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 153 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x79:0x6 DW_TAG_GNU_call_site
+ .long 128 # DW_AT_abstract_origin
+ # DW_AT_GNU_tail_call
+ .byte 4 # DW_AT_low_pc
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x80:0x14 DW_TAG_subprogram
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 36 # DW_AT_type
+ # DW_AT_declaration
+ # DW_AT_external
+ .byte 10 # Abbrev [10] 0x89:0x5 DW_TAG_formal_parameter
+ .long 36 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x8e:0x5 DW_TAG_formal_parameter
+ .long 36 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 11 # Abbrev [11] 0x94:0x5 DW_TAG_pointer_type
+ .long 36 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x99:0x5 DW_TAG_pointer_type
+ .long 158 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x9e:0x5 DW_TAG_pointer_type
+ .long 163 # DW_AT_type
+ .byte 3 # Abbrev [3] 0xa3:0x4 DW_TAG_base_type
+ .byte 10 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .ascii "\211\202\001" # DW_TAG_GNU_call_site
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .ascii "\225B" # DW_AT_GNU_tail_call
+ .byte 25 # DW_FORM_flag_present
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"",@progbits
+.Laddr_table_base0:
+ .quad x
+ .quad y
+ .quad .Lfunc_begin0
+ .quad .Lfunc_begin1
+ .quad .Ltmp3
+ .quad .Ltmp1
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 48 # Compilation Unit Length
+ .long 25 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "x" # External Name
+ .long 40 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "y" # External Name
+ .long 51 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "use" # External Name
+ .long 84 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "main" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 48 # Compilation Unit Length
+ .long 36 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 163 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "char" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf4-df-change-in-dw-op-gnu-addr-index-main.s b/bolt/test/X86/Inputs/dwarf4-df-change-in-dw-op-gnu-addr-index-main.s
new file mode 100644
index 0000000000000..6817057c2ac2b
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf4-df-change-in-dw-op-gnu-addr-index-main.s
@@ -0,0 +1,734 @@
+# clang++ -O2 -g -gdwarf-4 -gsplit-dwarf main.cpp
+# void use(int * x, int * y) {
+# static int Foo = *y + *x;
+# *x += 4;
+# *y -= Foo;
+# }
+#
+# int x = 0;
+# int y = 1;
+# int main(int argc, char *argv[]) {
+# x = argc;
+# y = argc + 3;
+# use(&x, &y);
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .file 1 "." "main.cpp"
+ .globl _Z3usePiS_ # -- Begin function _Z3usePiS_
+ .p2align 4, 0x90
+ .type _Z3usePiS_,@function
+_Z3usePiS_: # @_Z3usePiS_
+.Lfunc_begin0:
+ .loc 1 1 0 # main.cpp:1:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: use:x <- $rdi
+ #DEBUG_VALUE: use:y <- $rsi
+ pushq %r14
+ .cfi_def_cfa_offset 16
+ pushq %rbx
+ .cfi_def_cfa_offset 24
+ pushq %rax
+ .cfi_def_cfa_offset 32
+ .cfi_offset %rbx, -24
+ .cfi_offset %r14, -16
+ movq %rsi, %rbx
+ movq %rdi, %r14
+.Ltmp0:
+ .loc 1 2 2 prologue_end # main.cpp:2:2
+ movzbl _ZGVZ3usePiS_E3Foo(%rip), %eax
+ testb %al, %al
+ je .LBB0_1
+.Ltmp1:
+.LBB0_3: # %init.end
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 1 3 5 # main.cpp:3:5
+ addl $4, (%r14)
+ .loc 1 4 8 # main.cpp:4:8
+ movl _ZZ3usePiS_E3Foo(%rip), %eax
+ .loc 1 4 5 is_stmt 0 # main.cpp:4:5
+ subl %eax, (%rbx)
+ .loc 1 5 1 epilogue_begin is_stmt 1 # main.cpp:5:1
+ addq $8, %rsp
+ .cfi_def_cfa_offset 24
+ popq %rbx
+.Ltmp2:
+ #DEBUG_VALUE: use:y <- [DW_OP_LLVM_entry_value 1] $rsi
+ .cfi_def_cfa_offset 16
+ popq %r14
+.Ltmp3:
+ #DEBUG_VALUE: use:x <- [DW_OP_LLVM_entry_value 1] $rdi
+ .cfi_def_cfa_offset 8
+ retq
+.Ltmp4:
+.LBB0_1: # %init.check
+ .cfi_def_cfa_offset 32
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 1 2 2 # main.cpp:2:2
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_acquire@PLT
+.Ltmp5:
+ testl %eax, %eax
+ je .LBB0_3
+.Ltmp6:
+# %bb.2: # %init
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 1 2 24 is_stmt 0 # main.cpp:2:24
+ movl (%r14), %eax
+ .loc 1 2 22 # main.cpp:2:22
+ addl (%rbx), %eax
+ .loc 1 2 2 # main.cpp:2:2
+ movl %eax, _ZZ3usePiS_E3Foo(%rip)
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_release@PLT
+.Ltmp7:
+ .loc 1 0 2 # main.cpp:0:2
+ jmp .LBB0_3
+.Ltmp8:
+.Lfunc_end0:
+ .size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: main:argc <- $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ .loc 1 10 6 prologue_end is_stmt 1 # main.cpp:10:6
+ movl %edi, x(%rip)
+ .loc 1 11 13 # main.cpp:11:13
+ addl $3, %edi
+.Ltmp9:
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 1 11 6 is_stmt 0 # main.cpp:11:6
+ movl %edi, y(%rip)
+.Ltmp10:
+ #DEBUG_VALUE: use:y <- undef
+ #DEBUG_VALUE: use:x <- undef
+ .loc 1 2 2 is_stmt 1 # main.cpp:2:2
+ movzbl _ZGVZ3usePiS_E3Foo(%rip), %eax
+ testb %al, %al
+ je .LBB1_1
+.Ltmp11:
+.LBB1_4: # %_Z3usePiS_.exit
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 1 3 5 # main.cpp:3:5
+ addl $4, x(%rip)
+ .loc 1 4 8 # main.cpp:4:8
+ movl _ZZ3usePiS_E3Foo(%rip), %eax
+ .loc 1 4 5 is_stmt 0 # main.cpp:4:5
+ subl %eax, y(%rip)
+.Ltmp12:
+ .loc 1 13 4 is_stmt 1 # main.cpp:13:4
+ xorl %eax, %eax
+ retq
+.Ltmp13:
+.LBB1_1: # %init.check.i
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ pushq %rax
+ .cfi_def_cfa_offset 16
+.Ltmp14:
+ .loc 1 2 2 # main.cpp:2:2
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_acquire@PLT
+.Ltmp15:
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ testl %eax, %eax
+ je .LBB1_3
+.Ltmp16:
+# %bb.2: # %init.i
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 1 2 24 is_stmt 0 # main.cpp:2:24
+ movl x(%rip), %eax
+ .loc 1 2 22 # main.cpp:2:22
+ addl y(%rip), %eax
+ .loc 1 2 2 # main.cpp:2:2
+ movl %eax, _ZZ3usePiS_E3Foo(%rip)
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_release@PLT
+.Ltmp17:
+.LBB1_3:
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 1 0 2 # main.cpp:0:2
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ jmp .LBB1_4
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .type _ZZ3usePiS_E3Foo,@object # @_ZZ3usePiS_E3Foo
+ .local _ZZ3usePiS_E3Foo
+ .comm _ZZ3usePiS_E3Foo,4,4
+ .type _ZGVZ3usePiS_E3Foo,@object # @_ZGVZ3usePiS_E3Foo
+ .local _ZGVZ3usePiS_E3Foo
+ .comm _ZGVZ3usePiS_E3Foo,8,8
+ .type x,@object # @x
+ .bss
+ .globl x
+ .p2align 2, 0x0
+x:
+ .long 0 # 0x0
+ .size x, 4
+
+ .type y,@object # @y
+ .data
+ .globl y
+ .p2align 2, 0x0
+y:
+ .long 1 # 0x1
+ .size y, 4
+
+ .section .debug_loc.dwo,"e",@progbits
+.Ldebug_loc0:
+ .byte 3
+ .byte 3
+ .long .Ltmp1-.Lfunc_begin0
+ .short 1 # Loc expr size
+ .byte 85 # DW_OP_reg5
+ .byte 3
+ .byte 5
+ .long .Ltmp3-.Ltmp1
+ .short 1 # Loc expr size
+ .byte 94 # DW_OP_reg14
+ .byte 3
+ .byte 6
+ .long .Ltmp4-.Ltmp3
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 85 # DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 3
+ .byte 7
+ .long .Lfunc_end0-.Ltmp4
+ .short 1 # Loc expr size
+ .byte 94 # DW_OP_reg14
+ .byte 0
+.Ldebug_loc1:
+ .byte 3
+ .byte 3
+ .long .Ltmp1-.Lfunc_begin0
+ .short 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 3
+ .byte 5
+ .long .Ltmp2-.Ltmp1
+ .short 1 # Loc expr size
+ .byte 83 # DW_OP_reg3
+ .byte 3
+ .byte 8
+ .long .Ltmp4-.Ltmp2
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 3
+ .byte 7
+ .long .Lfunc_end0-.Ltmp4
+ .short 1 # Loc expr size
+ .byte 83 # DW_OP_reg3
+ .byte 0
+.Ldebug_loc2:
+ .byte 3
+ .byte 4
+ .long .Ltmp9-.Lfunc_begin1
+ .short 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 3
+ .byte 9
+ .long .Lfunc_end1-.Ltmp9
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 0
+.Ldebug_loc3:
+ .byte 3
+ .byte 4
+ .long .Ltmp11-.Lfunc_begin1
+ .short 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 3
+ .byte 10
+ .long .Ltmp13-.Ltmp11
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 3
+ .byte 11
+ .long .Ltmp15-.Ltmp13
+ .short 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 3
+ .byte 12
+ .long .Lfunc_end1-.Ltmp15
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 0
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .byte 14 # DW_FORM_strp
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .ascii "\262B" # DW_AT_GNU_ranges_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .ascii "\263B" # DW_AT_GNU_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x29 DW_TAG_compile_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lskel_string0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .long .Lskel_string1 # DW_AT_GNU_dwo_name
+ .quad -3506999759942021708 # DW_AT_GNU_dwo_id
+ .long .debug_ranges # DW_AT_GNU_ranges_base
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_GNU_addr_base
+.Ldebug_info_end0:
+ .section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+ .quad .Ltmp10-.Lfunc_begin0
+ .quad .Ltmp12-.Lfunc_begin0
+ .quad .Ltmp14-.Lfunc_begin0
+ .quad .Ltmp17-.Lfunc_begin0
+ .quad 0
+ .quad 0
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main.dwo" # string offset=38
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "Foo" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=4
+.Linfo_string2:
+ .asciz "x" # string offset=8
+.Linfo_string3:
+ .asciz "y" # string offset=10
+.Linfo_string4:
+ .asciz "_Z3usePiS_" # string offset=12
+.Linfo_string5:
+ .asciz "use" # string offset=23
+.Linfo_string6:
+ .asciz "main" # string offset=27
+.Linfo_string7:
+ .asciz "argc" # string offset=32
+.Linfo_string8:
+ .asciz "argv" # string offset=37
+.Linfo_string9:
+ .asciz "char" # string offset=42
+.Linfo_string10:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=47
+.Linfo_string11:
+ .asciz "main.cpp" # string offset=148
+.Linfo_string12:
+ .asciz "main.dwo" # string offset=157
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 4
+ .long 8
+ .long 10
+ .long 12
+ .long 23
+ .long 27
+ .long 32
+ .long 37
+ .long 42
+ .long 47
+ .long 148
+ .long 157
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xb1 DW_TAG_compile_unit
+ .byte 10 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 11 # DW_AT_name
+ .byte 12 # DW_AT_GNU_dwo_name
+ .quad -3506999759942021708 # DW_AT_GNU_dwo_id
+ .byte 2 # Abbrev [2] 0x19:0x2a DW_TAG_subprogram
+ .byte 3 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long 93 # DW_AT_abstract_origin
+ .byte 3 # Abbrev [3] 0x25:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 67 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 0
+ .byte 4 # Abbrev [4] 0x30:0x9 DW_TAG_formal_parameter
+ .long .Ldebug_loc0-.debug_loc.dwo # DW_AT_location
+ .long 99 # DW_AT_abstract_origin
+ .byte 4 # Abbrev [4] 0x39:0x9 DW_TAG_formal_parameter
+ .long .Ldebug_loc1-.debug_loc.dwo # DW_AT_location
+ .long 107 # DW_AT_abstract_origin
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x43:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x47:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 67 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 1
+ .byte 6 # Abbrev [6] 0x52:0xb DW_TAG_variable
+ .byte 3 # DW_AT_name
+ .long 67 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 2
+ .byte 7 # Abbrev [7] 0x5d:0x17 DW_TAG_subprogram
+ .byte 4 # DW_AT_linkage_name
+ .byte 5 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 1 # DW_AT_inline
+ .byte 8 # Abbrev [8] 0x63:0x8 DW_TAG_formal_parameter
+ .byte 2 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 116 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x6b:0x8 DW_TAG_formal_parameter
+ .byte 3 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 116 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x74:0x5 DW_TAG_pointer_type
+ .long 67 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x79:0x34 DW_TAG_subprogram
+ .byte 4 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .byte 6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 67 # DW_AT_type
+ # DW_AT_external
+ .byte 11 # Abbrev [11] 0x88:0xc DW_TAG_formal_parameter
+ .long .Ldebug_loc2-.debug_loc.dwo # DW_AT_location
+ .byte 7 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 67 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x94:0xc DW_TAG_formal_parameter
+ .long .Ldebug_loc3-.debug_loc.dwo # DW_AT_location
+ .byte 8 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 173 # DW_AT_type
+ .byte 12 # Abbrev [12] 0xa0:0xc DW_TAG_inlined_subroutine
+ .long 93 # DW_AT_abstract_origin
+ .long .Ldebug_ranges0-.debug_ranges # DW_AT_ranges
+ .byte 1 # DW_AT_call_file
+ .byte 12 # DW_AT_call_line
+ .byte 4 # DW_AT_call_column
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0xad:0x5 DW_TAG_pointer_type
+ .long 178 # DW_AT_type
+ .byte 9 # Abbrev [9] 0xb2:0x5 DW_TAG_pointer_type
+ .long 183 # DW_AT_type
+ .byte 5 # Abbrev [5] 0xb7:0x4 DW_TAG_base_type
+ .byte 9 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 32 # DW_AT_inline
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .ascii "\201>" # DW_FORM_GNU_addr_index
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 12 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 85 # DW_AT_ranges
+ .byte 23 # DW_FORM_sec_offset
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"",@progbits
+.Laddr_table_base0:
+ .quad _ZZ3usePiS_E3Foo
+ .quad x
+ .quad y
+ .quad .Lfunc_begin0
+ .quad .Lfunc_begin1
+ .quad .Ltmp1
+ .quad .Ltmp3
+ .quad .Ltmp4
+ .quad .Ltmp2
+ .quad .Ltmp9
+ .quad .Ltmp11
+ .quad .Ltmp13
+ .quad .Ltmp15
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 52 # Compilation Unit Length
+ .long 37 # DIE offset
+ .byte 160 # Attributes: VARIABLE, STATIC
+ .asciz "use::Foo" # External Name
+ .long 71 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "x" # External Name
+ .long 82 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "y" # External Name
+ .long 93 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "use" # External Name
+ .long 121 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "main" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 52 # Compilation Unit Length
+ .long 67 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 183 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "char" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .addrsig_sym _ZGVZ3usePiS_E3Foo
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf4-two-entries-loclist.s b/bolt/test/X86/Inputs/dwarf4-two-entries-loclist.s
new file mode 100644
index 0000000000000..d2df94ce16f88
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf4-two-entries-loclist.s
@@ -0,0 +1,390 @@
+# clang++ helper2.cpp -O2 -g2 -gdwarf-4 -S -o helper2.s
+# int z1 = 0;
+# int d1 = 0;
+#
+# int helper31(int z_, int d_) {
+# z1 += z_;
+# d1 += d_;
+# return z1 * d1;
+# }
+#
+#
+# int z = 0;
+# int d = 0;
+#
+# int helper3(int z_, int d_) {
+# z += z_;
+# d += d_;
+# return z * d;
+# }
+
+ .text
+ .file "helper2.cpp"
+ .file 1 "/dwarf4CrossCULocList" "helper2.cpp"
+ .globl _Z8helper31ii # -- Begin function _Z8helper31ii
+ .p2align 4, 0x90
+ .type _Z8helper31ii,@function
+_Z8helper31ii: # @_Z8helper31ii
+.Lfunc_begin0:
+ .loc 1 4 0 # helper2.cpp:4:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: helper31:z_ <- $edi
+ #DEBUG_VALUE: helper31:d_ <- $esi
+ movl %esi, %eax
+.Ltmp0:
+ .loc 1 5 5 prologue_end # helper2.cpp:5:5
+ addl z1(%rip), %edi
+.Ltmp1:
+ #DEBUG_VALUE: helper31:z_ <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 1 6 5 # helper2.cpp:6:5
+ addl d1(%rip), %eax
+ .loc 1 5 5 # helper2.cpp:5:5
+ movl %edi, z1(%rip)
+ .loc 1 6 5 # helper2.cpp:6:5
+ movl %eax, d1(%rip)
+ .loc 1 7 12 # helper2.cpp:7:12
+ imull %edi, %eax
+ .loc 1 7 2 is_stmt 0 # helper2.cpp:7:2
+ retq
+.Ltmp2:
+.Lfunc_end0:
+ .size _Z8helper31ii, .Lfunc_end0-_Z8helper31ii
+ .cfi_endproc
+ # -- End function
+ .globl _Z7helper3ii # -- Begin function _Z7helper3ii
+ .p2align 4, 0x90
+ .type _Z7helper3ii,@function
+_Z7helper3ii: # @_Z7helper3ii
+.Lfunc_begin1:
+ .loc 1 14 0 is_stmt 1 # helper2.cpp:14:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: helper3:z_ <- $edi
+ #DEBUG_VALUE: helper3:d_ <- $esi
+ movl %esi, %eax
+.Ltmp3:
+ .loc 1 15 4 prologue_end # helper2.cpp:15:4
+ addl z(%rip), %edi
+.Ltmp4:
+ #DEBUG_VALUE: helper3:z_ <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 1 16 4 # helper2.cpp:16:4
+ addl d(%rip), %eax
+ .loc 1 15 4 # helper2.cpp:15:4
+ movl %edi, z(%rip)
+ .loc 1 16 4 # helper2.cpp:16:4
+ movl %eax, d(%rip)
+ .loc 1 17 11 # helper2.cpp:17:11
+ imull %edi, %eax
+ .loc 1 17 2 is_stmt 0 # helper2.cpp:17:2
+ retq
+.Ltmp5:
+.Lfunc_end1:
+ .size _Z7helper3ii, .Lfunc_end1-_Z7helper3ii
+ .cfi_endproc
+ # -- End function
+ .type z1,@object # @z1
+ .bss
+ .globl z1
+ .p2align 2, 0x0
+z1:
+ .long 0 # 0x0
+ .size z1, 4
+
+ .type d1,@object # @d1
+ .globl d1
+ .p2align 2, 0x0
+d1:
+ .long 0 # 0x0
+ .size d1, 4
+
+ .type z,@object # @z
+ .globl z
+ .p2align 2, 0x0
+z:
+ .long 0 # 0x0
+ .size z, 4
+
+ .type d,@object # @d
+ .globl d
+ .p2align 2, 0x0
+d:
+ .long 0 # 0x0
+ .size d, 4
+
+ .section .debug_loc,"",@progbits
+.Ldebug_loc0:
+ .quad .Lfunc_begin0-.Lfunc_begin0
+ .quad .Ltmp1-.Lfunc_begin0
+ .short 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .quad .Ltmp1-.Lfunc_begin0
+ .quad .Lfunc_end0-.Lfunc_begin0
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .quad 0
+ .quad 0
+.Ldebug_loc1:
+ .quad .Lfunc_begin1-.Lfunc_begin0
+ .quad .Ltmp4-.Lfunc_begin0
+ .short 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .quad .Ltmp4-.Lfunc_begin0
+ .quad .Lfunc_end1-.Lfunc_begin0
+ .short 4 # Loc expr size
+ .byte 243 # DW_OP_GNU_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .quad 0
+ .quad 0
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 23 # DW_FORM_sec_offset
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xef DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable
+ .long .Linfo_string3 # DW_AT_name
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad z1
+ .byte 3 # Abbrev [3] 0x3f:0x7 DW_TAG_base_type
+ .long .Linfo_string4 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 2 # Abbrev [2] 0x46:0x15 DW_TAG_variable
+ .long .Linfo_string5 # DW_AT_name
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad d1
+ .byte 2 # Abbrev [2] 0x5b:0x15 DW_TAG_variable
+ .long .Linfo_string6 # DW_AT_name
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 11 # DW_AT_decl_line
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad z
+ .byte 2 # Abbrev [2] 0x70:0x15 DW_TAG_variable
+ .long .Linfo_string7 # DW_AT_name
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 12 # DW_AT_decl_line
+ .byte 9 # DW_AT_location
+ .byte 3
+ .quad d
+ .byte 4 # Abbrev [4] 0x85:0x3a DW_TAG_subprogram
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string8 # DW_AT_linkage_name
+ .long .Linfo_string9 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0xa2:0xf DW_TAG_formal_parameter
+ .long .Ldebug_loc0 # DW_AT_location
+ .long .Linfo_string12 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ .byte 6 # Abbrev [6] 0xb1:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string13 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 4 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0xbf:0x3a DW_TAG_subprogram
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string10 # DW_AT_linkage_name
+ .long .Linfo_string11 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 14 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0xdc:0xf DW_TAG_formal_parameter
+ .long .Ldebug_loc1 # DW_AT_location
+ .long .Linfo_string12 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 14 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ .byte 6 # Abbrev [6] 0xeb:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string13 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 14 # DW_AT_decl_line
+ .long 63 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "helper2.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/dwarf4CrossCULocList" # string offset=113
+.Linfo_string3:
+ .asciz "z1" # string offset=172
+.Linfo_string4:
+ .asciz "int" # string offset=175
+.Linfo_string5:
+ .asciz "d1" # string offset=179
+.Linfo_string6:
+ .asciz "z" # string offset=182
+.Linfo_string7:
+ .asciz "d" # string offset=184
+.Linfo_string8:
+ .asciz "_Z8helper31ii" # string offset=186
+.Linfo_string9:
+ .asciz "helper31" # string offset=200
+.Linfo_string10:
+ .asciz "_Z7helper3ii" # string offset=209
+.Linfo_string11:
+ .asciz "helper3" # string offset=222
+.Linfo_string12:
+ .asciz "z_" # string offset=230
+.Linfo_string13:
+ .asciz "d_" # string offset=233
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-helper.s b/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-helper.s
new file mode 100644
index 0000000000000..fd63c7cf33e61
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-helper.s
@@ -0,0 +1,380 @@
+# clang++ -O2 -g -gdwarf-4 -gsplit-dwarf
+# int z = 0;
+# int d = 0;
+# int helper(int z_, int d_) {
+# z += z_;
+# d += d_;
+# return z * d;
+# }
+ .text
+ .file "helper.cpp"
+ .file 0 "." "helper.cpp" md5 0xb012cefec76132f29ac48b29c7580352
+ .globl _Z6helperii # -- Begin function _Z6helperii
+ .p2align 4, 0x90
+ .type _Z6helperii,@function
+_Z6helperii: # @_Z6helperii
+.Lfunc_begin0:
+ .loc 0 3 0 # helper.cpp:3:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: helper:z_ <- $edi
+ #DEBUG_VALUE: helper:d_ <- $esi
+ movl %esi, %eax
+.Ltmp0:
+ .loc 0 4 4 prologue_end # helper.cpp:4:4
+ addl z(%rip), %edi
+.Ltmp1:
+ #DEBUG_VALUE: helper:z_ <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 0 5 4 # helper.cpp:5:4
+ addl d(%rip), %eax
+ .loc 0 4 4 # helper.cpp:4:4
+ movl %edi, z(%rip)
+ .loc 0 5 4 # helper.cpp:5:4
+ movl %eax, d(%rip)
+ .loc 0 6 11 # helper.cpp:6:11
+ imull %edi, %eax
+ .loc 0 6 2 is_stmt 0 # helper.cpp:6:2
+ retq
+.Ltmp2:
+.Lfunc_end0:
+ .size _Z6helperii, .Lfunc_end0-_Z6helperii
+ .cfi_endproc
+ # -- End function
+ .type z,@object # @z
+ .bss
+ .globl z
+ .p2align 2, 0x0
+z:
+ .long 0 # 0x0
+ .size z, 4
+
+ .type d,@object # @d
+ .globl d
+ .p2align 2, 0x0
+d:
+ .long 0 # 0x0
+ .size d, 4
+
+ .section .debug_loclists.dwo,"e",@progbits
+ .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lloclists_table_base0:
+ .long .Ldebug_loc0-.Lloclists_table_base0
+.Ldebug_loc0:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 2 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 6512974040646495267
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .byte 1 # DW_AT_dwo_name
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"",@progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "helper.dwo" # string offset=47
+ .section .debug_str_offsets,"",@progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 44 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "z" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=2
+.Linfo_string2:
+ .asciz "d" # string offset=6
+.Linfo_string3:
+ .asciz "_Z6helperii" # string offset=8
+.Linfo_string4:
+ .asciz "helper" # string offset=20
+.Linfo_string5:
+ .asciz "z_" # string offset=27
+.Linfo_string6:
+ .asciz "d_" # string offset=30
+.Linfo_string7:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=33
+.Linfo_string8:
+ .asciz "helper.cpp" # string offset=134
+.Linfo_string9:
+ .asciz "helper.dwo" # string offset=145
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 2
+ .long 6
+ .long 8
+ .long 20
+ .long 27
+ .long 30
+ .long 33
+ .long 134
+ .long 145
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 6512974040646495267
+ .byte 1 # Abbrev [1] 0x14:0x45 DW_TAG_compile_unit
+ .byte 7 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 8 # DW_AT_name
+ .byte 9 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 3 # Abbrev [3] 0x25:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 2 # Abbrev [2] 0x29:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 1
+ .byte 4 # Abbrev [4] 0x34:0x24 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x44:0x9 DW_TAG_formal_parameter
+ .byte 0 # DW_AT_location
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x4d:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 34 # DW_FORM_loclistx
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"",@progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad z
+ .quad d
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 26 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "z" # External Name
+ .long 41 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "d" # External Name
+ .long 52 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "helper" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 37 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-main.s b/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-main.s
new file mode 100644
index 0000000000000..ad4ab64659e4d
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-call-site-change-low-pc-main.s
@@ -0,0 +1,552 @@
+# clang++ -O2 -g -gdwarf-4 -gsplit-dwarf
+# void use(int * x, int * y) {
+# *x += 4;
+# *y -= 2;
+# }
+#
+# int helper(int z_, int d_);
+# int x = 0;
+# int y = 1;
+# int main(int argc, char *argv[]) {
+# x = argc;
+# y = argc + 3;
+# //use(&x, &y);
+# return helper(x, y);
+# }
+ .text
+ .file "main.cpp"
+ .file 0 "." "main.cpp" md5 0x1a68208241c6577e68c7b707538826da
+ .globl _Z3usePiS_ # -- Begin function _Z3usePiS_
+ .p2align 4, 0x90
+ .type _Z3usePiS_,@function
+_Z3usePiS_: # @_Z3usePiS_
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: use:x <- $rdi
+ #DEBUG_VALUE: use:y <- $rsi
+ .loc 0 2 5 prologue_end # main.cpp:2:5
+ addl $4, (%rdi)
+ .loc 0 3 5 # main.cpp:3:5
+ addl $-2, (%rsi)
+ .loc 0 4 1 # main.cpp:4:1
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: main:argc <- $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ # kill: def $edi killed $edi def $rdi
+ .loc 0 10 6 prologue_end # main.cpp:10:6
+ movl %edi, x(%rip)
+ .loc 0 11 13 # main.cpp:11:13
+ leal 3(%rdi), %esi
+.Ltmp1:
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 0 11 6 is_stmt 0 # main.cpp:11:6
+ movl %esi, y(%rip)
+ # kill: def $edi killed $edi killed $rdi
+.Ltmp2:
+ .loc 0 13 11 is_stmt 1 # main.cpp:13:11
+ jmp _Z6helperii@PLT # TAILCALL
+.Ltmp3:
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .type x,@object # @x
+ .bss
+ .globl x
+ .p2align 2, 0x0
+x:
+ .long 0 # 0x0
+ .size x, 4
+
+ .type y,@object # @y
+ .data
+ .globl y
+ .p2align 2, 0x0
+y:
+ .long 1 # 0x1
+ .size y, 4
+
+ .section .debug_loclists.dwo,"e",@progbits
+ .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lloclists_table_base0:
+ .long .Ldebug_loc0-.Lloclists_table_base0
+.Ldebug_loc0:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 2 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad 1538385283627936656
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .byte 1 # DW_AT_dwo_name
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"",@progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main.dwo" # string offset=47
+ .section .debug_str_offsets,"",@progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 60 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "x" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=2
+.Linfo_string2:
+ .asciz "y" # string offset=6
+.Linfo_string3:
+ .asciz "_Z6helperii" # string offset=8
+.Linfo_string4:
+ .asciz "helper" # string offset=20
+.Linfo_string5:
+ .asciz "_Z3usePiS_" # string offset=27
+.Linfo_string6:
+ .asciz "use" # string offset=38
+.Linfo_string7:
+ .asciz "main" # string offset=42
+.Linfo_string8:
+ .asciz "argc" # string offset=47
+.Linfo_string9:
+ .asciz "argv" # string offset=52
+.Linfo_string10:
+ .asciz "char" # string offset=57
+.Linfo_string11:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=62
+.Linfo_string12:
+ .asciz "main.cpp" # string offset=163
+.Linfo_string13:
+ .asciz "main.dwo" # string offset=172
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 2
+ .long 6
+ .long 8
+ .long 20
+ .long 27
+ .long 38
+ .long 42
+ .long 47
+ .long 52
+ .long 57
+ .long 62
+ .long 163
+ .long 172
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad 1538385283627936656
+ .byte 1 # Abbrev [1] 0x14:0x8e DW_TAG_compile_unit
+ .byte 11 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 12 # DW_AT_name
+ .byte 13 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 3 # Abbrev [3] 0x25:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 2 # Abbrev [2] 0x29:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 1
+ .byte 4 # Abbrev [4] 0x34:0x21 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 5 # DW_AT_linkage_name
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x40:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .byte 0 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 142 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x4a:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .byte 2 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 142 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 6 # Abbrev [6] 0x55:0x25 DW_TAG_subprogram
+ .byte 0 # DW_AT_ranges
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 7 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ # DW_AT_external
+ .byte 5 # Abbrev [5] 0x60:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .byte 8 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ .byte 7 # Abbrev [7] 0x6a:0x9 DW_TAG_formal_parameter
+ .byte 0 # DW_AT_location
+ .byte 9 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 147 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x73:0x6 DW_TAG_call_site
+ .long 122 # DW_AT_call_origin
+ # DW_AT_call_tail_call
+ .byte 3 # DW_AT_call_pc
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x7a:0x14 DW_TAG_subprogram
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 37 # DW_AT_type
+ # DW_AT_declaration
+ # DW_AT_external
+ .byte 10 # Abbrev [10] 0x83:0x5 DW_TAG_formal_parameter
+ .long 37 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x88:0x5 DW_TAG_formal_parameter
+ .long 37 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 11 # Abbrev [11] 0x8e:0x5 DW_TAG_pointer_type
+ .long 37 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x93:0x5 DW_TAG_pointer_type
+ .long 152 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x98:0x5 DW_TAG_pointer_type
+ .long 157 # DW_AT_type
+ .byte 3 # Abbrev [3] 0x9d:0x4 DW_TAG_base_type
+ .byte 10 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 85 # DW_AT_ranges
+ .byte 35 # DW_FORM_rnglistx
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 34 # DW_FORM_loclistx
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 72 # DW_TAG_call_site
+ .byte 0 # DW_CHILDREN_no
+ .byte 127 # DW_AT_call_origin
+ .byte 19 # DW_FORM_ref4
+ .ascii "\202\001" # DW_AT_call_tail_call
+ .byte 25 # DW_FORM_flag_present
+ .ascii "\201\001" # DW_AT_call_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 60 # DW_AT_declaration
+ .byte 25 # DW_FORM_flag_present
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_rnglists.dwo,"e",@progbits
+ .long .Ldebug_list_header_end1-.Ldebug_list_header_start1 # Length
+.Ldebug_list_header_start1:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lrnglists_dwo_table_base0:
+ .long .Ldebug_ranges0-.Lrnglists_dwo_table_base0
+.Ldebug_ranges0:
+ .byte 4 # DW_RLE_offset_pair
+ .uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
+ .byte 0 # DW_RLE_end_of_list
+.Ldebug_list_header_end1:
+ .section .debug_addr,"",@progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad x
+ .quad y
+ .quad .Lfunc_begin0
+ .quad .Ltmp2
+.Ldebug_addr_end0:
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 26 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "x" # External Name
+ .long 41 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "y" # External Name
+ .long 52 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "use" # External Name
+ .long 85 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "main" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 37 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 157 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "char" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-df-change-in-dw-op-gnu-addr-index-main.s b/bolt/test/X86/Inputs/dwarf5-df-change-in-dw-op-gnu-addr-index-main.s
new file mode 100644
index 0000000000000..1b0154f740b65
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-df-change-in-dw-op-gnu-addr-index-main.s
@@ -0,0 +1,774 @@
+# clang++ -O2 -g -gdwarf-5 -gsplit-dwarf main.cpp
+# void use(int * x, int * y) {
+# static int Foo = *y + *x;
+# *x += 4;
+# *y -= Foo;
+# }
+#
+# int x = 0;
+# int y = 1;
+# int main(int argc, char *argv[]) {
+# x = argc;
+# y = argc + 3;
+# use(&x, &y);
+# return 0;
+# }
+ .text
+ .file "main.cpp"
+ .file 0 "." "main.cpp" md5 0x4f704c611bdcbf8d7a62eb17d439188e
+ .globl _Z3usePiS_ # -- Begin function _Z3usePiS_
+ .p2align 4, 0x90
+ .type _Z3usePiS_,@function
+_Z3usePiS_: # @_Z3usePiS_
+.Lfunc_begin0:
+ .loc 0 1 0 # main.cpp:1:0
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: use:x <- $rdi
+ #DEBUG_VALUE: use:y <- $rsi
+ pushq %r14
+ .cfi_def_cfa_offset 16
+ pushq %rbx
+ .cfi_def_cfa_offset 24
+ pushq %rax
+ .cfi_def_cfa_offset 32
+ .cfi_offset %rbx, -24
+ .cfi_offset %r14, -16
+ movq %rsi, %rbx
+ movq %rdi, %r14
+.Ltmp0:
+ .loc 0 2 2 prologue_end # main.cpp:2:2
+ movzbl _ZGVZ3usePiS_E3Foo(%rip), %eax
+ testb %al, %al
+ je .LBB0_1
+.Ltmp1:
+.LBB0_3: # %init.end
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 0 3 5 # main.cpp:3:5
+ addl $4, (%r14)
+ .loc 0 4 8 # main.cpp:4:8
+ movl _ZZ3usePiS_E3Foo(%rip), %eax
+ .loc 0 4 5 is_stmt 0 # main.cpp:4:5
+ subl %eax, (%rbx)
+ .loc 0 5 1 epilogue_begin is_stmt 1 # main.cpp:5:1
+ addq $8, %rsp
+ .cfi_def_cfa_offset 24
+ popq %rbx
+.Ltmp2:
+ #DEBUG_VALUE: use:y <- [DW_OP_LLVM_entry_value 1] $rsi
+ .cfi_def_cfa_offset 16
+ popq %r14
+.Ltmp3:
+ #DEBUG_VALUE: use:x <- [DW_OP_LLVM_entry_value 1] $rdi
+ .cfi_def_cfa_offset 8
+ retq
+.Ltmp4:
+.LBB0_1: # %init.check
+ .cfi_def_cfa_offset 32
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 0 2 2 # main.cpp:2:2
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_acquire@PLT
+.Ltmp5:
+ testl %eax, %eax
+ je .LBB0_3
+.Ltmp6:
+# %bb.2: # %init
+ #DEBUG_VALUE: use:x <- $r14
+ #DEBUG_VALUE: use:y <- $rbx
+ .loc 0 2 24 is_stmt 0 # main.cpp:2:24
+ movl (%r14), %eax
+ .loc 0 2 22 # main.cpp:2:22
+ addl (%rbx), %eax
+ .loc 0 2 2 # main.cpp:2:2
+ movl %eax, _ZZ3usePiS_E3Foo(%rip)
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_release@PLT
+.Ltmp7:
+ .loc 0 0 2 # main.cpp:0:2
+ jmp .LBB0_3
+.Ltmp8:
+.Lfunc_end0:
+ .size _Z3usePiS_, .Lfunc_end0-_Z3usePiS_
+ .cfi_endproc
+ # -- End function
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: main:argc <- $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ .loc 0 10 6 prologue_end is_stmt 1 # main.cpp:10:6
+ movl %edi, x(%rip)
+ .loc 0 11 13 # main.cpp:11:13
+ addl $3, %edi
+.Ltmp9:
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ .loc 0 11 6 is_stmt 0 # main.cpp:11:6
+ movl %edi, y(%rip)
+.Ltmp10:
+ #DEBUG_VALUE: use:y <- undef
+ #DEBUG_VALUE: use:x <- undef
+ .loc 0 2 2 is_stmt 1 # main.cpp:2:2
+ movzbl _ZGVZ3usePiS_E3Foo(%rip), %eax
+ testb %al, %al
+ je .LBB1_1
+.Ltmp11:
+.LBB1_4: # %_Z3usePiS_.exit
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 0 3 5 # main.cpp:3:5
+ addl $4, x(%rip)
+ .loc 0 4 8 # main.cpp:4:8
+ movl _ZZ3usePiS_E3Foo(%rip), %eax
+ .loc 0 4 5 is_stmt 0 # main.cpp:4:5
+ subl %eax, y(%rip)
+.Ltmp12:
+ .loc 0 13 4 is_stmt 1 # main.cpp:13:4
+ xorl %eax, %eax
+ retq
+.Ltmp13:
+.LBB1_1: # %init.check.i
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- $rsi
+ pushq %rax
+ .cfi_def_cfa_offset 16
+.Ltmp14:
+ .loc 0 2 2 # main.cpp:2:2
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_acquire@PLT
+.Ltmp15:
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ testl %eax, %eax
+ je .LBB1_3
+.Ltmp16:
+# %bb.2: # %init.i
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 0 2 24 is_stmt 0 # main.cpp:2:24
+ movl x(%rip), %eax
+ .loc 0 2 22 # main.cpp:2:22
+ addl y(%rip), %eax
+ .loc 0 2 2 # main.cpp:2:2
+ movl %eax, _ZZ3usePiS_E3Foo(%rip)
+ leaq _ZGVZ3usePiS_E3Foo(%rip), %rdi
+ callq __cxa_guard_release@PLT
+.Ltmp17:
+.LBB1_3:
+ #DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
+ #DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
+ .loc 0 0 2 # main.cpp:0:2
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ jmp .LBB1_4
+.Lfunc_end1:
+ .size main, .Lfunc_end1-main
+ .cfi_endproc
+ # -- End function
+ .type _ZZ3usePiS_E3Foo,@object # @_ZZ3usePiS_E3Foo
+ .local _ZZ3usePiS_E3Foo
+ .comm _ZZ3usePiS_E3Foo,4,4
+ .type _ZGVZ3usePiS_E3Foo,@object # @_ZGVZ3usePiS_E3Foo
+ .local _ZGVZ3usePiS_E3Foo
+ .comm _ZGVZ3usePiS_E3Foo,8,8
+ .type x,@object # @x
+ .bss
+ .globl x
+ .p2align 2, 0x0
+x:
+ .long 0 # 0x0
+ .size x, 4
+
+ .type y,@object # @y
+ .data
+ .globl y
+ .p2align 2, 0x0
+y:
+ .long 1 # 0x1
+ .size y, 4
+
+ .section .debug_loclists.dwo,"e",@progbits
+ .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 4 # Offset entry count
+.Lloclists_table_base0:
+ .long .Ldebug_loc0-.Lloclists_table_base0
+ .long .Ldebug_loc1-.Lloclists_table_base0
+ .long .Ldebug_loc2-.Lloclists_table_base0
+ .long .Ldebug_loc3-.Lloclists_table_base0
+.Ldebug_loc0:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 3 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 85 # DW_OP_reg5
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp3-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 94 # DW_OP_reg14
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp3-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 85 # DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 94 # DW_OP_reg14
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_loc1:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 3 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp2-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 83 # DW_OP_reg3
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp2-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 83 # DW_OP_reg3
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_loc2:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 3 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 85 # super-register DW_OP_reg5
+ .byte 159 # DW_OP_stack_value
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_loc3:
+ .byte 1 # DW_LLE_base_addressx
+ .byte 3 # base address index
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp11-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp11-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp13-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp13-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp15-.Lfunc_begin0 # ending offset
+ .byte 1 # Loc expr size
+ .byte 84 # DW_OP_reg4
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Ltmp15-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
+ .byte 4 # Loc expr size
+ .byte 163 # DW_OP_entry_value
+ .byte 1 # 1
+ .byte 84 # DW_OP_reg4
+ .byte 159 # DW_OP_stack_value
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 74 # DW_TAG_skeleton_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .ascii "\264B" # DW_AT_GNU_pubnames
+ .byte 25 # DW_FORM_flag_present
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 4 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .quad -3440409667494789237
+ .byte 1 # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .byte 0 # DW_AT_comp_dir
+ # DW_AT_GNU_pubnames
+ .byte 1 # DW_AT_dwo_name
+ .byte 3 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"",@progbits
+ .long 12 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "." # string offset=0
+.Lskel_string1:
+ .asciz "main.dwo" # string offset=38
+ .section .debug_str_offsets,"",@progbits
+ .long .Lskel_string0
+ .long .Lskel_string1
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 56 # Length of String Offsets Set
+ .short 5
+ .short 0
+ .section .debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+ .asciz "Foo" # string offset=0
+.Linfo_string1:
+ .asciz "int" # string offset=4
+.Linfo_string2:
+ .asciz "x" # string offset=8
+.Linfo_string3:
+ .asciz "y" # string offset=10
+.Linfo_string4:
+ .asciz "_Z3usePiS_" # string offset=12
+.Linfo_string5:
+ .asciz "use" # string offset=23
+.Linfo_string6:
+ .asciz "main" # string offset=27
+.Linfo_string7:
+ .asciz "argc" # string offset=32
+.Linfo_string8:
+ .asciz "argv" # string offset=37
+.Linfo_string9:
+ .asciz "char" # string offset=42
+.Linfo_string10:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)" # string offset=47
+.Linfo_string11:
+ .asciz "main.cpp" # string offset=148
+.Linfo_string12:
+ .asciz "main.dwo" # string offset=157
+ .section .debug_str_offsets.dwo,"e",@progbits
+ .long 0
+ .long 4
+ .long 8
+ .long 10
+ .long 12
+ .long 23
+ .long 27
+ .long 32
+ .long 37
+ .long 42
+ .long 47
+ .long 148
+ .long 157
+ .section .debug_info.dwo,"e",@progbits
+ .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+ .short 5 # DWARF version number
+ .byte 5 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long 0 # Offset Into Abbrev. Section
+ .quad -3440409667494789237
+ .byte 1 # Abbrev [1] 0x14:0x95 DW_TAG_compile_unit
+ .byte 10 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 11 # DW_AT_name
+ .byte 12 # DW_AT_dwo_name
+ .byte 2 # Abbrev [2] 0x1a:0x24 DW_TAG_subprogram
+ .byte 3 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .long 88 # DW_AT_abstract_origin
+ .byte 3 # Abbrev [3] 0x26:0xb DW_TAG_variable
+ .byte 0 # DW_AT_name
+ .long 62 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 0
+ .byte 4 # Abbrev [4] 0x31:0x6 DW_TAG_formal_parameter
+ .byte 0 # DW_AT_location
+ .long 93 # DW_AT_abstract_origin
+ .byte 4 # Abbrev [4] 0x37:0x6 DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .long 101 # DW_AT_abstract_origin
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x3e:0x4 DW_TAG_base_type
+ .byte 1 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x42:0xb DW_TAG_variable
+ .byte 2 # DW_AT_name
+ .long 62 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 7 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 1
+ .byte 6 # Abbrev [6] 0x4d:0xb DW_TAG_variable
+ .byte 3 # DW_AT_name
+ .long 62 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # DW_AT_decl_file
+ .byte 8 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 161
+ .byte 2
+ .byte 7 # Abbrev [7] 0x58:0x16 DW_TAG_subprogram
+ .byte 4 # DW_AT_linkage_name
+ .byte 5 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ # DW_AT_external
+ # DW_AT_inline
+ .byte 8 # Abbrev [8] 0x5d:0x8 DW_TAG_formal_parameter
+ .byte 2 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 110 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x65:0x8 DW_TAG_formal_parameter
+ .byte 3 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 110 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x6e:0x5 DW_TAG_pointer_type
+ .long 62 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x73:0x27 DW_TAG_subprogram
+ .byte 0 # DW_AT_ranges
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 62 # DW_AT_type
+ # DW_AT_external
+ .byte 11 # Abbrev [11] 0x7e:0x9 DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 7 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 62 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x87:0x9 DW_TAG_formal_parameter
+ .byte 3 # DW_AT_location
+ .byte 8 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 154 # DW_AT_type
+ .byte 12 # Abbrev [12] 0x90:0x9 DW_TAG_inlined_subroutine
+ .long 88 # DW_AT_abstract_origin
+ .byte 1 # DW_AT_ranges
+ .byte 0 # DW_AT_call_file
+ .byte 12 # DW_AT_call_line
+ .byte 4 # DW_AT_call_column
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x9a:0x5 DW_TAG_pointer_type
+ .long 159 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x9f:0x5 DW_TAG_pointer_type
+ .long 164 # DW_AT_type
+ .byte 5 # Abbrev [5] 0xa4:0x4 DW_TAG_base_type
+ .byte 9 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_dwo_end0:
+ .section .debug_abbrev.dwo,"e",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 118 # DW_AT_dwo_name
+ .byte 37 # DW_FORM_strx1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 34 # DW_FORM_loclistx
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 32 # DW_AT_inline
+ .byte 33 # DW_FORM_implicit_const
+ .byte 1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 85 # DW_AT_ranges
+ .byte 35 # DW_FORM_rnglistx
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 34 # DW_FORM_loclistx
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 12 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 85 # DW_AT_ranges
+ .byte 35 # DW_FORM_rnglistx
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_rnglists.dwo,"e",@progbits
+ .long .Ldebug_list_header_end1-.Ldebug_list_header_start1 # Length
+.Ldebug_list_header_start1:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 2 # Offset entry count
+.Lrnglists_dwo_table_base0:
+ .long .Ldebug_ranges0-.Lrnglists_dwo_table_base0
+ .long .Ldebug_ranges1-.Lrnglists_dwo_table_base0
+.Ldebug_ranges0:
+ .byte 4 # DW_RLE_offset_pair
+ .uleb128 .Lfunc_begin1-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end1-.Lfunc_begin0 # ending offset
+ .byte 0 # DW_RLE_end_of_list
+.Ldebug_ranges1:
+ .byte 4 # DW_RLE_offset_pair
+ .uleb128 .Ltmp10-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp12-.Lfunc_begin0 # ending offset
+ .byte 4 # DW_RLE_offset_pair
+ .uleb128 .Ltmp14-.Lfunc_begin0 # starting offset
+ .uleb128 .Ltmp17-.Lfunc_begin0 # ending offset
+ .byte 0 # DW_RLE_end_of_list
+.Ldebug_list_header_end1:
+ .section .debug_addr,"",@progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad _ZZ3usePiS_E3Foo
+ .quad x
+ .quad y
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .section .debug_gnu_pubnames,"",@progbits
+ .long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
+.LpubNames_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 38 # DIE offset
+ .byte 160 # Attributes: VARIABLE, STATIC
+ .asciz "use::Foo" # External Name
+ .long 66 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "x" # External Name
+ .long 77 # DIE offset
+ .byte 32 # Attributes: VARIABLE, EXTERNAL
+ .asciz "y" # External Name
+ .long 88 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "use" # External Name
+ .long 115 # DIE offset
+ .byte 48 # Attributes: FUNCTION, EXTERNAL
+ .asciz "main" # External Name
+ .long 0 # End Mark
+.LpubNames_end0:
+ .section .debug_gnu_pubtypes,"",@progbits
+ .long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
+.LpubTypes_start0:
+ .short 2 # DWARF Version
+ .long .Lcu_begin0 # Offset of Compilation Unit Info
+ .long 40 # Compilation Unit Length
+ .long 62 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "int" # External Name
+ .long 164 # DIE offset
+ .byte 144 # Attributes: TYPE, STATIC
+ .asciz "char" # External Name
+ .long 0 # End Mark
+.LpubTypes_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 3a8db0f4bfb57348f49d9603119fa157114bbf8e)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .addrsig_sym _ZGVZ3usePiS_E3Foo
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/Inputs/dwarf5-loclist.s b/bolt/test/X86/Inputs/dwarf5-loclist.s
new file mode 100644
index 0000000000000..972c62146d357
--- /dev/null
+++ b/bolt/test/X86/Inputs/dwarf5-loclist.s
@@ -0,0 +1,393 @@
+# helper.cpp -O1 -g2 -gdwarf-5 -S -o helper.s
+# struct Foo1 {
+# int x;
+# int y;
+# };
+# inline __attribute__((always_inline))
+# static int helper(Foo1 &f) {
+# return f.x + 3;
+# }
+# int foo(int i) {
+# Foo1 foo;
+# foo.x = i;
+# foo.y = 3;
+# return helper(foo);
+# }
+
+ .text
+ .file "helper.cpp"
+ .globl _Z3fooi # -- Begin function _Z3fooi
+ .p2align 4, 0x90
+ .type _Z3fooi,@function
+_Z3fooi: # @_Z3fooi
+.Lfunc_begin0:
+ .file 0 "/dwarf4CrossCULocList" "helper.cpp" md5 0xc9271b4999165863c559e42d691423d1
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: foo:i <- $edi
+ #DEBUG_VALUE: foo:foo <- [DW_OP_LLVM_fragment 0 32] $edi
+ # kill: def $edi killed $edi def $rdi
+ #DEBUG_VALUE: foo:foo <- [DW_OP_LLVM_fragment 32 32] 3
+ .loc 0 7 14 prologue_end # helper.cpp:7:14
+ leal 3(%rdi), %eax
+.Ltmp0:
+ .loc 0 13 3 # helper.cpp:13:3
+ retq
+.Ltmp1:
+.Lfunc_end0:
+ .size _Z3fooi, .Lfunc_end0-_Z3fooi
+ .cfi_endproc
+ # -- End function
+ .section .debug_loclists,"",@progbits
+ .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
+.Ldebug_list_header_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 1 # Offset entry count
+.Lloclists_table_base0:
+ .long .Ldebug_loc0-.Lloclists_table_base0
+.Ldebug_loc0:
+ .byte 4 # DW_LLE_offset_pair
+ .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
+ .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
+ .byte 7 # Loc expr size
+ .byte 85 # super-register DW_OP_reg5
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .byte 51 # DW_OP_lit3
+ .byte 159 # DW_OP_stack_value
+ .byte 147 # DW_OP_piece
+ .byte 4 # 4
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_list_header_end0:
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .ascii "\214\001" # DW_AT_loclists_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 32 # DW_AT_inline
+ .byte 33 # DW_FORM_implicit_const
+ .byte 1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 16 # DW_TAG_reference_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 122 # DW_AT_call_all_calls
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 34 # DW_FORM_loclistx
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 0 # DW_CHILDREN_no
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x81 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .long .Lloclists_table_base0 # DW_AT_loclists_base
+ .byte 2 # Abbrev [2] 0x27:0x12 DW_TAG_subprogram
+ .byte 3 # DW_AT_linkage_name
+ .byte 4 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 57 # DW_AT_type
+ # DW_AT_inline
+ .byte 3 # Abbrev [3] 0x30:0x8 DW_TAG_formal_parameter
+ .byte 6 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 61 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 4 # Abbrev [4] 0x39:0x4 DW_TAG_base_type
+ .byte 5 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_reference_type
+ .long 66 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x42:0x19 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .byte 9 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 0 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 7 # Abbrev [7] 0x48:0x9 DW_TAG_member
+ .byte 7 # DW_AT_name
+ .long 57 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 7 # Abbrev [7] 0x51:0x9 DW_TAG_member
+ .byte 8 # DW_AT_name
+ .long 57 # DW_AT_type
+ .byte 0 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 8 # Abbrev [8] 0x5b:0x31 DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_call_all_calls
+ .byte 10 # DW_AT_linkage_name
+ .byte 11 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 57 # DW_AT_type
+ # DW_AT_external
+ .byte 9 # Abbrev [9] 0x6b:0xa DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .byte 12 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 9 # DW_AT_decl_line
+ .long 57 # DW_AT_type
+ .byte 10 # Abbrev [10] 0x75:0x9 DW_TAG_variable
+ .byte 0 # DW_AT_location
+ .byte 11 # DW_AT_name
+ .byte 0 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 66 # DW_AT_type
+ .byte 11 # Abbrev [11] 0x7e:0xd DW_TAG_inlined_subroutine
+ .long 39 # DW_AT_abstract_origin
+ .byte 0 # DW_AT_low_pc
+ .long .Ltmp0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 0 # DW_AT_call_file
+ .byte 13 # DW_AT_call_line
+ .byte 10 # DW_AT_call_column
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_str_offsets,"",@progbits
+ .long 56 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "helper.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/dwarf4CrossCULocList" # string offset=112
+.Linfo_string3:
+ .asciz "_ZL6helperR4Foo1" # string offset=171
+.Linfo_string4:
+ .asciz "helper" # string offset=188
+.Linfo_string5:
+ .asciz "int" # string offset=195
+.Linfo_string6:
+ .asciz "f" # string offset=199
+.Linfo_string7:
+ .asciz "x" # string offset=201
+.Linfo_string8:
+ .asciz "y" # string offset=203
+.Linfo_string9:
+ .asciz "Foo1" # string offset=205
+.Linfo_string10:
+ .asciz "_Z3fooi" # string offset=210
+.Linfo_string11:
+ .asciz "foo" # string offset=218
+.Linfo_string12:
+ .asciz "i" # string offset=222
+ .section .debug_str_offsets,"",@progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .long .Linfo_string5
+ .long .Linfo_string6
+ .long .Linfo_string7
+ .long .Linfo_string8
+ .long .Linfo_string9
+ .long .Linfo_string10
+ .long .Linfo_string11
+ .long .Linfo_string12
+ .section .debug_addr,"",@progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+.Ldebug_addr_end0:
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/bug-function-layout-execount.s b/bolt/test/X86/bug-function-layout-execount.s
new file mode 100644
index 0000000000000..540b6790d01e9
--- /dev/null
+++ b/bolt/test/X86/bug-function-layout-execount.s
@@ -0,0 +1,73 @@
+# Verifies that llvm-bolt correctly sorts functions by their execution counts.
+
+# REQUIRES: x86_64-linux, asserts
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
+# RUN: link_fdata %s %t.o %t.fdata
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe --data %t.fdata --lite --reorder-functions=exec-count \
+# RUN: -v=2 --debug-only=hfsort -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: Starting pass: reorder-functions
+# CHECK-NEXT: hot func func2 (1500)
+# CHECK-NEXT: hot func func1 (500)
+# CHECK-NEXT: hot func main (400)
+# CHECK-NEXT: hot func func5 (110)
+# CHECK-NEXT: hot func func3 (100)
+# CHECK-NEXT: hot func func4 (99)
+
+ .text
+ .globl main
+ .type main, %function
+main:
+# FDATA: 0 [unknown] 0 1 main 0 1 400
+ .cfi_startproc
+ call func1
+ retq
+ .size _start, .-_start
+ .cfi_endproc
+
+ .globl func1
+ .type func1,@function
+func1:
+# FDATA: 0 [unknown] 0 1 func1 0 1 500
+ .cfi_startproc
+ retq
+ .size func1, .-func1
+ .cfi_endproc
+
+ .globl func2
+ .type func2,@function
+func2:
+# FDATA: 0 [unknown] 0 1 func2 0 1 1500
+ .cfi_startproc
+ retq
+ .size func2, .-func2
+ .cfi_endproc
+
+ .globl func3
+ .type func3,@function
+func3:
+# FDATA: 0 [unknown] 0 1 func3 0 1 100
+ .cfi_startproc
+ retq
+ .size func3, .-func3
+ .cfi_endproc
+
+ .globl func4
+ .type func4,@function
+func4:
+# FDATA: 0 [unknown] 0 1 func4 0 1 99
+ .cfi_startproc
+ retq
+ .size func4, .-func4
+ .cfi_endproc
+
+ .globl func5
+ .type func5,@function
+func5:
+# FDATA: 0 [unknown] 0 1 func5 0 1 110
+ .cfi_startproc
+ retq
+ .size func5, .-func5
+ .cfi_endproc
diff --git a/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test b/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test
new file mode 100644
index 0000000000000..581ce2cffcfd4
--- /dev/null
+++ b/bolt/test/X86/dwarf4-cross-cu-loclist-dwarf4-loclist--dwarf5-loclist.test
@@ -0,0 +1,60 @@
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-cross-cu-with-loclist.s -o %t.o
+# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-loclist.s -o %t1.o
+# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-two-entries-loclist.s -o %t2.o
+# RUN: %clang %cflags %t1.o %t2.o %t.o -o %t.exe
+# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections
+# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
+# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.bolt | FileCheck --check-prefix=POSTCHECK %s
+
+# Tests that BOLT correctly handles location list with DWARF5/DWARF4 when order of CUs is not the same as in input.
+
+# PRECHECK: version = 0x0005
+# PRECHECK: version = 0x0004
+# PRECHECK: version = 0x0004
+# PRECHECK: version = 0x0004
+
+# POSTCHECK: version = 0x0004
+# POSTCHECK: DW_TAG_formal_parameter
+# POSTCHECK-NEXT: DW_AT_location
+# POSTCHECK-NEXT: DW_AT_name
+# POSTCHECK-NEXT: DW_AT_decl_file
+# POSTCHECK-NEXT: DW_AT_decl_line
+# POSTCHECK-NEXT: DW_AT_type [DW_FORM_ref_addr]
+# POSTCHECK-SAME: "int")
+
+# POSTCHECK: DW_TAG_variable
+# POSTCHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR1:]]
+# POSTCHECK-SAME: 0x[[#ADDR1 + 0x8]]):
+# POSTCHECK-SAME: DW_OP_reg5 RDI, DW_OP_piece 0x4, DW_OP_lit3, DW_OP_stack_value, DW_OP_piece 0x4)
+
+# POSTCHECK: version = 0x0004
+# POSTCHECK: DW_TAG_variable
+# POSTCHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR2:]]
+# POSTCHECK-SAME: 0x[[#ADDR2 + 0x4]]):
+# POSTCHECK-SAME: DW_OP_reg5 RDI, DW_OP_piece 0x4, DW_OP_lit3, DW_OP_stack_value, DW_OP_piece 0x4)
+
+# POSTCHECK: version = 0x0005
+# POSTCHECK: DW_TAG_variable
+# POSTCHECK-NEXT: DW_AT_location [DW_FORM_loclistx] (indexed (0x0) loclist
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR3:]]
+# POSTCHECK-SAME: 0x[[#ADDR3 + 0x4]]):
+# POSTCHECK-SAME: DW_OP_reg5 RDI, DW_OP_piece 0x4, DW_OP_lit3, DW_OP_stack_value, DW_OP_piece 0x4)
+
+# POSTCHECK: version = 0x0004
+# POSTCHECK: DW_TAG_formal_parameter
+# POSTCHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR4:]]
+# POSTCHECK-SAME: 0x[[#ADDR4 + 0x8]]): DW_OP_reg5 RDI
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR5:]]
+# POSTCHECK-SAME: 0x[[#ADDR5 + 0x16]]): DW_OP_GNU_entry_value(DW_OP_reg5 RDI), DW_OP_stack_value)
+# POSTCHECK: DW_TAG_formal_parameter
+# POSTCHECK: DW_TAG_formal_parameter
+# POSTCHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR6:]]
+# POSTCHECK-SAME: 0x[[#ADDR6 + 0x8]]): DW_OP_reg5 RDI
+# POSTCHECK-NEXT: [0x[[#%.16x,ADDR7:]]
+# POSTCHECK-SAME: 0x[[#ADDR7 + 0x16]]): DW_OP_GNU_entry_value(DW_OP_reg5 RDI), DW_OP_stack_value)
diff --git a/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test b/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test
new file mode 100644
index 0000000000000..e00958d106141
--- /dev/null
+++ b/bolt/test/X86/dwarf4-df-call-site-change-low-pc.test
@@ -0,0 +1,27 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-call-site-change-low-pc-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-call-site-change-low-pc-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-4 -O2 -gsplit-dwarf=split main.o helper.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo &> %t/maindwo.txt
+; RUN: cat %t/maindwo.txt | FileCheck -check-prefix=PRE-BOLT-DWO-MAIN %s
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt
+; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s
+
+; Tests that DW_AT_low_pc changes in DW_TAG_GNU_call_site.
+
+; PRE-BOLT-DWO-MAIN: version = 0x0004
+; PRE-BOLT-DWO-MAIN: DW_TAG_GNU_call_site
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_abstract_origin
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_GNU_tail_call
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000004)
+
+; BOLT-DWO-MAIN: version = 0x0004
+; BOLT-DWO-MAIN: DW_TAG_GNU_call_site
+; BOLT-DWO-MAIN-NEXT: DW_AT_abstract_origin
+; BOLT-DWO-MAIN-NEXT: DW_AT_GNU_tail_call
+; BOLT-DWO-MAIN-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000005)
diff --git a/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test b/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test
new file mode 100644
index 0000000000000..5173c890f66ab
--- /dev/null
+++ b/bolt/test/X86/dwarf4-df-change-in-dw-op-gnu-addr-index-main.test
@@ -0,0 +1,23 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf4-df-change-in-dw-op-gnu-addr-index-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo &> %t/maindwo.txt
+; RUN: cat %t/maindwo.txt | FileCheck -check-prefix=PRE-BOLT-DWO-MAIN %s
+; RUN: not llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt
+; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s
+
+; Tests that new indices are assigned to DW_OP_GNU_addr_index.
+
+; PRE-BOLT-DWO-MAIN: version = 0x0004
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x0)
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x1)
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x2)
+
+; BOLT-DWO-MAIN: version = 0x0004
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x1)
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x6)
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x7)
diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s
new file mode 100755
index 0000000000000..4cf0d3d0e2558
--- /dev/null
+++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-no-internal-dwarf-error.s
@@ -0,0 +1,408 @@
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
+# RUN: %clang %cflags -dwarf-4 %t1.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections -v 1 &> %tlog.txt
+# RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s
+# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s
+
+# Tests BOLT does not assert when DIE reference is invalid.
+
+# CHECKBOLT: Referenced DIE offsets not in .debug_info
+# CHECKBOLT-NEXT: 91
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name
+# CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0091 => {0x00000091})
+
+# Assembly manually modified
+# struct pair {int i; int j; };
+# static pair p;
+# int load() {
+# return p.i + p.j;
+# }
+# void store(int i, int j) {
+# p.i = i;
+# p.j = j;
+# }
+# int main() {
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .file 1 "/invalidWithin" "main.cpp"
+ .section .text._Z4loadv,"ax",@progbits
+ .globl _Z4loadv # -- Begin function _Z4loadv
+ .p2align 4, 0x90
+ .type _Z4loadv,@function
+_Z4loadv: # @_Z4loadv
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 4 20 prologue_end # main.cpp:4:20
+ movl _ZL1p.1(%rip), %eax
+ .loc 1 4 16 is_stmt 0 # main.cpp:4:16
+ addl _ZL1p.0(%rip), %eax
+ .loc 1 4 5 # main.cpp:4:5
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size _Z4loadv, .Lfunc_end0-_Z4loadv
+ .cfi_endproc
+ # -- End function
+ .section .text._Z5storeii,"ax",@progbits
+ .globl _Z5storeii # -- Begin function _Z5storeii
+ .p2align 4, 0x90
+ .type _Z5storeii,@function
+_Z5storeii: # @_Z5storeii
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: store:i <- $edi
+ #DEBUG_VALUE: store:j <- $esi
+ .loc 1 7 9 prologue_end is_stmt 1 # main.cpp:7:9
+ movl %edi, _ZL1p.0(%rip)
+ .loc 1 8 9 # main.cpp:8:9
+ movl %esi, _ZL1p.1(%rip)
+ .loc 1 9 1 # main.cpp:9:1
+ retq
+.Ltmp1:
+.Lfunc_end1:
+ .size _Z5storeii, .Lfunc_end1-_Z5storeii
+ .cfi_endproc
+ # -- End function
+ .section .text.main,"ax",@progbits
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin2:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 11 1 prologue_end # main.cpp:11:1
+ xorl %eax, %eax
+ retq
+.Ltmp2:
+.Lfunc_end2:
+ .size main, .Lfunc_end2-main
+ .cfi_endproc
+ # -- End function
+ .type _ZL1p.0,@object # @_ZL1p.0
+ .local _ZL1p.0
+ .comm _ZL1p.0,4,4
+ .type _ZL1p.1,@object # @_ZL1p.1
+ .local _ZL1p.1
+ .comm _ZL1p.1,4,4
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 85 # DW_AT_ranges
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xd9 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad 0 # DW_AT_low_pc
+ .long .Ldebug_ranges0 # DW_AT_ranges
+ .byte 2 # Abbrev [2] 0x2a:0x26 DW_TAG_variable
+ .long .Linfo_string3 # DW_AT_name
+ .long 145 # DW_AT_type --> Modified manually s/80/145
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 22 # DW_AT_location
+ .byte 3
+ .quad _ZL1p.0
+ .byte 147
+ .byte 4
+ .byte 3
+ .quad _ZL1p.1
+ .byte 147
+ .byte 4
+ .long .Linfo_string8 # DW_AT_linkage_name
+ .byte 3 # Abbrev [3] 0x50:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .long .Linfo_string7 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x59:0xc DW_TAG_member
+ .long .Linfo_string4 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x65:0xc DW_TAG_member
+ .long .Linfo_string6 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x72:0x7 DW_TAG_base_type
+ .long .Linfo_string5 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x79:0x1d DW_TAG_subprogram
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string9 # DW_AT_linkage_name
+ .long .Linfo_string10 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 7 # Abbrev [7] 0x96:0x34 DW_TAG_subprogram
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string11 # DW_AT_linkage_name
+ .long .Linfo_string12 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0xaf:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .long .Linfo_string4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 8 # Abbrev [8] 0xbc:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0xca:0x19 DW_TAG_subprogram
+ .quad .Lfunc_begin2 # DW_AT_low_pc
+ .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string13 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+ .quad .Lfunc_begin0
+ .quad .Lfunc_end0
+ .quad .Lfunc_begin1
+ .quad .Lfunc_end1
+ .quad .Lfunc_begin2
+ .quad .Lfunc_end2
+ .quad 0
+ .quad 0
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/invalidWithin" # string offset=110
+.Linfo_string3:
+ .asciz "p" # string offset=162
+.Linfo_string4:
+ .asciz "i" # string offset=164
+.Linfo_string5:
+ .asciz "int" # string offset=166
+.Linfo_string6:
+ .asciz "j" # string offset=170
+.Linfo_string7:
+ .asciz "pair" # string offset=172
+.Linfo_string8:
+ .asciz "_ZL1p" # string offset=177
+.Linfo_string9:
+ .asciz "_Z4loadv" # string offset=183
+.Linfo_string10:
+ .asciz "load" # string offset=192
+.Linfo_string11:
+ .asciz "_Z5storeii" # string offset=197
+.Linfo_string12:
+ .asciz "store" # string offset=208
+.Linfo_string13:
+ .asciz "main" # string offset=214
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s
new file mode 100755
index 0000000000000..9d27c9cd9ff87
--- /dev/null
+++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-cant-parse-die.s
@@ -0,0 +1,408 @@
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
+# RUN: %clang %cflags -dwarf-4 %t1.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections -v 1 &> %tlog.txt
+# RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s
+# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s
+
+# Tests BOLT does not assert when DIE reference is invalid.
+
+# CHECKBOLT: BOLT-WARNING: [internal-dwarf-error]: could not parse referenced DIE at offset:
+# CHECKBOLT-NOT: Referenced DIE offsets not in .debug_info
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name
+# CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x008c => {0x0000008c})
+
+# Assembly manually modified
+# struct pair {int i; int j; };
+# static pair p;
+# int load() {
+# return p.i + p.j;
+# }
+# void store(int i, int j) {
+# p.i = i;
+# p.j = j;
+# }
+# int main() {
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .file 1 "/invalidWithin" "main.cpp"
+ .section .text._Z4loadv,"ax",@progbits
+ .globl _Z4loadv # -- Begin function _Z4loadv
+ .p2align 4, 0x90
+ .type _Z4loadv,@function
+_Z4loadv: # @_Z4loadv
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 4 20 prologue_end # main.cpp:4:20
+ movl _ZL1p.1(%rip), %eax
+ .loc 1 4 16 is_stmt 0 # main.cpp:4:16
+ addl _ZL1p.0(%rip), %eax
+ .loc 1 4 5 # main.cpp:4:5
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size _Z4loadv, .Lfunc_end0-_Z4loadv
+ .cfi_endproc
+ # -- End function
+ .section .text._Z5storeii,"ax",@progbits
+ .globl _Z5storeii # -- Begin function _Z5storeii
+ .p2align 4, 0x90
+ .type _Z5storeii,@function
+_Z5storeii: # @_Z5storeii
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: store:i <- $edi
+ #DEBUG_VALUE: store:j <- $esi
+ .loc 1 7 9 prologue_end is_stmt 1 # main.cpp:7:9
+ movl %edi, _ZL1p.0(%rip)
+ .loc 1 8 9 # main.cpp:8:9
+ movl %esi, _ZL1p.1(%rip)
+ .loc 1 9 1 # main.cpp:9:1
+ retq
+.Ltmp1:
+.Lfunc_end1:
+ .size _Z5storeii, .Lfunc_end1-_Z5storeii
+ .cfi_endproc
+ # -- End function
+ .section .text.main,"ax",@progbits
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin2:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 11 1 prologue_end # main.cpp:11:1
+ xorl %eax, %eax
+ retq
+.Ltmp2:
+.Lfunc_end2:
+ .size main, .Lfunc_end2-main
+ .cfi_endproc
+ # -- End function
+ .type _ZL1p.0,@object # @_ZL1p.0
+ .local _ZL1p.0
+ .comm _ZL1p.0,4,4
+ .type _ZL1p.1,@object # @_ZL1p.1
+ .local _ZL1p.1
+ .comm _ZL1p.1,4,4
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 85 # DW_AT_ranges
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xd9 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad 0 # DW_AT_low_pc
+ .long .Ldebug_ranges0 # DW_AT_ranges
+ .byte 2 # Abbrev [2] 0x2a:0x26 DW_TAG_variable
+ .long .Linfo_string3 # DW_AT_name
+ .long 140 # DW_AT_type --> Modified manually s/80/140
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 22 # DW_AT_location
+ .byte 3
+ .quad _ZL1p.0
+ .byte 147
+ .byte 4
+ .byte 3
+ .quad _ZL1p.1
+ .byte 147
+ .byte 4
+ .long .Linfo_string8 # DW_AT_linkage_name
+ .byte 3 # Abbrev [3] 0x50:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .long .Linfo_string7 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x59:0xc DW_TAG_member
+ .long .Linfo_string4 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x65:0xc DW_TAG_member
+ .long .Linfo_string6 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x72:0x7 DW_TAG_base_type
+ .long .Linfo_string5 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x79:0x1d DW_TAG_subprogram
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string9 # DW_AT_linkage_name
+ .long .Linfo_string10 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 7 # Abbrev [7] 0x96:0x34 DW_TAG_subprogram
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string11 # DW_AT_linkage_name
+ .long .Linfo_string12 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0xaf:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .long .Linfo_string4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 8 # Abbrev [8] 0xbc:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0xca:0x19 DW_TAG_subprogram
+ .quad .Lfunc_begin2 # DW_AT_low_pc
+ .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string13 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+ .quad .Lfunc_begin0
+ .quad .Lfunc_end0
+ .quad .Lfunc_begin1
+ .quad .Lfunc_end1
+ .quad .Lfunc_begin2
+ .quad .Lfunc_end2
+ .quad 0
+ .quad 0
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/invalidWithin" # string offset=110
+.Linfo_string3:
+ .asciz "p" # string offset=162
+.Linfo_string4:
+ .asciz "i" # string offset=164
+.Linfo_string5:
+ .asciz "int" # string offset=166
+.Linfo_string6:
+ .asciz "j" # string offset=170
+.Linfo_string7:
+ .asciz "pair" # string offset=172
+.Linfo_string8:
+ .asciz "_ZL1p" # string offset=177
+.Linfo_string9:
+ .asciz "_Z4loadv" # string offset=183
+.Linfo_string10:
+ .asciz "load" # string offset=192
+.Linfo_string11:
+ .asciz "_Z5storeii" # string offset=197
+.Linfo_string12:
+ .asciz "store" # string offset=208
+.Linfo_string13:
+ .asciz "main" # string offset=214
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s
new file mode 100755
index 0000000000000..b9cbf513bb26f
--- /dev/null
+++ b/bolt/test/X86/dwarf4-invalid-reference-die-offset-with-internal-dwarf-error-invalid-die.s
@@ -0,0 +1,408 @@
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
+# RUN: %clang %cflags -dwarf-4 %t1.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections -v 1 &> %tlog.txt
+# RUN: cat %tlog.txt | FileCheck --check-prefix=CHECKBOLT %s
+# RUN: llvm-dwarfdump --show-form --verbose --debug-info %t.exe | FileCheck --check-prefix=CHECK %s
+
+# Tests BOLT does not assert when DIE reference is invalid.
+
+# CHECKBOLT: BOLT-WARNING: [internal-dwarf-error]: invalid referenced DIE at offset:
+# CHECKBOLT-NOT: Referenced DIE offsets not in .debug_info
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name
+# CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x008f => {0x0000008f})
+
+# Assembly manually modified
+# struct pair {int i; int j; };
+# static pair p;
+# int load() {
+# return p.i + p.j;
+# }
+# void store(int i, int j) {
+# p.i = i;
+# p.j = j;
+# }
+# int main() {
+# return 0;
+# }
+
+ .text
+ .file "main.cpp"
+ .file 1 "/invalidWithin" "main.cpp"
+ .section .text._Z4loadv,"ax",@progbits
+ .globl _Z4loadv # -- Begin function _Z4loadv
+ .p2align 4, 0x90
+ .type _Z4loadv,@function
+_Z4loadv: # @_Z4loadv
+.Lfunc_begin0:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 4 20 prologue_end # main.cpp:4:20
+ movl _ZL1p.1(%rip), %eax
+ .loc 1 4 16 is_stmt 0 # main.cpp:4:16
+ addl _ZL1p.0(%rip), %eax
+ .loc 1 4 5 # main.cpp:4:5
+ retq
+.Ltmp0:
+.Lfunc_end0:
+ .size _Z4loadv, .Lfunc_end0-_Z4loadv
+ .cfi_endproc
+ # -- End function
+ .section .text._Z5storeii,"ax",@progbits
+ .globl _Z5storeii # -- Begin function _Z5storeii
+ .p2align 4, 0x90
+ .type _Z5storeii,@function
+_Z5storeii: # @_Z5storeii
+.Lfunc_begin1:
+ .cfi_startproc
+# %bb.0: # %entry
+ #DEBUG_VALUE: store:i <- $edi
+ #DEBUG_VALUE: store:j <- $esi
+ .loc 1 7 9 prologue_end is_stmt 1 # main.cpp:7:9
+ movl %edi, _ZL1p.0(%rip)
+ .loc 1 8 9 # main.cpp:8:9
+ movl %esi, _ZL1p.1(%rip)
+ .loc 1 9 1 # main.cpp:9:1
+ retq
+.Ltmp1:
+.Lfunc_end1:
+ .size _Z5storeii, .Lfunc_end1-_Z5storeii
+ .cfi_endproc
+ # -- End function
+ .section .text.main,"ax",@progbits
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main,@function
+main: # @main
+.Lfunc_begin2:
+ .cfi_startproc
+# %bb.0: # %entry
+ .loc 1 11 1 prologue_end # main.cpp:11:1
+ xorl %eax, %eax
+ retq
+.Ltmp2:
+.Lfunc_end2:
+ .size main, .Lfunc_end2-main
+ .cfi_endproc
+ # -- End function
+ .type _ZL1p.0,@object # @_ZL1p.0
+ .local _ZL1p.0
+ .comm _ZL1p.0,4,4
+ .type _ZL1p.1,@object # @_ZL1p.1
+ .local _ZL1p.1
+ .comm _ZL1p.1,4,4
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 85 # DW_AT_ranges
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 19 # DW_TAG_structure_type
+ .byte 1 # DW_CHILDREN_yes
+ .byte 54 # DW_AT_calling_convention
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 13 # DW_TAG_member
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 56 # DW_AT_data_member_location
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 110 # DW_AT_linkage_name
+ .byte 14 # DW_FORM_strp
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 17 # DW_AT_low_pc
+ .byte 1 # DW_FORM_addr
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .ascii "\227B" # DW_AT_GNU_all_call_sites
+ .byte 25 # DW_FORM_flag_present
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0xd9 DW_TAG_compile_unit
+ .long .Linfo_string0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .long .Linfo_string1 # DW_AT_name
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .long .Linfo_string2 # DW_AT_comp_dir
+ .quad 0 # DW_AT_low_pc
+ .long .Ldebug_ranges0 # DW_AT_ranges
+ .byte 2 # Abbrev [2] 0x2a:0x26 DW_TAG_variable
+ .long .Linfo_string3 # DW_AT_name
+ .long 143 # DW_AT_type --> Modified manually s/80/143
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .byte 22 # DW_AT_location
+ .byte 3
+ .quad _ZL1p.0
+ .byte 147
+ .byte 4
+ .byte 3
+ .quad _ZL1p.1
+ .byte 147
+ .byte 4
+ .long .Linfo_string8 # DW_AT_linkage_name
+ .byte 3 # Abbrev [3] 0x50:0x22 DW_TAG_structure_type
+ .byte 5 # DW_AT_calling_convention
+ .long .Linfo_string7 # DW_AT_name
+ .byte 8 # DW_AT_byte_size
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # Abbrev [4] 0x59:0xc DW_TAG_member
+ .long .Linfo_string4 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 0 # DW_AT_data_member_location
+ .byte 4 # Abbrev [4] 0x65:0xc DW_TAG_member
+ .long .Linfo_string6 # DW_AT_name
+ .long 114 # DW_AT_type
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 4 # DW_AT_data_member_location
+ .byte 0 # End Of Children Mark
+ .byte 5 # Abbrev [5] 0x72:0x7 DW_TAG_base_type
+ .long .Linfo_string5 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 6 # Abbrev [6] 0x79:0x1d DW_TAG_subprogram
+ .quad .Lfunc_begin0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string9 # DW_AT_linkage_name
+ .long .Linfo_string10 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 7 # Abbrev [7] 0x96:0x34 DW_TAG_subprogram
+ .quad .Lfunc_begin1 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string11 # DW_AT_linkage_name
+ .long .Linfo_string12 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ # DW_AT_external
+ .byte 8 # Abbrev [8] 0xaf:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 85
+ .long .Linfo_string4 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 8 # Abbrev [8] 0xbc:0xd DW_TAG_formal_parameter
+ .byte 1 # DW_AT_location
+ .byte 84
+ .long .Linfo_string6 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 6 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0xca:0x19 DW_TAG_subprogram
+ .quad .Lfunc_begin2 # DW_AT_low_pc
+ .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 87
+ # DW_AT_GNU_all_call_sites
+ .long .Linfo_string13 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 10 # DW_AT_decl_line
+ .long 114 # DW_AT_type
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+ .section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+ .quad .Lfunc_begin0
+ .quad .Lfunc_end0
+ .quad .Lfunc_begin1
+ .quad .Lfunc_end1
+ .quad .Lfunc_begin2
+ .quad .Lfunc_end2
+ .quad 0
+ .quad 0
+ .section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=101
+.Linfo_string2:
+ .asciz "/invalidWithin" # string offset=110
+.Linfo_string3:
+ .asciz "p" # string offset=162
+.Linfo_string4:
+ .asciz "i" # string offset=164
+.Linfo_string5:
+ .asciz "int" # string offset=166
+.Linfo_string6:
+ .asciz "j" # string offset=170
+.Linfo_string7:
+ .asciz "pair" # string offset=172
+.Linfo_string8:
+ .asciz "_ZL1p" # string offset=177
+.Linfo_string9:
+ .asciz "_Z4loadv" # string offset=183
+.Linfo_string10:
+ .asciz "load" # string offset=192
+.Linfo_string11:
+ .asciz "_Z5storeii" # string offset=197
+.Linfo_string12:
+ .asciz "store" # string offset=208
+.Linfo_string13:
+ .asciz "main" # string offset=214
+ .ident "clang version 18.0.0 (git@github.com:llvm/llvm-project.git 37d6c1cc7d4dd3a8a47ba62254bc88521bd50d66)"
+ .section ".note.GNU-stack","",@progbits
+ .addrsig
+ .section .debug_line,"",@progbits
+.Lline_table_start0:
diff --git a/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test b/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test
new file mode 100644
index 0000000000000..ea717a5e0888d
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-call-site-change-low-pc.test
@@ -0,0 +1,27 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=4 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-call-site-change-low-pc-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-call-site-change-low-pc-helper.s \
+; RUN: -split-dwarf-file=helper.dwo -o helper.o
+; RUN: %clang %cflags -gdwarf-5 -O2 -gsplit-dwarf=split main.o helper.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo &> %t/maindwo.txt
+; RUN: cat %t/maindwo.txt | FileCheck -check-prefix=PRE-BOLT-DWO-MAIN %s
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt
+; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s
+
+; Tests that DW_AT_low_pc changes in DW_TAG_call_site.
+
+; PRE-BOLT-DWO-MAIN: version = 0x0005
+; PRE-BOLT-DWO-MAIN: DW_TAG_call_site
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_call_origin
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_call_tail_call
+; PRE-BOLT-DWO-MAIN-NEXT: DW_AT_call_pc [DW_FORM_addrx] (indexed (00000003)
+
+; BOLT-DWO-MAIN: version = 0x0005
+; BOLT-DWO-MAIN: DW_TAG_call_site
+; BOLT-DWO-MAIN-NEXT: DW_AT_call_origin
+; BOLT-DWO-MAIN-NEXT: DW_AT_call_tail_call
+; BOLT-DWO-MAIN-NEXT: DW_AT_call_pc [DW_FORM_addrx] (indexed (00000004)
diff --git a/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test b/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test
new file mode 100644
index 0000000000000..f266caec7af3b
--- /dev/null
+++ b/bolt/test/X86/dwarf5-df-change-in-dw-op-gnu-addr-index-main.test
@@ -0,0 +1,23 @@
+; RUN: rm -rf %t
+; RUN: mkdir %t
+; RUN: cd %t
+; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-change-in-dw-op-gnu-addr-index-main.s \
+; RUN: -split-dwarf-file=main.dwo -o main.o
+; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o -o main.exe
+; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo &> %t/maindwo.txt
+; RUN: cat %t/maindwo.txt | FileCheck -check-prefix=PRE-BOLT-DWO-MAIN %s
+; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.dwo.dwo &> %t/maindwodwo.txt
+; RUN: cat %t/maindwodwo.txt | FileCheck -check-prefix=BOLT-DWO-MAIN %s
+
+; Tests that new indices are assigned to DW_OP_GNU_addr_index.
+
+; PRE-BOLT-DWO-MAIN: version = 0x0005
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0)
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x1)
+; PRE-BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x2)
+
+; BOLT-DWO-MAIN: version = 0x0005
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x1)
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x2)
+; BOLT-DWO-MAIN: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x3)
diff --git a/bolt/test/runtime/X86/reg-reassign-swap-cold.s b/bolt/test/runtime/X86/reg-reassign-swap-cold.s
new file mode 100644
index 0000000000000..115b5b0eeff8b
--- /dev/null
+++ b/bolt/test/runtime/X86/reg-reassign-swap-cold.s
@@ -0,0 +1,64 @@
+# This test case reproduces a bug where, during register swapping,
+# the code fragments associated with the function need to be swapped
+# together (which may be generated during PGO optimization). If not
+# handled properly, optimized binary execution can result in a segmentation fault.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
+# RUN: link_fdata %s %t.o %t.fdata
+# RUN: llvm-strip --strip-unneeded %t.o
+# RUN: %clang -no-pie %t.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.out -data=%t.fdata --reg-reassign | FileCheck %s
+# RUN: %t.out
+
+# CHECK: BOLT-INFO: Reg Reassignment Pass Stats
+# CHECK-NEXT: 2 functions affected.
+ .text
+ .globl main
+ .globl main.cold
+ .p2align 4, 0x90
+ .type main,@function
+ .type main.cold,@function
+main.cold:
+bb1:
+ cmp $0x3, %r12
+ jne bb8
+bb2:
+ jmp bb4
+main: # @main
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rax
+ pushq %r12
+ pushq %rbx
+ .cfi_def_cfa_offset 16
+ mov $0x1, %r12
+ mov $0x2, %rbx
+ add $0x1, %r12
+ shr $0x14, %r12
+ mov $0x3, %r12
+bb3:
+ jmp bb1
+bb4:
+ cmp $0x3, %r12
+bb5:
+ jne bb8
+bb6:
+ xorl %eax, %eax
+bb7:
+ popq %rcx
+ popq %rbx
+ popq %r12
+ .cfi_def_cfa_offset 8
+ retq
+bb8:
+ mov $0x1, %rax
+ jmp bb7
+# FDATA: 1 main.cold #bb2# 1 main #bb4# 0 100
+# FDATA: 1 main #bb5# 1 main #bb6# 0 100
+# FDATA: 1 main #bb3# 1 main.cold 0 0 100
+
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
diff --git a/clang-tools-extra/clang-include-fixer/IncludeFixer.cpp b/clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
index 45fc15619ecab..1bb5cf756b95b 100644
--- a/clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
+++ b/clang-tools-extra/clang-include-fixer/IncludeFixer.cpp
@@ -314,11 +314,11 @@ std::string IncludeFixerSemaSource::minimizeInclude(
if (!Entry)
return std::string(Include);
- bool IsSystem = false;
+ bool IsAngled = false;
std::string Suggestion =
- HeaderSearch.suggestPathToFileForDiagnostics(*Entry, "", &IsSystem);
+ HeaderSearch.suggestPathToFileForDiagnostics(*Entry, "", &IsAngled);
- return IsSystem ? '<' + Suggestion + '>' : '"' + Suggestion + '"';
+ return IsAngled ? '<' + Suggestion + '>' : '"' + Suggestion + '"';
}
/// Get the include fixer context for the queried symbol.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index 019d9b1f18a5a..41a210a83a84f 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -437,8 +437,11 @@ void ClangTidyDiagnosticConsumer::HandleDiagnostic(
SmallString<100> Message;
Info.FormatDiagnostic(Message);
FullSourceLoc Loc;
- if (Info.getLocation().isValid() && Info.hasSourceManager())
+ if (Info.hasSourceManager())
Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
+ else if (Context.DiagEngine->hasSourceManager())
+ Loc = FullSourceLoc(Info.getLocation(),
+ Context.DiagEngine->getSourceManager());
Converter.emitDiagnostic(Loc, DiagLevel, Message, Info.getRanges(),
Info.getFixItHints());
}
diff --git a/clang-tools-extra/clang-tidy/add_new_check.py b/clang-tools-extra/clang-tidy/add_new_check.py
index c642000eba228..520212883d997 100755
--- a/clang-tools-extra/clang-tidy/add_new_check.py
+++ b/clang-tools-extra/clang-tidy/add_new_check.py
@@ -483,7 +483,7 @@ def process_doc(doc_file):
def format_link(doc_file):
check_name, match = process_doc(doc_file)
- if not match and check_name:
+ if not match and check_name and not check_name.startswith("clang-analyzer-"):
return " `%(check_name)s <%(module)s/%(check)s.html>`_,%(autofix)s\n" % {
"check_name": check_name,
"module": doc_file[0],
@@ -495,13 +495,13 @@ def format_link(doc_file):
def format_link_alias(doc_file):
check_name, match = process_doc(doc_file)
- if match and check_name:
+ if (match or (check_name.startswith("clang-analyzer-"))) and check_name:
module = doc_file[0]
check_file = doc_file[1].replace(".rst", "")
- if match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers":
+ if not match or match.group(1) == "https://clang.llvm.org/docs/analyzer/checkers":
title = "Clang Static Analyzer " + check_file
# Preserve the anchor in checkers.html from group 2.
- target = match.group(1) + ".html" + match.group(2)
+ target = "" if not match else match.group(1) + ".html" + match.group(2)
autofix = ""
else:
redirect_parts = re.search("^\.\./([^/]*)/([^/]*)$", match.group(1))
@@ -509,18 +509,30 @@ def format_link_alias(doc_file):
target = redirect_parts[1] + "/" + redirect_parts[2] + ".html"
autofix = has_auto_fix(title)
- # The checker is just a redirect.
- return (
- " `%(check_name)s <%(module)s/%(check_file)s.html>`_, `%(title)s <%(target)s>`_,%(autofix)s\n"
- % {
- "check_name": check_name,
- "module": module,
- "check_file": check_file,
- "target": target,
- "title": title,
- "autofix": autofix,
- }
- )
+ if target:
+ # The checker is just a redirect.
+ return (
+ " `%(check_name)s <%(module)s/%(check_file)s.html>`_, `%(title)s <%(target)s>`_,%(autofix)s\n"
+ % {
+ "check_name": check_name,
+ "module": module,
+ "check_file": check_file,
+ "target": target,
+ "title": title,
+ "autofix": autofix,
+ })
+ else:
+ # The checker is just a alias without redirect.
+ return (
+ " `%(check_name)s <%(module)s/%(check_file)s.html>`_, %(title)s,%(autofix)s\n"
+ % {
+ "check_name": check_name,
+ "module": module,
+ "check_file": check_file,
+ "target": target,
+ "title": title,
+ "autofix": autofix,
+ })
return ""
checks = map(format_link, doc_files)
diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
index 2f155820a83e5..a01b7f5a4ee6e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp
@@ -19,6 +19,8 @@ namespace clang::tidy::bugprone {
namespace {
+static constexpr bool DefaultIgnoreMacros = false;
+
// Keep track of macro expansions that contain both __FILE__ and __LINE__. If
// such a macro also uses __func__ or __FUNCTION__, we don't want to issue a
// warning because __FILE__ and __LINE__ may be useful even if __func__ or
@@ -56,6 +58,16 @@ class MacroExpansionsWithFileAndLine : public PPCallbacks {
} // namespace
+LambdaFunctionNameCheck::LambdaFunctionNameCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IgnoreMacros(
+ Options.getLocalOrGlobal("IgnoreMacros", DefaultIgnoreMacros)) {}
+
+void LambdaFunctionNameCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IgnoreMacros", IgnoreMacros);
+}
+
void LambdaFunctionNameCheck::registerMatchers(MatchFinder *Finder) {
// Match on PredefinedExprs inside a lambda.
Finder->addMatcher(predefinedExpr(hasAncestor(lambdaExpr())).bind("E"),
@@ -76,6 +88,9 @@ void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) {
return;
}
if (E->getLocation().isMacroID()) {
+ if (IgnoreMacros)
+ return;
+
auto ER =
Result.SourceManager->getImmediateExpansionRange(E->getLocation());
if (SuppressMacroExpansions.find(ER.getAsRange()) !=
@@ -84,6 +99,7 @@ void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) {
return;
}
}
+
diag(E->getLocation(),
"inside a lambda, '%0' expands to the name of the function call "
"operator; consider capturing the name of the enclosing function "
diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h
index 03f1c4544aee1..dab64f74aa6ca 100644
--- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h
@@ -31,8 +31,9 @@ class LambdaFunctionNameCheck : public ClangTidyCheck {
};
using SourceRangeSet = std::set;
- LambdaFunctionNameCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ LambdaFunctionNameCheck(StringRef Name, ClangTidyContext *Context);
+
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
@@ -40,6 +41,7 @@ class LambdaFunctionNameCheck : public ClangTidyCheck {
private:
SourceRangeSet SuppressMacroExpansions;
+ bool IgnoreMacros;
};
} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
index c2cde34fb1336..eb35bbc6a538f 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt
@@ -18,6 +18,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule
MissingStdForwardCheck.cpp
NarrowingConversionsCheck.cpp
NoMallocCheck.cpp
+ NoSuspendWithLockCheck.cpp
OwningMemoryCheck.cpp
PreferMemberInitializerCheck.cpp
ProBoundsArrayToPointerDecayCheck.cpp
@@ -50,6 +51,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule
clang_target_link_libraries(clangTidyCppCoreGuidelinesModule
PRIVATE
+ clangAnalysis
clangAST
clangASTMatchers
clangBasic
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
index fdbf0e11f3f5f..e9f0201615616 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -32,6 +32,7 @@
#include "MissingStdForwardCheck.h"
#include "NarrowingConversionsCheck.h"
#include "NoMallocCheck.h"
+#include "NoSuspendWithLockCheck.h"
#include "OwningMemoryCheck.h"
#include "PreferMemberInitializerCheck.h"
#include "ProBoundsArrayToPointerDecayCheck.h"
@@ -89,6 +90,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule {
CheckFactories.registerCheck(
"cppcoreguidelines-narrowing-conversions");
CheckFactories.registerCheck("cppcoreguidelines-no-malloc");
+ CheckFactories.registerCheck(
+ "cppcoreguidelines-no-suspend-with-lock");
CheckFactories.registerCheck(
"cppcoreguidelines-noexcept-destructor");
CheckFactories.registerCheck(
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
new file mode 100644
index 0000000000000..ca293178c78b4
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
@@ -0,0 +1,73 @@
+//===--- NoSuspendWithLockCheck.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 "NoSuspendWithLockCheck.h"
+#include "../utils/ExprSequence.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Analysis/CFG.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::cppcoreguidelines {
+
+void NoSuspendWithLockCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "LockGuards", LockGuards);
+}
+
+void NoSuspendWithLockCheck::registerMatchers(MatchFinder *Finder) {
+ auto LockType = elaboratedType(namesType(templateSpecializationType(
+ hasDeclaration(namedDecl(matchers::matchesAnyListedName(
+ utils::options::parseStringList(LockGuards)))))));
+
+ StatementMatcher Lock =
+ declStmt(has(varDecl(hasType(LockType)).bind("lock-decl")))
+ .bind("lock-decl-stmt");
+ Finder->addMatcher(
+ expr(anyOf(coawaitExpr(), coyieldExpr(), dependentCoawaitExpr()),
+ forCallable(functionDecl().bind("function")),
+ unless(isInTemplateInstantiation()),
+ hasAncestor(
+ compoundStmt(has(Lock), forCallable(equalsBoundNode("function")))
+ .bind("block")))
+ .bind("suspend"),
+ this);
+}
+
+void NoSuspendWithLockCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *Block = Result.Nodes.getNodeAs("block");
+ const auto *Suspend = Result.Nodes.getNodeAs("suspend");
+ const auto *LockDecl = Result.Nodes.getNodeAs("lock-decl");
+ const auto *LockStmt = Result.Nodes.getNodeAs("lock-decl-stmt");
+
+ if (!Block || !Suspend || !LockDecl || !LockStmt)
+ return;
+
+ ASTContext &Context = *Result.Context;
+ CFG::BuildOptions Options;
+ Options.AddImplicitDtors = true;
+ Options.AddTemporaryDtors = true;
+
+ std::unique_ptr TheCFG = CFG::buildCFG(
+ nullptr, const_cast(Block), &Context, Options);
+ if (!TheCFG)
+ return;
+
+ utils::ExprSequence Sequence(TheCFG.get(), Block, &Context);
+ const Stmt *LastBlockStmt = Block->body_back();
+ if (Sequence.inSequence(LockStmt, Suspend) &&
+ (Suspend == LastBlockStmt ||
+ Sequence.inSequence(Suspend, LastBlockStmt))) {
+ diag(Suspend->getBeginLoc(), "coroutine suspended with lock %0 held")
+ << LockDecl;
+ }
+}
+
+} // namespace clang::tidy::cppcoreguidelines
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.h
new file mode 100644
index 0000000000000..c7b7f476003fb
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.h
@@ -0,0 +1,44 @@
+//===--- NoSuspendWithLockCheck.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_CPPCOREGUIDELINES_NOSUSPENDWITHLOCKCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NOSUSPENDWITHLOCKCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::cppcoreguidelines {
+
+/// Flag coroutines that suspend while any lock guard is alive.
+/// This check implements CppCoreGuideline CP.52.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/no-suspend-with-lock.html
+class NoSuspendWithLockCheck : public ClangTidyCheck {
+public:
+ NoSuspendWithLockCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ LockGuards(Options.get("LockGuards",
+ "::std::unique_lock;::std::scoped_lock;::"
+ "std::shared_lock;::std::lock_guard")) {}
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus20;
+ }
+
+private:
+ /// Semicolon-separated list of fully qualified names of lock guard template
+ /// types. Defaults to
+ /// `::std::unique_lock;::std::scoped_lock;::std::shared_lock;::std::lock_guard`.
+ const StringRef LockGuards;
+};
+
+} // namespace clang::tidy::cppcoreguidelines
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NOSUSPENDWITHLOCKCHECK_H
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
index c210cb67e4f6b..6f67ab955baa3 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
@@ -10,6 +10,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
using namespace clang::ast_matchers;
@@ -56,6 +57,7 @@ void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) {
TK_AsIs,
implicitCastExpr(
unless(hasParent(arraySubscriptExpr())),
+ unless(hasSourceExpression(predefinedExpr())),
unless(hasParentIgnoringImpCasts(explicitCastExpr())),
unless(isInsideOfRangeBeginEndStmt()),
unless(hasSourceExpression(ignoringParens(stringLiteral()))),
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
index 07b88d5c49e80..ff5a750a8dac4 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
@@ -281,8 +281,14 @@ ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name,
void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) {
auto IsUserProvidedNonDelegatingConstructor =
- allOf(isUserProvided(),
- unless(anyOf(isInstantiated(), isDelegatingConstructor())));
+ allOf(isUserProvided(), unless(isInstantiated()),
+ unless(isDelegatingConstructor()),
+ ofClass(cxxRecordDecl().bind("parent")),
+ unless(hasAnyConstructorInitializer(cxxCtorInitializer(
+ isWritten(), unless(isMemberInitializer()),
+ hasTypeLoc(loc(
+ qualType(hasDeclaration(equalsBoundNode("parent")))))))));
+
auto IsNonTrivialDefaultConstructor = allOf(
isDefaultConstructor(), unless(isUserProvided()),
hasParent(cxxRecordDecl(unless(isTriviallyDefaultConstructible()))));
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
index ac1f40cfe18ae..3923df312791d 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "ProTypeVarargCheck.h"
+#include "../utils/Matchers.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -133,7 +134,9 @@ void ProTypeVarargCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(callee(functionDecl(isVariadic(),
- unless(hasAnyName(AllowedVariadics)))))
+ unless(hasAnyName(AllowedVariadics)))),
+ unless(hasAncestor(expr(matchers::hasUnevaluatedContext()))),
+ unless(hasAncestor(typeLoc())))
.bind("callvararg"),
this);
diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
index f47609b19badf..2658c4b38702c 100644
--- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp
@@ -87,7 +87,7 @@ void IncludeCleanerCheck::registerPPCallbacks(const SourceManager &SM,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
PP->addPPCallbacks(RecordedPreprocessor.record(*PP));
- HS = &PP->getHeaderSearchInfo();
+ this->PP = PP;
RecordedPI.record(*PP);
}
@@ -121,7 +121,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
// FIXME: Find a way to have less code duplication between include-cleaner
// analysis implementation and the below code.
walkUsed(MainFileDecls, RecordedPreprocessor.MacroReferences, &RecordedPI,
- *SM,
+ *PP,
[&](const include_cleaner::SymbolReference &Ref,
llvm::ArrayRef Providers) {
// Process each symbol once to reduce noise in the findings.
@@ -200,8 +200,8 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
tooling::HeaderIncludes HeaderIncludes(getCurrentMainFile(), Code,
FileStyle->IncludeStyle);
for (const auto &Inc : Missing) {
- std::string Spelling =
- include_cleaner::spellHeader({Inc.Missing, *HS, MainFile});
+ std::string Spelling = include_cleaner::spellHeader(
+ {Inc.Missing, PP->getHeaderSearchInfo(), MainFile});
bool Angled = llvm::StringRef{Spelling}.starts_with("<");
// We might suggest insertion of an existing include in edge cases, e.g.,
// include is present in a PP-disabled region, or spelling of the header
diff --git a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
index 9641c7fd9dfcf..b46e409bd6f6a 100644
--- a/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.h
@@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/Regex.h"
#include
@@ -42,7 +43,7 @@ class IncludeCleanerCheck : public ClangTidyCheck {
private:
include_cleaner::RecordedPP RecordedPreprocessor;
include_cleaner::PragmaIncludes RecordedPI;
- HeaderSearch *HS;
+ const Preprocessor *PP = nullptr;
std::vector IgnoreHeaders;
// Whether emit only one finding per usage of a symbol.
const bool DeduplicateFindings;
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index 4850440329bc1..92a541c9e59be 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -441,8 +441,6 @@ AST_MATCHER(Expr, isIntegerConstantExpr) {
return Node.isIntegerConstantExpr(Finder->getASTContext());
}
-AST_MATCHER(Expr, isRequiresExpr) { return isa(Node); }
-
AST_MATCHER(BinaryOperator, operandsAreEquivalent) {
return areEquivalentExpr(Node.getLHS(), Node.getRHS());
}
@@ -862,7 +860,8 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
const auto BannedIntegerLiteral =
integerLiteral(expandedByMacro(KnownBannedMacroNames));
- const auto BannedAncestor = expr(isRequiresExpr());
+ const auto IsInUnevaluatedContext = expr(anyOf(
+ hasAncestor(expr(hasUnevaluatedContext())), hasAncestor(typeLoc())));
// Binary with equivalent operands, like (X != 2 && X != 2).
Finder->addMatcher(
@@ -879,7 +878,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
unless(hasEitherOperand(hasType(realFloatingPointType()))),
unless(hasLHS(AnyLiteralExpr)),
unless(hasDescendant(BannedIntegerLiteral)),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("binary")),
this);
@@ -893,7 +892,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
unless(binaryOperatorIsInMacro()),
// TODO: if the banned macros are themselves duplicated
unless(hasDescendant(BannedIntegerLiteral)),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("nested-duplicates"),
this);
@@ -904,7 +903,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
// Filter noisy false positives.
unless(conditionalOperatorIsInMacro()),
unless(isInTemplateInstantiation()),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("cond")),
this);
@@ -918,7 +917,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
parametersAreEquivalent(),
// Filter noisy false positives.
unless(isMacro()), unless(isInTemplateInstantiation()),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("call")),
this);
@@ -929,7 +928,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
nestedParametersAreEquivalent(), argumentCountIs(2),
// Filter noisy false positives.
unless(isMacro()), unless(isInTemplateInstantiation()),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("nested-duplicates"),
this);
@@ -947,7 +946,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
integerLiteral())),
hasRHS(integerLiteral())))))
.bind("logical-bitwise-confusion")),
- unless(hasAncestor(BannedAncestor)))),
+ unless(IsInUnevaluatedContext))),
this);
// Match expressions like: (X << 8) & 0xFF
@@ -961,7 +960,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
integerLiteral().bind("shift-const"))))),
ignoringParenImpCasts(
integerLiteral().bind("and-const"))),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("left-right-shift-confusion")),
this);
@@ -980,7 +979,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
traverse(TK_AsIs, binaryOperator(isComparisonOperator(),
hasOperands(BinOpCstLeft, CstRight),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("binop-const-compare-to-const")),
this);
@@ -991,7 +990,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
binaryOperator(isComparisonOperator(),
anyOf(allOf(hasLHS(BinOpCstLeft), hasRHS(SymRight)),
allOf(hasLHS(SymRight), hasRHS(BinOpCstLeft))),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("binop-const-compare-to-sym")),
this);
@@ -1002,7 +1001,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
hasRHS(BinOpCstRight),
// Already reported as redundant.
unless(operandsAreEquivalent()),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("binop-const-compare-to-binop-const")),
this);
@@ -1019,7 +1018,7 @@ void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) {
hasLHS(ComparisonLeft), hasRHS(ComparisonRight),
// Already reported as redundant.
unless(operandsAreEquivalent()),
- unless(hasAncestor(BannedAncestor)))
+ unless(IsInUnevaluatedContext))
.bind("comparisons-of-symbol-and-const")),
this);
}
diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
index d932b5fb936cb..ca4f6ad409b08 100644
--- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
@@ -26,14 +26,20 @@ std::optional makeCharacterLiteral(const StringLiteral *Literal) {
Literal->outputString(OS);
}
// Now replace the " with '.
- auto Pos = Result.find_first_of('"');
- if (Pos == Result.npos)
+ auto OpenPos = Result.find_first_of('"');
+ if (OpenPos == Result.npos)
return std::nullopt;
- Result[Pos] = '\'';
- Pos = Result.find_last_of('"');
- if (Pos == Result.npos)
+ Result[OpenPos] = '\'';
+
+ auto ClosePos = Result.find_last_of('"');
+ if (ClosePos == Result.npos)
return std::nullopt;
- Result[Pos] = '\'';
+ Result[ClosePos] = '\'';
+
+ // "'" is OK, but ''' is not, so add a backslash
+ if ((ClosePos - OpenPos) == 2 && Result[OpenPos + 1] == '\'')
+ Result.replace(OpenPos + 1, 1, "\\'");
+
return Result;
}
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index 863ac4dbbf4c6..99b792b90a3ca 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -228,7 +228,8 @@ bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
if (!S)
return false;
if (isa(S) || isa(S) || isa(S) ||
- isa(S) || isa(S))
+ isa(S) || isa(S) ||
+ isa(S))
return true;
if (isa(S) || isa(S) ||
isUnaryLogicalNotOperator(S) ||
diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
index 619374cddbcf6..93c31d80c1138 100644
--- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
@@ -15,8 +15,12 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
+namespace {
+AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); }
+} // namespace
+
static unsigned getNameSpecifierNestingLevel(const QualType &QType) {
- if (const ElaboratedType *ElType = QType->getAs()) {
+ if (const auto *ElType = QType->getAs()) {
if (const NestedNameSpecifier *NestedSpecifiers = ElType->getQualifier()) {
unsigned NameSpecifierNestingLevel = 1;
do {
@@ -38,7 +42,7 @@ void StaticAccessedThroughInstanceCheck::storeOptions(
void StaticAccessedThroughInstanceCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStaticStorageClass()),
+ memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStatic()),
varDecl(hasStaticStorageDuration()),
enumConstantDecl())))
.bind("memberExpression"),
diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index e0c2d63d2024c..312d9241cfa57 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -389,6 +389,8 @@ def main():
clang_apply_replacements_binary = find_binary(
args.clang_apply_replacements_binary, "clang-apply-replacements", build_path
)
+
+ if args.fix or (yaml and args.export_fixes):
tmpdir = tempfile.mkdtemp()
try:
diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index 957a6f873e102..ef5d5db0577b0 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -237,14 +237,8 @@ void CommandMangler::operator()(tooling::CompileCommand &Command,
llvm::opt::InputArgList ArgList;
ArgList = OptTable.ParseArgs(
llvm::ArrayRef(OriginalArgs).drop_front(), IgnoredCount, IgnoredCount,
- /*FlagsToInclude=*/
- IsCLMode ? (driver::options::CLOption | driver::options::CoreOption |
- driver::options::CLDXCOption)
- : /*everything*/ 0,
- /*FlagsToExclude=*/driver::options::NoDriverOption |
- (IsCLMode
- ? 0
- : (driver::options::CLOption | driver::options::CLDXCOption)));
+ llvm::opt::Visibility(IsCLMode ? driver::options::CLOption
+ : driver::options::ClangOption));
llvm::SmallVector IndicesToDrop;
// Having multiple architecture options (e.g. when building fat binaries)
@@ -441,23 +435,13 @@ DriverMode getDriverMode(const std::vector &Args) {
// Returns the set of DriverModes where an option may be used.
unsigned char getModes(const llvm::opt::Option &Opt) {
- // Why is this so complicated?!
- // Reference is clang::driver::Driver::getIncludeExcludeOptionFlagMasks()
unsigned char Result = DM_None;
- if (Opt.hasFlag(driver::options::CC1Option))
+ if (Opt.hasVisibilityFlag(driver::options::ClangOption))
+ Result |= DM_GCC;
+ if (Opt.hasVisibilityFlag(driver::options::CC1Option))
Result |= DM_CC1;
- if (!Opt.hasFlag(driver::options::NoDriverOption)) {
- if (Opt.hasFlag(driver::options::CLOption)) {
- Result |= DM_CL;
- } else if (Opt.hasFlag(driver::options::CLDXCOption)) {
- Result |= DM_CL;
- } else {
- Result |= DM_GCC;
- if (Opt.hasFlag(driver::options::CoreOption)) {
- Result |= DM_CL;
- }
- }
- }
+ if (Opt.hasVisibilityFlag(driver::options::CLOption))
+ Result |= DM_CL;
return Result;
}
@@ -493,8 +477,8 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) {
static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \
static constexpr llvm::ArrayRef NAME( \
NAME##_init, std::size(NAME##_init) - 1);
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, METAVAR, VALUES) \
+#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
+ FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \
Prefixes[DriverID::OPT_##ID] = PREFIX;
#include "clang/Driver/Options.inc"
#undef OPTION
@@ -505,8 +489,8 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) {
DriverID AliasID;
const void *AliasArgs;
} AliasTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, METAVAR, VALUES) \
+#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \
+ FLAGS, VISIBILITY, PARAM, HELP, METAVAR, VALUES) \
{DriverID::OPT_##ID, DriverID::OPT_##ALIAS, ALIASARGS},
#include "clang/Driver/Options.inc"
#undef OPTION
diff --git a/clang-tools-extra/clangd/Headers.cpp b/clang-tools-extra/clangd/Headers.cpp
index 83fba21b1d931..6005069be0116 100644
--- a/clang-tools-extra/clangd/Headers.cpp
+++ b/clang-tools-extra/clangd/Headers.cpp
@@ -286,11 +286,11 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
assert(InsertedHeader.valid());
if (InsertedHeader.Verbatim)
return InsertedHeader.File;
- bool IsSystem = false;
+ bool IsAngled = false;
std::string Suggested;
if (HeaderSearchInfo) {
Suggested = HeaderSearchInfo->suggestPathToFileForDiagnostics(
- InsertedHeader.File, BuildDir, IncludingFile, &IsSystem);
+ InsertedHeader.File, BuildDir, IncludingFile, &IsAngled);
} else {
// Calculate include relative to including file only.
StringRef IncludingDir = llvm::sys::path::parent_path(IncludingFile);
@@ -303,7 +303,7 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
// FIXME: should we allow (some limited number of) "../header.h"?
if (llvm::sys::path::is_absolute(Suggested))
return std::nullopt;
- if (IsSystem)
+ if (IsAngled)
Suggested = "<" + Suggested + ">";
else
Suggested = "\"" + Suggested + "\"";
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index aaa160bb048ef..0ec85fc24df15 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1245,12 +1245,11 @@ std::string getSymbolName(include_cleaner::Symbol Sym) {
}
void maybeAddUsedSymbols(ParsedAST &AST, HoverInfo &HI, const Inclusion &Inc) {
- const SourceManager &SM = AST.getSourceManager();
auto Converted = convertIncludes(AST);
llvm::DenseSet UsedSymbols;
include_cleaner::walkUsed(
AST.getLocalTopLevelDecls(), collectMacroReferences(AST),
- AST.getPragmaIncludes().get(), SM,
+ AST.getPragmaIncludes().get(), AST.getPreprocessor(),
[&](const include_cleaner::SymbolReference &Ref,
llvm::ArrayRef Providers) {
if (Ref.RT != include_cleaner::RefType::Explicit ||
diff --git a/clang-tools-extra/clangd/IncludeCleaner.cpp b/clang-tools-extra/clangd/IncludeCleaner.cpp
index 07c6937ac10d5..1fcb5c7228fb6 100644
--- a/clang-tools-extra/clangd/IncludeCleaner.cpp
+++ b/clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -394,7 +394,7 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST) {
trace::Span Tracer("include_cleaner::walkUsed");
include_cleaner::walkUsed(
AST.getLocalTopLevelDecls(), /*MacroRefs=*/Macros,
- AST.getPragmaIncludes().get(), SM,
+ AST.getPragmaIncludes().get(), AST.getPreprocessor(),
[&](const include_cleaner::SymbolReference &Ref,
llvm::ArrayRef Providers) {
bool Satisfied = false;
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 1962aa51aef41..56f85ee155cb2 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -273,7 +273,7 @@ std::string summarizeExpr(const Expr *E) {
return getSimpleName(E->getMember()).str();
}
std::string
- VisitDependentScopeMemberExpr(const DependentScopeDeclRefExpr *E) {
+ VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
return getSimpleName(E->getDeclName()).str();
}
std::string VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) {
@@ -485,6 +485,56 @@ QualType maybeDesugar(ASTContext &AST, QualType QT) {
return QT;
}
+// Given a callee expression `Fn`, if the call is through a function pointer,
+// try to find the declaration of the corresponding function pointer type,
+// so that we can recover argument names from it.
+// FIXME: This function is mostly duplicated in SemaCodeComplete.cpp; unify.
+static FunctionProtoTypeLoc getPrototypeLoc(Expr *Fn) {
+ TypeLoc Target;
+ Expr *NakedFn = Fn->IgnoreParenCasts();
+ if (const auto *T = NakedFn->getType().getTypePtr()->getAs()) {
+ Target = T->getDecl()->getTypeSourceInfo()->getTypeLoc();
+ } else if (const auto *DR = dyn_cast(NakedFn)) {
+ const auto *D = DR->getDecl();
+ if (const auto *const VD = dyn_cast(D)) {
+ Target = VD->getTypeSourceInfo()->getTypeLoc();
+ }
+ }
+
+ if (!Target)
+ return {};
+
+ // Unwrap types that may be wrapping the function type
+ while (true) {
+ if (auto P = Target.getAs()) {
+ Target = P.getPointeeLoc();
+ continue;
+ }
+ if (auto A = Target.getAs()) {
+ Target = A.getModifiedLoc();
+ continue;
+ }
+ if (auto P = Target.getAs()) {
+ Target = P.getInnerLoc();
+ continue;
+ }
+ break;
+ }
+
+ if (auto F = Target.getAs()) {
+ return F;
+ }
+
+ return {};
+}
+
+struct Callee {
+ // Only one of Decl or Loc is set.
+ // Loc is for calls through function pointers.
+ const FunctionDecl *Decl = nullptr;
+ FunctionProtoTypeLoc Loc;
+};
+
class InlayHintVisitor : public RecursiveASTVisitor {
public:
InlayHintVisitor(std::vector &Results, ParsedAST &AST,
@@ -524,7 +574,11 @@ class InlayHintVisitor : public RecursiveASTVisitor {
return true;
}
- processCall(E->getConstructor(), {E->getArgs(), E->getNumArgs()});
+ Callee Callee;
+ Callee.Decl = E->getConstructor();
+ if (!Callee.Decl)
+ return true;
+ processCall(Callee, {E->getArgs(), E->getNumArgs()});
return true;
}
@@ -534,7 +588,7 @@ class InlayHintVisitor : public RecursiveASTVisitor {
// Do not show parameter hints for operator calls written using operator
// syntax or user-defined literals. (Among other reasons, the resulting
- // hints can look awkard, e.g. the expression can itself be a function
+ // hints can look awkward, e.g. the expression can itself be a function
// argument and then we'd get two hints side by side).
if (isa(E) || isa(E))
return true;
@@ -542,12 +596,15 @@ class InlayHintVisitor : public RecursiveASTVisitor {
auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E);
if (CalleeDecls.size() != 1)
return true;
- const FunctionDecl *Callee = nullptr;
+
+ Callee Callee;
if (const auto *FD = dyn_cast(CalleeDecls[0]))
- Callee = FD;
+ Callee.Decl = FD;
else if (const auto *FTD = dyn_cast(CalleeDecls[0]))
- Callee = FTD->getTemplatedDecl();
- if (!Callee)
+ Callee.Decl = FTD->getTemplatedDecl();
+ else if (FunctionProtoTypeLoc Loc = getPrototypeLoc(E->getCallee()))
+ Callee.Loc = Loc;
+ else
return true;
processCall(Callee, {E->getArgs(), E->getNumArgs()});
@@ -676,7 +733,8 @@ class InlayHintVisitor : public RecursiveASTVisitor {
// For structured bindings, print canonical types. This is important
// because for bindings that use the tuple_element protocol, the
// non-canonical types would be "tuple_element::type".
- if (auto Type = Binding->getType(); !Type.isNull())
+ if (auto Type = Binding->getType();
+ !Type.isNull() && !Type->isDependentType())
addTypeHint(Binding->getLocation(), Type.getCanonicalType(),
/*Prefix=*/": ");
}
@@ -762,25 +820,35 @@ class InlayHintVisitor : public RecursiveASTVisitor {
private:
using NameVec = SmallVector;
- void processCall(const FunctionDecl *Callee,
- llvm::ArrayRef Args) {
- if (!Cfg.InlayHints.Parameters || Args.size() == 0 || !Callee)
+ void processCall(Callee Callee, llvm::ArrayRef Args) {
+ assert(Callee.Decl || Callee.Loc);
+
+ if (!Cfg.InlayHints.Parameters || Args.size() == 0)
return;
// The parameter name of a move or copy constructor is not very interesting.
- if (auto *Ctor = dyn_cast(Callee))
- if (Ctor->isCopyOrMoveConstructor())
- return;
+ if (Callee.Decl)
+ if (auto *Ctor = dyn_cast(Callee.Decl))
+ if (Ctor->isCopyOrMoveConstructor())
+ return;
+
+ auto Params =
+ Callee.Decl ? Callee.Decl->parameters() : Callee.Loc.getParams();
// Resolve parameter packs to their forwarded parameter
- auto ForwardedParams = resolveForwardingParameters(Callee);
+ SmallVector ForwardedParams;
+ if (Callee.Decl)
+ ForwardedParams = resolveForwardingParameters(Callee.Decl);
+ else
+ ForwardedParams = {Params.begin(), Params.end()};
NameVec ParameterNames = chooseParameterNames(ForwardedParams);
// Exclude setters (i.e. functions with one argument whose name begins with
// "set"), and builtins like std::move/forward/... as their parameter name
// is also not likely to be interesting.
- if (isSetter(Callee, ParameterNames) || isSimpleBuiltin(Callee))
+ if (Callee.Decl &&
+ (isSetter(Callee.Decl, ParameterNames) || isSimpleBuiltin(Callee.Decl)))
return;
for (size_t I = 0; I < ParameterNames.size() && I < Args.size(); ++I) {
@@ -793,8 +861,7 @@ class InlayHintVisitor : public RecursiveASTVisitor {
StringRef Name = ParameterNames[I];
bool NameHint = shouldHintName(Args[I], Name);
- bool ReferenceHint =
- shouldHintReference(Callee->getParamDecl(I), ForwardedParams[I]);
+ bool ReferenceHint = shouldHintReference(Params[I], ForwardedParams[I]);
if (NameHint || ReferenceHint) {
addInlayHint(Args[I]->getSourceRange(), HintSide::Left,
diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp
index 81cfe8bb60b3e..3cf6671be9600 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -396,6 +396,15 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
assert(CI);
+
+ if (CI->getFrontendOpts().Inputs.size() > 0) {
+ auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
+ if (Lang == Language::Asm || Lang == Language::LLVM_IR) {
+ elog("Clangd does not support assembly or IR source files");
+ return std::nullopt;
+ }
+ }
+
// Command-line parsing sets DisableFree to true by default, but we don't want
// to leak memory in clangd.
CI->getFrontendOpts().DisableFree = false;
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 23a48e0a8e5f6..e88c804692568 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -592,7 +592,7 @@ bool fromJSON(const llvm::json::Value &, ConfigurationSettings &,
/// Clangd extension: parameters configurable at `initialize` time.
/// LSP defines this type as `any`.
struct InitializationOptions {
- // What we can change throught the didChangeConfiguration request, we can
+ // What we can change through the didChangeConfiguration request, we can
// also set through the initialize request (initializationOptions field).
ConfigurationSettings ConfigSettings;
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index 6cce28f53b577..ac99b220f6bd3 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -133,6 +133,16 @@ struct DriverArgs {
}
}
+ // Downgrade objective-c++-header (used in clangd's fallback flags for .h
+ // files) to c++-header, as some drivers may fail to run the extraction
+ // command if it contains `-xobjective-c++-header` and objective-c++ support
+ // is not installed.
+ // In practice, we don't see different include paths for the two on
+ // clang+mac, which is the most common objectve-c compiler.
+ if (Lang == "objective-c++-header") {
+ Lang = "c++-header";
+ }
+
// If language is not explicit in the flags, infer from the file.
// This is important as we want to cache each language separately.
if (Lang.empty()) {
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index bcbd214a725ce..9beb3f1417b9a 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1339,7 +1339,7 @@ maybeFindIncludeReferences(ParsedAST &AST, Position Pos,
auto Converted = convertIncludes(AST);
include_cleaner::walkUsed(
AST.getLocalTopLevelDecls(), collectMacroReferences(AST),
- AST.getPragmaIncludes().get(), SM,
+ AST.getPragmaIncludes().get(), AST.getPreprocessor(),
[&](const include_cleaner::SymbolReference &Ref,
llvm::ArrayRef Providers) {
if (Ref.RT != include_cleaner::RefType::Explicit ||
diff --git a/clang-tools-extra/clangd/index/StdLib.cpp b/clang-tools-extra/clangd/index/StdLib.cpp
index d9aa46d6b75b1..477a5d1ebe523 100644
--- a/clang-tools-extra/clangd/index/StdLib.cpp
+++ b/clang-tools-extra/clangd/index/StdLib.cpp
@@ -59,8 +59,8 @@ LangStandard::Kind standardFromOpts(const LangOptions &LO) {
return LangStandard::lang_cxx11;
return LangStandard::lang_cxx98;
}
- if (LO.C2x)
- return LangStandard::lang_c2x;
+ if (LO.C23)
+ return LangStandard::lang_c23;
// C17 has no new features, so treat {C11,C17} as C17.
if (LO.C11)
return LangStandard::lang_c17;
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index c9a211b9c4fc2..e843413601f5a 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -328,42 +328,33 @@ class SymbolCollector::HeaderFileURICache {
// instead of
// which should be used instead of directly
// importing the header.
- std::optional getFrameworkUmbrellaSpelling(
- llvm::StringRef Framework, SrcMgr::CharacteristicKind HeadersDirKind,
- const HeaderSearch &HS, FrameworkHeaderPath &HeaderPath) {
+ std::optional
+ getFrameworkUmbrellaSpelling(llvm::StringRef Framework,
+ const HeaderSearch &HS,
+ FrameworkHeaderPath &HeaderPath) {
auto Res = CacheFrameworkToUmbrellaHeaderSpelling.try_emplace(Framework);
auto *CachedSpelling = &Res.first->second;
if (!Res.second) {
return HeaderPath.IsPrivateHeader ? CachedSpelling->PrivateHeader
: CachedSpelling->PublicHeader;
}
- bool IsSystem = isSystem(HeadersDirKind);
SmallString<256> UmbrellaPath(HeaderPath.HeadersParentDir);
llvm::sys::path::append(UmbrellaPath, "Headers", Framework + ".h");
llvm::vfs::Status Status;
auto StatErr = HS.getFileMgr().getNoncachedStatValue(UmbrellaPath, Status);
- if (!StatErr) {
- if (IsSystem)
- CachedSpelling->PublicHeader = llvm::formatv("<{0}/{0}.h>", Framework);
- else
- CachedSpelling->PublicHeader =
- llvm::formatv("\"{0}/{0}.h\"", Framework);
- }
+ if (!StatErr)
+ CachedSpelling->PublicHeader = llvm::formatv("<{0}/{0}.h>", Framework);
UmbrellaPath = HeaderPath.HeadersParentDir;
llvm::sys::path::append(UmbrellaPath, "PrivateHeaders",
Framework + "_Private.h");
StatErr = HS.getFileMgr().getNoncachedStatValue(UmbrellaPath, Status);
- if (!StatErr) {
- if (IsSystem)
- CachedSpelling->PrivateHeader =
- llvm::formatv("<{0}/{0}_Private.h>", Framework);
- else
- CachedSpelling->PrivateHeader =
- llvm::formatv("\"{0}/{0}_Private.h\"", Framework);
- }
+ if (!StatErr)
+ CachedSpelling->PrivateHeader =
+ llvm::formatv("<{0}/{0}_Private.h>", Framework);
+
return HeaderPath.IsPrivateHeader ? CachedSpelling->PrivateHeader
: CachedSpelling->PublicHeader;
}
@@ -386,21 +377,14 @@ class SymbolCollector::HeaderFileURICache {
CachePathToFrameworkSpelling.erase(Res.first);
return std::nullopt;
}
- auto DirKind = HS.getFileDirFlavor(FE);
if (auto UmbrellaSpelling =
- getFrameworkUmbrellaSpelling(Framework, DirKind, HS, *HeaderPath)) {
+ getFrameworkUmbrellaSpelling(Framework, HS, *HeaderPath)) {
*CachedHeaderSpelling = *UmbrellaSpelling;
return llvm::StringRef(*CachedHeaderSpelling);
}
- if (isSystem(DirKind))
- *CachedHeaderSpelling =
- llvm::formatv("<{0}/{1}>", Framework, HeaderPath->HeaderSubpath)
- .str();
- else
- *CachedHeaderSpelling =
- llvm::formatv("\"{0}/{1}\"", Framework, HeaderPath->HeaderSubpath)
- .str();
+ *CachedHeaderSpelling =
+ llvm::formatv("<{0}/{1}>", Framework, HeaderPath->HeaderSubpath).str();
return llvm::StringRef(*CachedHeaderSpelling);
}
diff --git a/clang-tools-extra/clangd/index/SymbolLocation.h b/clang-tools-extra/clangd/index/SymbolLocation.h
index eadf211bb3bf6..ea7d605172e47 100644
--- a/clang-tools-extra/clangd/index/SymbolLocation.h
+++ b/clang-tools-extra/clangd/index/SymbolLocation.h
@@ -30,7 +30,7 @@ struct SymbolLocation {
// Position is encoded into 32 bits to save space.
// If Line/Column overflow, the value will be their maximum value.
struct Position {
- Position() : LineColumnPacked(0) {}
+ Position() = default;
void setLine(uint32_t Line);
uint32_t line() const { return LineColumnPacked >> ColumnBits; }
void setColumn(uint32_t Column);
@@ -46,7 +46,7 @@ struct SymbolLocation {
static constexpr uint32_t MaxColumn = (1 << ColumnBits) - 1;
private:
- uint32_t LineColumnPacked; // Top 20 bit line, bottom 12 bits column.
+ uint32_t LineColumnPacked = 0; // Top 20 bit line, bottom 12 bits column.
};
/// The symbol range, using half-open range [Start, End).
diff --git a/clang-tools-extra/clangd/tool/CMakeLists.txt b/clang-tools-extra/clangd/tool/CMakeLists.txt
index 5c3b566c97364..6c21175d7687c 100644
--- a/clang-tools-extra/clangd/tool/CMakeLists.txt
+++ b/clang-tools-extra/clangd/tool/CMakeLists.txt
@@ -26,11 +26,7 @@ clang_target_link_libraries(clangdMain
clangBasic
clangFormat
clangFrontend
- clangLex
- clangSema
clangTooling
- clangToolingCore
- clangToolingRefactoring
clangToolingSyntax
)
@@ -48,11 +44,8 @@ clang_target_link_libraries(clangd
PRIVATE
clangAST
clangBasic
- clangFormat
- clangFrontend
clangLex
clangSema
- clangTooling
clangToolingCore
clangToolingRefactoring
clangToolingSyntax
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index dd6ee44224471..671c0b7da97c6 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1397,20 +1397,37 @@ TEST(SignatureHelpTest, Overloads) {
}
TEST(SignatureHelpTest, FunctionPointers) {
- auto FunctionPointerResults = signatures(R"cpp(
+ llvm::StringLiteral Tests[] = {
+ // Variable of function pointer type
+ R"cpp(
void (*foo)(int x, int y);
int main() { foo(^); }
- )cpp");
- EXPECT_THAT(FunctionPointerResults.signatures,
- UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
-
- auto FunctionPointerTypedefResults = signatures(R"cpp(
+ )cpp",
+ // Wrapped in an AttributedType
+ R"cpp(
+ void (__stdcall *foo)(int x, int y);
+ int main() { foo(^); }
+ )cpp",
+ // Another syntax for an AttributedType
+ R"cpp(
+ void (__attribute__(stdcall) *foo)(int x, int y);
+ int main() { foo(^); },
+ )cpp",
+ // Wrapped in a typedef
+ R"cpp(
typedef void (*fn)(int x, int y);
fn foo;
int main() { foo(^); }
- )cpp");
- EXPECT_THAT(FunctionPointerTypedefResults.signatures,
- UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
+ )cpp",
+ // Wrapped in both a typedef and an AttributedTyped
+ R"cpp(
+ typedef void (__stdcall *fn)(int x, int y);
+ fn foo;
+ int main() { foo(^); }
+ )cpp"};
+ for (auto Test : Tests)
+ EXPECT_THAT(signatures(Test).signatures,
+ UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
}
TEST(SignatureHelpTest, Constructors) {
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 2ad7f0ee55d72..9cab9a086958d 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2543,6 +2543,19 @@ TEST(Hover, All) {
HI.Type = "Test &&";
HI.Definition = "Test &&test = {}";
}},
+ {
+ R"cpp(// Shouldn't crash when evaluating the initializer.
+ struct Bar {}; // error-ok
+ struct Foo { void foo(Bar x = y); }
+ void Foo::foo(Bar [[^x]]) {})cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "x";
+ HI.Kind = index::SymbolKind::Parameter;
+ HI.NamespaceScope = "";
+ HI.LocalScope = "Foo::foo::";
+ HI.Type = "Bar";
+ HI.Definition = "Bar x = ()";
+ }},
{
R"cpp(// auto on alias
typedef int int_type;
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index d38b875994e63..1d12db3661c9e 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -919,6 +919,26 @@ TEST(ParameterHints, ImplicitConstructor) {
)cpp");
}
+TEST(ParameterHints, FunctionPointer) {
+ assertParameterHints(
+ R"cpp(
+ void (*f1)(int param);
+ void (__stdcall *f2)(int param);
+ using f3_t = void(*)(int param);
+ f3_t f3;
+ using f4_t = void(__stdcall *)(int param);
+ f4_t f4;
+ void bar() {
+ f1($f1[[42]]);
+ f2($f2[[42]]);
+ f3($f3[[42]]);
+ f4($f4[[42]]);
+ }
+ )cpp",
+ ExpectedHint{"param: ", "f1"}, ExpectedHint{"param: ", "f2"},
+ ExpectedHint{"param: ", "f3"}, ExpectedHint{"param: ", "f4"});
+}
+
TEST(ParameterHints, ArgMatchesParam) {
assertParameterHints(R"cpp(
void foo(int param);
@@ -1333,6 +1353,11 @@ TEST(TypeHints, DependentType) {
// FIXME: It would be nice to show "T" as the hint.
auto $var2[[var2]] = arg;
}
+
+ template
+ void bar(T arg) {
+ auto [a, b] = arg;
+ }
)cpp");
}
diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
index b0d5bea1d3279..ec8132645f81f 100644
--- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp
@@ -13,6 +13,7 @@
#include "../../clang-tidy/ClangTidyCheck.h"
#include "AST.h"
+#include "CompileCommands.h"
#include "Compiler.h"
#include "Config.h"
#include "Diagnostics.h"
@@ -731,6 +732,37 @@ TEST(ParsedASTTest, DiscoversPragmaMarks) {
pragmaTrivia(" End")));
}
+TEST(ParsedASTTest, GracefulFailureOnAssemblyFile) {
+ std::string Filename = "TestTU.S";
+ std::string Code = R"S(
+main:
+ # test comment
+ bx lr
+ )S";
+
+ // The rest is a simplified version of TestTU::build().
+ // Don't call TestTU::build() itself because it would assert on
+ // failure to build an AST.
+ MockFS FS;
+ std::string FullFilename = testPath(Filename);
+ FS.Files[FullFilename] = Code;
+ ParseInputs Inputs;
+ auto &Argv = Inputs.CompileCommand.CommandLine;
+ Argv = {"clang"};
+ Argv.push_back(FullFilename);
+ Inputs.CompileCommand.Filename = FullFilename;
+ Inputs.CompileCommand.Directory = testRoot();
+ Inputs.Contents = Code;
+ Inputs.TFS = &FS;
+ StoreDiags Diags;
+ auto CI = buildCompilerInvocation(Inputs, Diags);
+ assert(CI && "Failed to build compilation invocation.");
+ auto AST = ParsedAST::build(FullFilename, Inputs, std::move(CI), {}, nullptr);
+
+ EXPECT_FALSE(AST.has_value())
+ << "Should not try to build AST for assembly source file";
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
index 338cada5c03cb..58b9c85801051 100644
--- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -702,9 +702,9 @@ TEST_F(SymbolCollectorTest, ObjCFrameworkIncludeHeader) {
EXPECT_THAT(
Symbols,
UnorderedElementsAre(
- AllOf(qName("NSObject"), includeHeader("\"Foundation/NSObject.h\"")),
+ AllOf(qName("NSObject"), includeHeader("")),
AllOf(qName("PrivateClass"),
- includeHeader("\"Foundation/NSObject+Private.h\"")),
+ includeHeader("")),
AllOf(qName("Container"))));
// After adding the umbrella headers, we should use that spelling instead.
@@ -722,13 +722,13 @@ TEST_F(SymbolCollectorTest, ObjCFrameworkIncludeHeader) {
"Foundation_Private.h"),
0, llvm::MemoryBuffer::getMemBuffer(PrivateUmbrellaHeader));
runSymbolCollector(Header, Main, {"-F", FrameworksPath, "-xobjective-c++"});
- EXPECT_THAT(Symbols,
- UnorderedElementsAre(
- AllOf(qName("NSObject"),
- includeHeader("\"Foundation/Foundation.h\"")),
- AllOf(qName("PrivateClass"),
- includeHeader("\"Foundation/Foundation_Private.h\"")),
- AllOf(qName("Container"))));
+ EXPECT_THAT(
+ Symbols,
+ UnorderedElementsAre(
+ AllOf(qName("NSObject"), includeHeader("")),
+ AllOf(qName("PrivateClass"),
+ includeHeader("")),
+ AllOf(qName("Container"))));
runSymbolCollector(Header, Main,
{"-iframework", FrameworksPath, "-xobjective-c++"});
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index dbd2fbf6de6d4..5cf09bd26fab8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -136,6 +136,12 @@ New checks
extracted from an optional-like type and then used to create a new instance
of the same optional-like type.
+- New :doc:`cppcoreguidelines-no-suspend-with-lock
+ ` check.
+
+ Flags coroutines that suspend while a lock guard is in scope at the
+ suspension point.
+
- New :doc:`modernize-use-constraints
` check.
@@ -167,6 +173,10 @@ Changes in existing checks
`, so that it does not warn
on macros starting with underscore and lowercase letter.
+- Improved :doc:`bugprone-lambda-function-name
+ ` check by adding option
+ `IgnoreMacros` to ignore warnings in macros.
+
- Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables
` check
to ignore ``static`` variables declared within the scope of
@@ -176,18 +186,38 @@ Changes in existing checks
` check to
ignore delegate constructors.
+- Improved :doc `cppcoreguidelines-pro-bounds-array-to-pointer-decay
+ ` check
+ to ignore predefined expression (e.g., ``__func__``, ...).
+
+- Improved :doc:`cppcoreguidelines-pro-type-member-init
+ ` check to ignore
+ dependent delegate constructors.
+
+- Improved :doc:`cppcoreguidelines-pro-type-vararg
+ ` check to ignore
+ false-positives in unevaluated context (e.g., ``decltype``, ``sizeof``, ...).
+
- Improved :doc:`llvm-namespace-comment
` check to provide fixes for
``inline`` namespaces in the same format as :program:`clang-format`.
- Improved :doc:`misc-include-cleaner
` check by adding option
- `DeduplicateFindings` to output one finding per symbol occurence.
+ `DeduplicateFindings` to output one finding per symbol occurrence.
+
+- Improved :doc:`misc-redundant-expression
+ ` check to ignore
+ false-positives in unevaluated context (e.g., ``decltype``).
- Improved :doc:`modernize-loop-convert
` to support for-loops with
iterators initialized by free functions like ``begin``, ``end``, or ``size``.
+- Improved :doc:`performance-faster-string-find
+ ` check to properly escape
+ single quotes.
+
- Improved :doc:`performanc-noexcept-swap
` check to enforce a stricter
match with the swap function signature, eliminating false-positives.
@@ -196,6 +226,15 @@ Changes in existing checks
` check to emit proper
warnings when a type forward declaration precedes its definition.
+- Improved :doc:`readability-implicit-bool-conversion
+ ` check to take
+ do-while loops into account for the `AllowIntegerConditions` and
+ `AllowPointerConditions` options.
+
+- Improved :doc:`readability-static-accessed-through-instance
+ ` check to
+ identify calls to static member functions with out-of-class inline definitions.
+
Removed checks
^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst
index 6f0ba836fdf5c..e9cbf2b46b2bc 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst
@@ -25,3 +25,11 @@ Likely intended output::
Called from FancyFunction
Now called from FancyFunction
+
+Options
+-------
+
+.. option:: IgnoreMacros
+
+ The value `true` specifies that attempting to get the name of a function from
+ within a macro should not be diagnosed. The default value is `false`.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.CallAndMessage.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.CallAndMessage.rst
index 69d1e6e5a5d4a..cb8a21dc688c7 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.CallAndMessage.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.CallAndMessage.rst
@@ -5,6 +5,10 @@
clang-analyzer-core.CallAndMessage
==================================
+Check for logical errors for function calls and Objective-C message expressions
+(e.g., uninitialized arguments, null function pointers).
+
The clang-analyzer-core.CallAndMessage check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DivideZero.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DivideZero.rst
index f3c652f88b6f8..2128501702515 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DivideZero.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DivideZero.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.DivideZero
==============================
+Check for division by zero.
+
The clang-analyzer-core.DivideZero check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DynamicTypePropagation.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DynamicTypePropagation.rst
deleted file mode 100644
index e4f8eeaaab9d0..0000000000000
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.DynamicTypePropagation.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-.. title:: clang-tidy - clang-analyzer-core.DynamicTypePropagation
-
-clang-analyzer-core.DynamicTypePropagation
-==========================================
-
-Generate dynamic type information
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NonNullParamChecker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NonNullParamChecker.rst
index 3188c29e5c285..c103b99da3eba 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NonNullParamChecker.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NonNullParamChecker.rst
@@ -5,6 +5,10 @@
clang-analyzer-core.NonNullParamChecker
=======================================
+Check for null pointers passed as arguments to a function whose arguments are
+references or marked with the 'nonnull' attribute.
+
The clang-analyzer-core.NonNullParamChecker check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NullDereference.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NullDereference.rst
index f771c9e280369..c225fa5ee9526 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NullDereference.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.NullDereference.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.NullDereference
===================================
+Check for dereferences of null pointers.
+
The clang-analyzer-core.NullDereference check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.StackAddressEscape.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.StackAddressEscape.rst
index a3fb1111556b2..1efe0a4b26b2e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.StackAddressEscape.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.StackAddressEscape.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.StackAddressEscape
======================================
+Check that addresses to stack memory do not escape the function.
+
The clang-analyzer-core.StackAddressEscape check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.UndefinedBinaryOperatorResult.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.UndefinedBinaryOperatorResult.rst
index 1e36f6bbab233..29f9d695b5f83 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.UndefinedBinaryOperatorResult.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.UndefinedBinaryOperatorResult.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.UndefinedBinaryOperatorResult
=================================================
+Check for undefined results of binary operators.
+
The clang-analyzer-core.UndefinedBinaryOperatorResult check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.VLASize.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.VLASize.rst
index 80e6ba5f33572..600392b564732 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.VLASize.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.VLASize.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.VLASize
===========================
+Check for declarations of VLA of undefined or zero size.
+
The clang-analyzer-core.VLASize check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.ArraySubscript.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.ArraySubscript.rst
index 5da6a33c3605f..ebb4c74249ca9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.ArraySubscript.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.ArraySubscript.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.uninitialized.ArraySubscript
================================================
+Check for uninitialized values used as array subscripts.
+
The clang-analyzer-core.uninitialized.ArraySubscript check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Assign.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Assign.rst
index 8cc982b6fee3c..eb53d0ecbd29b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Assign.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Assign.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.uninitialized.Assign
========================================
+Check for assigning uninitialized values.
+
The clang-analyzer-core.uninitialized.Assign check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Branch.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Branch.rst
index e0fcd7bcc76a9..330d8507e66a9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Branch.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.Branch.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.uninitialized.Branch
========================================
+Check for uninitialized values used as branch conditions.
+
The clang-analyzer-core.uninitialized.Branch check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.CapturedBlockVariable.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.CapturedBlockVariable.rst
index 396ce2656cbc8..ffe7a940096a7 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.CapturedBlockVariable.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.CapturedBlockVariable.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-core.uninitialized.CapturedBlockVariable
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#core-uninitialized-capturedblockvariable
clang-analyzer-core.uninitialized.CapturedBlockVariable
=======================================================
-Check for blocks that capture uninitialized values
+Check for blocks that capture uninitialized values.
+
+The clang-analyzer-core.uninitialized.CapturedBlockVariable check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.NewArraySize.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.NewArraySize.rst
new file mode 100644
index 0000000000000..79a5c0abebf8f
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.NewArraySize.rst
@@ -0,0 +1,13 @@
+.. title:: clang-tidy - clang-analyzer-core.uninitialized.NewArraySize
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#core-uninitialized-newarraysize
+
+clang-analyzer-core.uninitialized.NewArraySize
+==============================================
+
+Check if the size of the array in a new[] expression is undefined.
+
+The clang-analyzer-core.uninitialized.NewArraySize check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.UndefReturn.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.UndefReturn.rst
index 057567429d25a..4039cd0f9a112 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.UndefReturn.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/core.uninitialized.UndefReturn.rst
@@ -5,6 +5,9 @@
clang-analyzer-core.uninitialized.UndefReturn
=============================================
+Check for uninitialized values being returned to the caller.
+
The clang-analyzer-core.uninitialized.UndefReturn check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.InnerPointer.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.InnerPointer.rst
index 660284b61de67..bc7d8a7d27660 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.InnerPointer.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.InnerPointer.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-cplusplus.InnerPointer
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-innerpointer
clang-analyzer-cplusplus.InnerPointer
=====================================
-Check for inner pointers of C++ containers used after re/deallocation
+Check for inner pointers of C++ containers used after re/deallocation.
+
+The clang-analyzer-cplusplus.InnerPointer check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst
index b0d663d558b3a..e723f21f6bc60 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.Move.rst
@@ -1,10 +1,9 @@
.. title:: clang-tidy - clang-analyzer-cplusplus.Move
-.. meta::
- :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-move
clang-analyzer-cplusplus.Move
=============================
-The clang-analyzer-cplusplus.Move check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
-for more information.
+Find use-after-move bugs in C++.
+
+The clang-analyzer-cplusplus.Move check is an alias of
+Clang Static Analyzer cplusplus.Move.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDelete.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDelete.rst
index 57964a8c93925..620f1e88da181 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDelete.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDelete.rst
@@ -5,6 +5,10 @@
clang-analyzer-cplusplus.NewDelete
==================================
+Check for double-free and use-after-free problems. Traces memory managed by
+new/delete.
+
The clang-analyzer-cplusplus.NewDelete check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDeleteLeaks.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDeleteLeaks.rst
index 4601a460df168..1f85373511d37 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDeleteLeaks.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.NewDeleteLeaks.rst
@@ -5,6 +5,9 @@
clang-analyzer-cplusplus.NewDeleteLeaks
=======================================
+Check for memory leaks. Traces memory managed by new/delete.
+
The clang-analyzer-cplusplus.NewDeleteLeaks check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PlacementNew.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PlacementNew.rst
new file mode 100644
index 0000000000000..c5d19a7deeb2e
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PlacementNew.rst
@@ -0,0 +1,14 @@
+.. title:: clang-tidy - clang-analyzer-cplusplus.PlacementNew
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-placementnew
+
+clang-analyzer-cplusplus.PlacementNew
+=====================================
+
+Check if default placement new is provided with pointers to sufficient storage
+capacity.
+
+The clang-analyzer-cplusplus.PlacementNew check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst
new file mode 100644
index 0000000000000..9fab628b80d44
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst
@@ -0,0 +1,9 @@
+.. title:: clang-tidy - clang-analyzer-cplusplus.PureVirtualCall
+
+clang-analyzer-cplusplus.PureVirtualCall
+========================================
+
+Check pure virtual function calls during construction/destruction.
+
+The clang-analyzer-cplusplus.PureVirtualCall check is an alias of
+Clang Static Analyzer cplusplus.PureVirtualCall.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.StringChecker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.StringChecker.rst
new file mode 100644
index 0000000000000..e3d4a511a61a7
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.StringChecker.rst
@@ -0,0 +1,13 @@
+.. title:: clang-tidy - clang-analyzer-cplusplus.StringChecker
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-stringchecker
+
+clang-analyzer-cplusplus.StringChecker
+======================================
+
+Checks C++ std::string bugs.
+
+The clang-analyzer-cplusplus.StringChecker check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/deadcode.DeadStores.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/deadcode.DeadStores.rst
index 0bb41212f4d20..b421e2cbd3c69 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/deadcode.DeadStores.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/deadcode.DeadStores.rst
@@ -5,6 +5,9 @@
clang-analyzer-deadcode.DeadStores
==================================
+Check for values stored to variables that are never read afterwards.
+
The clang-analyzer-deadcode.DeadStores check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/fuchsia.HandleChecker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/fuchsia.HandleChecker.rst
new file mode 100644
index 0000000000000..5f2a3aaae1ed1
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/fuchsia.HandleChecker.rst
@@ -0,0 +1,13 @@
+.. title:: clang-tidy - clang-analyzer-fuchsia.HandleChecker
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#fuchsia-handlechecker
+
+clang-analyzer-fuchsia.HandleChecker
+====================================
+
+A Checker that detect leaks related to Fuchsia handles.
+
+The clang-analyzer-fuchsia.HandleChecker check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullPassedToNonnull.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullPassedToNonnull.rst
index 7ebbb9b7d6588..85e0dc2f116c5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullPassedToNonnull.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullPassedToNonnull.rst
@@ -5,6 +5,9 @@
clang-analyzer-nullability.NullPassedToNonnull
==============================================
+Warns when a null pointer is passed to a pointer which has a _Nonnull type.
+
The clang-analyzer-nullability.NullPassedToNonnull check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullReturnedFromNonnull.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullReturnedFromNonnull.rst
index e585c7ba1826b..132c8311bc1d0 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullReturnedFromNonnull.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullReturnedFromNonnull.rst
@@ -5,6 +5,10 @@
clang-analyzer-nullability.NullReturnedFromNonnull
==================================================
+Warns when a null pointer is returned from a function that has _Nonnull return
+type.
+
The clang-analyzer-nullability.NullReturnedFromNonnull check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableDereferenced.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableDereferenced.rst
index 9734863366126..027487b1533ea 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableDereferenced.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableDereferenced.rst
@@ -5,6 +5,9 @@
clang-analyzer-nullability.NullableDereferenced
===============================================
+Warns when a nullable pointer is dereferenced.
+
The clang-analyzer-nullability.NullableDereferenced check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullablePassedToNonnull.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullablePassedToNonnull.rst
index 1c9b590e67d8f..f1261e680595a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullablePassedToNonnull.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullablePassedToNonnull.rst
@@ -5,6 +5,9 @@
clang-analyzer-nullability.NullablePassedToNonnull
==================================================
+Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
+
The clang-analyzer-nullability.NullablePassedToNonnull check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableReturnedFromNonnull.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableReturnedFromNonnull.rst
index c30b530a0dec1..dc6f7a1525b80 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableReturnedFromNonnull.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/nullability.NullableReturnedFromNonnull.rst
@@ -1,6 +1,14 @@
.. title:: clang-tidy - clang-analyzer-nullability.NullableReturnedFromNonnull
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#nullability-nullablereturnedfromnonnull
clang-analyzer-nullability.NullableReturnedFromNonnull
======================================================
-Warns when a nullable pointer is returned from a function that has _Nonnull return type.
+Warns when a nullable pointer is returned from a function that has _Nonnull
+return type.
+
+The clang-analyzer-nullability.NullableReturnedFromNonnull check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.UninitializedObject.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.UninitializedObject.rst
index 3380dc3277735..5cf352a23cadc 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.UninitializedObject.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.UninitializedObject.rst
@@ -5,6 +5,9 @@
clang-analyzer-optin.cplusplus.UninitializedObject
==================================================
+Reports uninitialized fields after object construction.
+
The clang-analyzer-optin.cplusplus.UninitializedObject check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.VirtualCall.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.VirtualCall.rst
index 52cf5ff97db81..5ec5faaec71ee 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.VirtualCall.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.cplusplus.VirtualCall.rst
@@ -5,6 +5,9 @@
clang-analyzer-optin.cplusplus.VirtualCall
==========================================
+Check virtual function calls during construction/destruction.
+
The clang-analyzer-optin.cplusplus.VirtualCall check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.mpi.MPI-Checker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.mpi.MPI-Checker.rst
index 211070c5a6e0e..45b1a92fc3378 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.mpi.MPI-Checker.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.mpi.MPI-Checker.rst
@@ -5,6 +5,9 @@
clang-analyzer-optin.mpi.MPI-Checker
====================================
+Checks MPI code.
+
The clang-analyzer-optin.mpi.MPI-Checker check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst
index 65e9efba1b2eb..c2fef59f56894 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst
@@ -3,4 +3,7 @@
clang-analyzer-optin.osx.OSObjectCStyleCast
===========================================
-Checker for C-style casts of OSObjects
+Checker for C-style casts of OSObjects.
+
+The clang-analyzer-optin.osx.OSObjectCStyleCast check is an alias of
+Clang Static Analyzer optin.osx.OSObjectCStyleCast.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.EmptyLocalizationContextChecker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.EmptyLocalizationContextChecker.rst
index 8a8395c8c8ce9..669f37c365c8e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.EmptyLocalizationContextChecker.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.EmptyLocalizationContextChecker.rst
@@ -5,6 +5,9 @@
clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker
=============================================================================
+Check that NSLocalizedString macros include a comment for context.
+
The clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.NonLocalizedStringChecker.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.NonLocalizedStringChecker.rst
index dc214719ba73b..3ab5fd847d407 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.NonLocalizedStringChecker.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.cocoa.localizability.NonLocalizedStringChecker.rst
@@ -5,6 +5,10 @@
clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker
=======================================================================
+Warns about uses of non-localized NSStrings passed to UI methods expecting
+localized NSStrings.
+
The clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.GCDAntipattern.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.GCDAntipattern.rst
index 2684f750091a0..6b1af473c572b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.GCDAntipattern.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.GCDAntipattern.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-optin.performance.GCDAntipattern
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-gcdantipattern
clang-analyzer-optin.performance.GCDAntipattern
===============================================
-Check for performance anti-patterns when using Grand Central Dispatch
+Check for performance anti-patterns when using Grand Central Dispatch.
+
+The clang-analyzer-optin.performance.GCDAntipattern check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.Padding.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.Padding.rst
index fc2d7300de76a..40e5e65419285 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.Padding.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.performance.Padding.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-optin.performance.Padding
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-performance-padding
clang-analyzer-optin.performance.Padding
========================================
Check for excessively padded structs.
+
+The clang-analyzer-optin.performance.Padding check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.portability.UnixAPI.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.portability.UnixAPI.rst
index 07545becaef8e..43dafc841777d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.portability.UnixAPI.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.portability.UnixAPI.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-optin.portability.UnixAPI
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#optin-portability-unixapi
clang-analyzer-optin.portability.UnixAPI
========================================
-Finds implementation-defined behavior in UNIX/Posix functions
+Finds implementation-defined behavior in UNIX/Posix functions.
+
+The clang-analyzer-optin.portability.UnixAPI check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.API.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.API.rst
index b3aae0c8bb504..46f0821880d50 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.API.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.API.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.API
======================
+Check for proper uses of various Apple APIs.
+
The clang-analyzer-osx.API check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst
index 50fb5a8db6b0a..a7b8a1cfb14cd 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst
@@ -3,4 +3,7 @@
clang-analyzer-osx.MIG
======================
-Find violations of the Mach Interface Generator calling convention
+Find violations of the Mach Interface Generator calling convention.
+
+The clang-analyzer-osx.MIG check is an alias of
+Clang Static Analyzer osx.MIG.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.NumberObjectConversion.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.NumberObjectConversion.rst
index 7471ad17d7d7d..cc45624987db8 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.NumberObjectConversion.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.NumberObjectConversion.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.NumberObjectConversion
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-numberobjectconversion
clang-analyzer-osx.NumberObjectConversion
=========================================
-Check for erroneous conversions of objects representing numbers into numbers
+Check for erroneous conversions of objects representing numbers into numbers.
+
+The clang-analyzer-osx.NumberObjectConversion check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst
index 8eceb3f3b4dd1..c32982d407c28 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst
@@ -3,4 +3,7 @@
clang-analyzer-osx.OSObjectRetainCount
======================================
-Check for leaks and improper reference count management for OSObject
+Check for leaks and improper reference count management for OSObject.
+
+The clang-analyzer-osx.OSObjectRetainCount check is an alias of
+Clang Static Analyzer osx.OSObjectRetainCount.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.ObjCProperty.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.ObjCProperty.rst
index 0b87cd0207825..8df48b78ca2bc 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.ObjCProperty.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.ObjCProperty.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.ObjCProperty
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-objcproperty
clang-analyzer-osx.ObjCProperty
===============================
-Check for proper uses of Objective-C properties
+Check for proper uses of Objective-C properties.
+
+The clang-analyzer-osx.ObjCProperty check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.SecKeychainAPI.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.SecKeychainAPI.rst
index 130fae59a677b..4d6f6a1684111 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.SecKeychainAPI.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.SecKeychainAPI.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.SecKeychainAPI
=================================
+Check for proper uses of Secure Keychain APIs.
+
The clang-analyzer-osx.SecKeychainAPI check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AtSync.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AtSync.rst
index 56a98bfb9a2e1..60e4022ff9915 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AtSync.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AtSync.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.AtSync
===============================
+Check for nil pointers used as mutexes for @synchronized.
+
The clang-analyzer-osx.cocoa.AtSync check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AutoreleaseWrite.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AutoreleaseWrite.rst
index 01fbe4f84368f..1cca7bb9238e6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AutoreleaseWrite.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.AutoreleaseWrite.rst
@@ -1,6 +1,14 @@
.. title:: clang-tidy - clang-analyzer-osx.cocoa.AutoreleaseWrite
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-cocoa-autoreleasewrite
clang-analyzer-osx.cocoa.AutoreleaseWrite
=========================================
-Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C
+Warn about potentially crashing writes to autoreleasing objects from different
+autoreleasing pools in Objective-C.
+
+The clang-analyzer-osx.cocoa.AutoreleaseWrite check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ClassRelease.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ClassRelease.rst
index d6c0bae27ead7..3cf78ab874f3b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ClassRelease.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ClassRelease.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.ClassRelease
=====================================
+Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
+
The clang-analyzer-osx.cocoa.ClassRelease check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Dealloc.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Dealloc.rst
index e02bf63b9a33b..acaf11442b0e2 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Dealloc.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Dealloc.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.Dealloc
================================
+Warn about Objective-C classes that lack a correct implementation of -dealloc.
+
The clang-analyzer-osx.cocoa.Dealloc check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.IncompatibleMethodTypes.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.IncompatibleMethodTypes.rst
index 6aa64e209746e..17e13f582c0f6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.IncompatibleMethodTypes.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.IncompatibleMethodTypes.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.IncompatibleMethodTypes
================================================
+Warn about Objective-C method signatures with type incompatibilities.
+
The clang-analyzer-osx.cocoa.IncompatibleMethodTypes check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Loops.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Loops.rst
index 622f80ff87106..2ee092bbf8f00 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Loops.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.Loops.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.cocoa.Loops
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-cocoa-loops
clang-analyzer-osx.cocoa.Loops
==============================
-Improved modeling of loops using Cocoa collection types
+Improved modeling of loops using Cocoa collection types.
+
+The clang-analyzer-osx.cocoa.Loops check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.MissingSuperCall.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.MissingSuperCall.rst
index a8e4290278a9f..ee57d1d86f100 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.MissingSuperCall.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.MissingSuperCall.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.cocoa.MissingSuperCall
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-cocoa-missingsupercall
clang-analyzer-osx.cocoa.MissingSuperCall
=========================================
-Warn about Objective-C methods that lack a necessary call to super
+Warn about Objective-C methods that lack a necessary call to super.
+
+The clang-analyzer-osx.cocoa.MissingSuperCall check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSAutoreleasePool.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSAutoreleasePool.rst
index 9446850c45881..0c10069041604 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSAutoreleasePool.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSAutoreleasePool.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.NSAutoreleasePool
==========================================
+Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
+
The clang-analyzer-osx.cocoa.NSAutoreleasePool check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSError.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSError.rst
index 23416fcf8688d..35fddde39d8db 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSError.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NSError.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.NSError
================================
+Check usage of NSError** parameters.
+
The clang-analyzer-osx.cocoa.NSError check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NilArg.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NilArg.rst
index 4b521041976cf..0e189a1d9d1d8 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NilArg.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NilArg.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.NilArg
===============================
+Check for prohibited nil arguments to ObjC method calls.
+
The clang-analyzer-osx.cocoa.NilArg check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NonNilReturnValue.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NonNilReturnValue.rst
index a6da9b0cca491..aafdd3dc27f5c 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NonNilReturnValue.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.NonNilReturnValue.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.cocoa.NonNilReturnValue
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-cocoa-nonnilreturnvalue
clang-analyzer-osx.cocoa.NonNilReturnValue
==========================================
-Model the APIs that are guaranteed to return a non-nil value
+Model the APIs that are guaranteed to return a non-nil value.
+
+The clang-analyzer-osx.cocoa.NonNilReturnValue check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ObjCGenerics.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ObjCGenerics.rst
index 10e21e30a5ea3..d27a492cb224e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ObjCGenerics.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.ObjCGenerics.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.ObjCGenerics
=====================================
+Check for type errors when using Objective-C generics.
+
The clang-analyzer-osx.cocoa.ObjCGenerics check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RetainCount.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RetainCount.rst
index 92a72df785fad..d0e71e8a823bf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RetainCount.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RetainCount.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.RetainCount
====================================
+Check for leaks and improper reference count management.
+
The clang-analyzer-osx.cocoa.RetainCount check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RunLoopAutoreleaseLeak.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RunLoopAutoreleaseLeak.rst
index 67a0519b9b777..3b2e433964e77 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RunLoopAutoreleaseLeak.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.RunLoopAutoreleaseLeak.rst
@@ -1,6 +1,13 @@
.. title:: clang-tidy - clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak
+.. meta::
+ :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#osx-cocoa-runloopautoreleaseleak
clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak
===============================================
-Check for leaked memory in autorelease pools that will never be drained
+Check for leaked memory in autorelease pools that will never be drained.
+
+The clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak check is an alias, please see
+`Clang Static Analyzer Available Checkers
+`_
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SelfInit.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SelfInit.rst
index 96e559e103a35..a5484f2ad8c7f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SelfInit.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SelfInit.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.SelfInit
=================================
+Check that 'self' is properly initialized inside an initializer method.
+
The clang-analyzer-osx.cocoa.SelfInit check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SuperDealloc.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SuperDealloc.rst
index 598f12686b42c..ab13b6ab3289b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SuperDealloc.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.SuperDealloc.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.SuperDealloc
=====================================
+Warn about improper use of '[super dealloc]' in Objective-C.
+
The clang-analyzer-osx.cocoa.SuperDealloc check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.UnusedIvars.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.UnusedIvars.rst
index 5a12aa4802c96..cb3ffd1d870eb 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.UnusedIvars.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.UnusedIvars.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.cocoa.UnusedIvars
====================================
+Warn about private ivars that are never used.
+
The clang-analyzer-osx.cocoa.UnusedIvars check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.VariadicMethodTypes.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.VariadicMethodTypes.rst
index 292e7e3fd1c08..fd9405451a427 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.VariadicMethodTypes.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.cocoa.VariadicMethodTypes.rst
@@ -5,6 +5,10 @@
clang-analyzer-osx.cocoa.VariadicMethodTypes
============================================
+Check for passing non-Objective-C types to variadic collection initialization
+methods that expect only Objective-C types.
+
The clang-analyzer-osx.cocoa.VariadicMethodTypes check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFError.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFError.rst
index 7dab4bdabda31..200ec6232bcc2 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFError.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFError.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.coreFoundation.CFError
=========================================
+Check usage of CFErrorRef* parameters.
+
The clang-analyzer-osx.coreFoundation.CFError check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFNumber.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFNumber.rst
index 86e117a72f8b3..83a0541e0e32c 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFNumber.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFNumber.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.coreFoundation.CFNumber
==========================================
+Check for proper uses of CFNumber APIs.
+
The clang-analyzer-osx.coreFoundation.CFNumber check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFRetainRelease.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFRetainRelease.rst
index 0865611b5df61..766993900d364 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFRetainRelease.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.CFRetainRelease.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.coreFoundation.CFRetainRelease
=================================================
+Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
+
The clang-analyzer-osx.coreFoundation.CFRetainRelease check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.OutOfBounds.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.OutOfBounds.rst
index ca1eb756eace6..e8fb9ea806f68 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.OutOfBounds.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.OutOfBounds.rst
@@ -5,6 +5,9 @@
clang-analyzer-osx.coreFoundation.containers.OutOfBounds
========================================================
+Checks for index out-of-bounds when using 'CFArray' API.
+
The clang-analyzer-osx.coreFoundation.containers.OutOfBounds check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.PointerSizedValues.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.PointerSizedValues.rst
index fb1fa15f96267..57370934eae6f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.PointerSizedValues.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.coreFoundation.containers.PointerSizedValues.rst
@@ -5,6 +5,10 @@
clang-analyzer-osx.coreFoundation.containers.PointerSizedValues
===============================================================
+Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size
+values.
+
The clang-analyzer-osx.coreFoundation.containers.PointerSizedValues check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.FloatLoopCounter.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.FloatLoopCounter.rst
index b378a34b9f7da..a39f4ae66f032 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.FloatLoopCounter.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.FloatLoopCounter.rst
@@ -5,6 +5,10 @@
clang-analyzer-security.FloatLoopCounter
========================================
+Warn on using a floating point value as a loop counter (CERT: FLP30-C,
+FLP30-CPP).
+
The clang-analyzer-security.FloatLoopCounter check is an alias, please see
-`Clang Static Analyzer Available Checkers `_
+`Clang Static Analyzer Available Checkers
+`_
for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.insecureAPI.DeprecatedOrUnsafeBufferHandling.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.insecureAPI.DeprecatedOrUnsafeBufferHandling.rst
index b4e611b265318..c7c035ecec6ae 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.insecureAPI.DeprecatedOrUnsafeBufferHandling.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.insecureAPI.DeprecatedOrUnsafeBufferHandling.rst
@@ -5,6 +5,9 @@
clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
====================================================================
+Warn on uses of unsecure or deprecated buffer manipulating functions.
+
The clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling check is an alias, please see
-`Clang Static Analyzer Available Checkers