[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / DWARFLinker / DWARFLinkerCompileUnit.cpp
blob925ab3d295c256a749ed346454e427e80182e306
1 //===- DWARFLinkerCompileUnit.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
10 #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
12 namespace llvm {
14 /// Check if the DIE at \p Idx is in the scope of a function.
15 static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
16 while (Idx) {
17 if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram)
18 return true;
19 Idx = U.getInfo(Idx).ParentIdx;
21 return false;
24 uint16_t CompileUnit::getLanguage() {
25 if (!Language) {
26 DWARFDie CU = getOrigUnit().getUnitDIE();
27 Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
29 return Language;
32 StringRef CompileUnit::getSysRoot() {
33 if (SysRoot.empty()) {
34 DWARFDie CU = getOrigUnit().getUnitDIE();
35 SysRoot = dwarf::toStringRef(CU.find(dwarf::DW_AT_LLVM_sysroot)).str();
37 return SysRoot;
40 void CompileUnit::markEverythingAsKept() {
41 unsigned Idx = 0;
43 setHasInterestingContent();
45 for (auto &I : Info) {
46 // Mark everything that wasn't explicit marked for pruning.
47 I.Keep = !I.Prune;
48 auto DIE = OrigUnit.getDIEAtIndex(Idx++);
50 // Try to guess which DIEs must go to the accelerator tables. We do that
51 // just for variables, because functions will be handled depending on
52 // whether they carry a DW_AT_low_pc attribute or not.
53 if (DIE.getTag() != dwarf::DW_TAG_variable &&
54 DIE.getTag() != dwarf::DW_TAG_constant)
55 continue;
57 Optional<DWARFFormValue> Value;
58 if (!(Value = DIE.find(dwarf::DW_AT_location))) {
59 if ((Value = DIE.find(dwarf::DW_AT_const_value)) &&
60 !inFunctionScope(*this, I.ParentIdx))
61 I.InDebugMap = true;
62 continue;
64 if (auto Block = Value->getAsBlock()) {
65 if (Block->size() > OrigUnit.getAddressByteSize() &&
66 (*Block)[0] == dwarf::DW_OP_addr)
67 I.InDebugMap = true;
72 uint64_t CompileUnit::computeNextUnitOffset(uint16_t DwarfVersion) {
73 NextUnitOffset = StartOffset;
74 if (NewUnit) {
75 NextUnitOffset += (DwarfVersion >= 5) ? 12 : 11; // Header size
76 NextUnitOffset += NewUnit->getUnitDie().getSize();
78 return NextUnitOffset;
81 /// Keep track of a forward cross-cu reference from this unit
82 /// to \p Die that lives in \p RefUnit.
83 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit,
84 DeclContext *Ctxt, PatchLocation Attr) {
85 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr);
88 void CompileUnit::fixupForwardReferences() {
89 for (const auto &Ref : ForwardDIEReferences) {
90 DIE *RefDie;
91 const CompileUnit *RefUnit;
92 PatchLocation Attr;
93 DeclContext *Ctxt;
94 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref;
95 if (Ctxt && Ctxt->getCanonicalDIEOffset())
96 Attr.set(Ctxt->getCanonicalDIEOffset());
97 else
98 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset());
102 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
103 Labels.insert({LabelLowPc, PcOffset});
106 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
107 int64_t PcOffset) {
108 // Don't add empty ranges to the interval map. They are a problem because
109 // the interval map expects half open intervals. This is safe because they
110 // are empty anyway.
111 if (FuncHighPc != FuncLowPc)
112 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
113 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
114 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
117 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
118 if (Die.getTag() != dwarf::DW_TAG_compile_unit)
119 RangeAttributes.push_back(Attr);
120 else
121 UnitRangeAttribute = Attr;
124 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
125 LocationAttributes.emplace_back(Attr, PcOffset);
128 void CompileUnit::addNamespaceAccelerator(const DIE *Die,
129 DwarfStringPoolEntryRef Name) {
130 Namespaces.emplace_back(Name, Die);
133 void CompileUnit::addObjCAccelerator(const DIE *Die,
134 DwarfStringPoolEntryRef Name,
135 bool SkipPubSection) {
136 ObjC.emplace_back(Name, Die, SkipPubSection);
139 void CompileUnit::addNameAccelerator(const DIE *Die,
140 DwarfStringPoolEntryRef Name,
141 bool SkipPubSection) {
142 Pubnames.emplace_back(Name, Die, SkipPubSection);
145 void CompileUnit::addTypeAccelerator(const DIE *Die,
146 DwarfStringPoolEntryRef Name,
147 bool ObjcClassImplementation,
148 uint32_t QualifiedNameHash) {
149 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation);
152 } // namespace llvm