1 //===- DWARFLinkerTypeUnit.h ------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
10 #define LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
12 #include "DWARFLinkerUnit.h"
13 #include "llvm/CodeGen/DIE.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
15 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
18 namespace dwarf_linker
{
21 /// Type Unit is used to represent an artificial compilation unit
22 /// which keeps all type information. This type information is referenced
23 /// from other compilation units.
24 class TypeUnit
: public DwarfUnit
{
26 TypeUnit(LinkingGlobalData
&GlobalData
, unsigned ID
,
27 std::optional
<uint16_t> Language
, dwarf::FormParams Format
,
28 llvm::endianness Endianess
);
30 /// Generates DIE tree based on information from TypesMap.
31 void createDIETree(BumpPtrAllocator
&Allocator
);
33 /// Emits resulting dwarf based on information from DIE tree.
34 Error
finishCloningAndEmit(const Triple
&TargetTriple
);
36 /// Returns global type pool.
37 TypePool
&getTypePool() { return Types
; }
39 /// TypeUnitAccelInfo extends AccelInfo structure with type specific fileds.
40 /// We need these additional fields to decide whether OutDIE should have an
41 /// accelerator record or not. The TypeEntryBodyPtr can refer to the
42 /// declaration DIE and definition DIE corresponding to the type entry.
43 /// Only one of them would be used in final output. So if TypeUnitAccelInfo
44 /// refers OutDIE which does not match with TypeEntryBodyPtr->getFinalDie()
45 /// then such record should be skipped.
46 struct TypeUnitAccelInfo
: public AccelInfo
{
47 /// Pointer to the output DIE which owns this accelerator record.
48 DIE
*OutDIE
= nullptr;
50 /// Pointer to the type entry body.
51 TypeEntryBody
*TypeEntryBodyPtr
= nullptr;
54 /// Enumerates all accelerator records and call \p Handler for each.
56 forEachAcceleratorRecord(function_ref
<void(AccelInfo
&)> Handler
) override
{
57 AcceleratorRecords
.forEach([&](TypeUnitAccelInfo
&Info
) {
58 // Check whether current record is for the final DIE.
59 assert(Info
.TypeEntryBodyPtr
!= nullptr);
61 if (&Info
.TypeEntryBodyPtr
->getFinalDie() != Info
.OutDIE
)
64 Info
.OutOffset
= Info
.OutDIE
->getOffset();
69 /// Returns index for the specified \p String inside .debug_str_offsets.
70 uint64_t getDebugStrIndex(const StringEntry
*String
) override
{
71 std::unique_lock
<std::mutex
> LockGuard(DebugStringIndexMapMutex
);
72 return DebugStringIndexMap
.getValueIndex(String
);
75 /// Adds \p Info to the unit's accelerator records.
76 void saveAcceleratorInfo(const TypeUnitAccelInfo
&Info
) {
77 AcceleratorRecords
.add(Info
);
81 /// Type DIEs are partially created at clonning stage. They are organised
82 /// as a tree using type entries. This function links DIEs(corresponding
83 /// to the type entries) into the tree structure.
84 uint64_t finalizeTypeEntryRec(uint64_t OutOffset
, DIE
*OutDIE
,
87 /// Prepares DIEs to be linked into the tree.
88 void prepareDataForTreeCreation();
90 /// Add specified \p Dir and \p Filename into the line table
91 /// of this type unit.
92 uint32_t addFileNameIntoLinetable(StringEntry
*Dir
, StringEntry
*FileName
);
94 std::pair
<dwarf::Form
, uint8_t> getScalarFormForValue(uint64_t Value
) const;
96 uint8_t getSizeByAttrForm(dwarf::Form Form
) const;
98 struct CmpStringEntryRef
{
99 bool operator()(const StringEntry
*LHS
, const StringEntry
*RHS
) const {
100 return LHS
->first() < RHS
->first();
103 struct CmpDirIDStringEntryRef
{
104 bool operator()(const std::pair
<StringEntry
*, uint64_t> &LHS
,
105 const std::pair
<StringEntry
*, uint64_t> &RHS
) const {
106 return LHS
.second
< RHS
.second
||
107 (!(RHS
.second
< LHS
.second
) &&
108 LHS
.first
->first() < RHS
.first
->first());
112 /// The DW_AT_language of this unit.
113 std::optional
<uint16_t> Language
;
115 /// This unit line table.
116 DWARFDebugLine::LineTable LineTable
;
118 /// Data members keeping file names for line table.
119 using DirectoriesMapTy
= std::map
<StringEntry
*, size_t, CmpStringEntryRef
>;
120 using FilenamesMapTy
= std::map
<std::pair
<StringEntry
*, uint64_t>, size_t,
121 CmpDirIDStringEntryRef
>;
123 DirectoriesMapTy DirectoriesMap
;
124 FilenamesMapTy FileNamesMap
;
129 /// List of accelerator entries for this unit.
130 ArrayList
<TypeUnitAccelInfo
> AcceleratorRecords
;
132 /// Guard for DebugStringIndexMap.
133 std::mutex DebugStringIndexMapMutex
;
136 } // end of namespace parallel
137 } // end of namespace dwarf_linker
138 } // end of namespace llvm
140 #endif // LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H