Mercurial > hg > CbC > CbC_llvm
comparison tools/dsymutil/CompileUnit.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- tools/dsymutil/CompileUnit.h - Dwarf compile unit ------------------===// | |
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 //===----------------------------------------------------------------------===// | |
8 | |
9 #include "CompileUnit.h" | |
10 #include "DeclContext.h" | |
11 | |
12 namespace llvm { | |
13 namespace dsymutil { | |
14 | |
15 /// Check if the DIE at \p Idx is in the scope of a function. | |
16 static bool inFunctionScope(CompileUnit &U, unsigned Idx) { | |
17 while (Idx) { | |
18 if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram) | |
19 return true; | |
20 Idx = U.getInfo(Idx).ParentIdx; | |
21 } | |
22 return false; | |
23 } | |
24 | |
25 uint16_t CompileUnit::getLanguage() { | |
26 if (!Language) { | |
27 DWARFDie CU = getOrigUnit().getUnitDIE(); | |
28 Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0); | |
29 } | |
30 return Language; | |
31 } | |
32 | |
33 void CompileUnit::markEverythingAsKept() { | |
34 unsigned Idx = 0; | |
35 | |
36 setHasInterestingContent(); | |
37 | |
38 for (auto &I : Info) { | |
39 // Mark everything that wasn't explicit marked for pruning. | |
40 I.Keep = !I.Prune; | |
41 auto DIE = OrigUnit.getDIEAtIndex(Idx++); | |
42 | |
43 // Try to guess which DIEs must go to the accelerator tables. We do that | |
44 // just for variables, because functions will be handled depending on | |
45 // whether they carry a DW_AT_low_pc attribute or not. | |
46 if (DIE.getTag() != dwarf::DW_TAG_variable && | |
47 DIE.getTag() != dwarf::DW_TAG_constant) | |
48 continue; | |
49 | |
50 Optional<DWARFFormValue> Value; | |
51 if (!(Value = DIE.find(dwarf::DW_AT_location))) { | |
52 if ((Value = DIE.find(dwarf::DW_AT_const_value)) && | |
53 !inFunctionScope(*this, I.ParentIdx)) | |
54 I.InDebugMap = true; | |
55 continue; | |
56 } | |
57 if (auto Block = Value->getAsBlock()) { | |
58 if (Block->size() > OrigUnit.getAddressByteSize() && | |
59 (*Block)[0] == dwarf::DW_OP_addr) | |
60 I.InDebugMap = true; | |
61 } | |
62 } | |
63 } | |
64 | |
65 uint64_t CompileUnit::computeNextUnitOffset() { | |
66 NextUnitOffset = StartOffset; | |
67 if (NewUnit) { | |
68 NextUnitOffset += 11 /* Header size */; | |
69 NextUnitOffset += NewUnit->getUnitDie().getSize(); | |
70 } | |
71 return NextUnitOffset; | |
72 } | |
73 | |
74 /// Keep track of a forward cross-cu reference from this unit | |
75 /// to \p Die that lives in \p RefUnit. | |
76 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit, | |
77 DeclContext *Ctxt, PatchLocation Attr) { | |
78 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr); | |
79 } | |
80 | |
81 void CompileUnit::fixupForwardReferences() { | |
82 for (const auto &Ref : ForwardDIEReferences) { | |
83 DIE *RefDie; | |
84 const CompileUnit *RefUnit; | |
85 PatchLocation Attr; | |
86 DeclContext *Ctxt; | |
87 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref; | |
88 if (Ctxt && Ctxt->getCanonicalDIEOffset()) | |
89 Attr.set(Ctxt->getCanonicalDIEOffset()); | |
90 else | |
91 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset()); | |
92 } | |
93 } | |
94 | |
95 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) { | |
96 Labels.insert({LabelLowPc, PcOffset}); | |
97 } | |
98 | |
99 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, | |
100 int64_t PcOffset) { | |
101 // Don't add empty ranges to the interval map. They are a problem because | |
102 // the interval map expects half open intervals. This is safe because they | |
103 // are empty anyway. | |
104 if (FuncHighPc != FuncLowPc) | |
105 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset); | |
106 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset); | |
107 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); | |
108 } | |
109 | |
110 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) { | |
111 if (Die.getTag() != dwarf::DW_TAG_compile_unit) | |
112 RangeAttributes.push_back(Attr); | |
113 else | |
114 UnitRangeAttribute = Attr; | |
115 } | |
116 | |
117 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) { | |
118 LocationAttributes.emplace_back(Attr, PcOffset); | |
119 } | |
120 | |
121 void CompileUnit::addNamespaceAccelerator(const DIE *Die, | |
122 DwarfStringPoolEntryRef Name) { | |
123 Namespaces.emplace_back(Name, Die); | |
124 } | |
125 | |
126 void CompileUnit::addObjCAccelerator(const DIE *Die, | |
127 DwarfStringPoolEntryRef Name, | |
128 bool SkipPubSection) { | |
129 ObjC.emplace_back(Name, Die, SkipPubSection); | |
130 } | |
131 | |
132 void CompileUnit::addNameAccelerator(const DIE *Die, | |
133 DwarfStringPoolEntryRef Name, | |
134 bool SkipPubSection) { | |
135 Pubnames.emplace_back(Name, Die, SkipPubSection); | |
136 } | |
137 | |
138 void CompileUnit::addTypeAccelerator(const DIE *Die, | |
139 DwarfStringPoolEntryRef Name, | |
140 bool ObjcClassImplementation, | |
141 uint32_t QualifiedNameHash) { | |
142 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation); | |
143 } | |
144 | |
145 } // namespace dsymutil | |
146 } // namespace llvm |