Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework -----------------===//
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 "DwarfFile.h"
10
#include "DwarfCompileUnit.h"
11
#include "DwarfDebug.h"
12
#include "DwarfUnit.h"
13
#include "llvm/ADT/SmallVector.h"
14
#include "llvm/CodeGen/AsmPrinter.h"
15
#include "llvm/CodeGen/DIE.h"
16
#include "llvm/IR/DebugInfoMetadata.h"
17
#include "llvm/MC/MCStreamer.h"
18
#include <algorithm>
19
#include <cstdint>
20
21
using namespace llvm;
22
23
DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
24
71.5k
    : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {}
25
26
2.72k
void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) {
27
2.72k
  CUs.push_back(std::move(U));
28
2.72k
}
29
30
// Emit the various dwarf units to the unit section USection with
31
// the abbreviations going into ASection.
32
3.26k
void DwarfFile::emitUnits(bool UseOffsets) {
33
3.26k
  for (const auto &TheU : CUs)
34
2.72k
    emitUnit(TheU.get(), UseOffsets);
35
3.26k
}
36
37
2.76k
void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
38
2.76k
  if (TheU->getCUNode()->isDebugDirectivesOnly())
39
3
    return;
40
2.76k
41
2.76k
  MCSection *S = TheU->getSection();
42
2.76k
43
2.76k
  if (!S)
44
0
    return;
45
2.76k
46
2.76k
  // Skip CUs that ended up not being needed (split CUs that were abandoned
47
2.76k
  // because they added no information beyond the non-split CU)
48
2.76k
  if (llvm::empty(TheU->getUnitDie().values()))
49
1
    return;
50
2.75k
51
2.75k
  Asm->OutStreamer->SwitchSection(S);
52
2.75k
  TheU->emitHeader(UseOffsets);
53
2.75k
  Asm->emitDwarfDIE(TheU->getUnitDie());
54
2.75k
55
2.75k
  if (MCSymbol *EndLabel = TheU->getEndLabel())
56
2.74k
    Asm->OutStreamer->EmitLabel(EndLabel);
57
2.75k
}
58
59
// Compute the size and offset for each DIE.
60
3.26k
void DwarfFile::computeSizeAndOffsets() {
61
3.26k
  // Offset from the first CU in the debug info section is 0 initially.
62
3.26k
  unsigned SecOffset = 0;
63
3.26k
64
3.26k
  // Iterate over each compile unit and set the size and offsets for each
65
3.26k
  // DIE within each compile unit. All offsets are CU relative.
66
3.26k
  for (const auto &TheU : CUs) {
67
2.72k
    if (TheU->getCUNode()->isDebugDirectivesOnly())
68
3
      continue;
69
2.72k
70
2.72k
    // Skip CUs that ended up not being needed (split CUs that were abandoned
71
2.72k
    // because they added no information beyond the non-split CU)
72
2.72k
    if (llvm::empty(TheU->getUnitDie().values()))
73
1
      return;
74
2.72k
75
2.72k
    TheU->setDebugSectionOffset(SecOffset);
76
2.72k
    SecOffset += computeSizeAndOffsetsForUnit(TheU.get());
77
2.72k
  }
78
3.26k
}
79
80
2.75k
unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
81
2.75k
  // CU-relative offset is reset to 0 here.
82
2.75k
  unsigned Offset = sizeof(int32_t) +      // Length of Unit Info
83
2.75k
                    TheU->getHeaderSize(); // Unit-specific headers
84
2.75k
85
2.75k
  // The return value here is CU-relative, after laying out
86
2.75k
  // all of the CU DIE.
87
2.75k
  return computeSizeAndOffset(TheU->getUnitDie(), Offset);
88
2.75k
}
89
90
// Compute the size and offset of a DIE. The offset is relative to start of the
91
// CU. It returns the offset after laying out the DIE.
92
2.75k
unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
93
2.75k
  return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset);
94
2.75k
}
95
96
3.26k
void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); }
97
98
// Emit strings into a string section.
99
void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection,
100
3.26k
                            bool UseRelativeOffsets) {
101
3.26k
  StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets);
102
3.26k
}
103
104
1.31k
bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
105
1.31k
  auto &ScopeVars = ScopeVariables[LS];
106
1.31k
  const DILocalVariable *DV = Var->getVariable();
107
1.31k
  if (unsigned ArgNum = DV->getArg()) {
108
789
    auto Cached = ScopeVars.Args.find(ArgNum);
109
789
    if (Cached == ScopeVars.Args.end())
110
789
      ScopeVars.Args[ArgNum] = Var;
111
0
    else {
112
0
      Cached->second->addMMIEntry(*Var);
113
0
      return false;
114
0
    }
115
523
  } else {
116
523
    ScopeVars.Locals.push_back(Var);
117
523
  }
118
1.31k
  return true;
119
1.31k
}
120
121
8
void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) {
122
8
  SmallVectorImpl<DbgLabel *> &Labels = ScopeLabels[LS];
123
8
  Labels.push_back(Label);
124
8
}
125
126
std::pair<uint32_t, RangeSpanList *>
127
56.9k
DwarfFile::addRange(const DwarfCompileUnit &CU, SmallVector<RangeSpan, 2> R) {
128
56.9k
  CURangeLists.push_back(
129
56.9k
      RangeSpanList(Asm->createTempSymbol("debug_ranges"), CU, std::move(R)));
130
56.9k
  return std::make_pair(CURangeLists.size() - 1, &CURangeLists.back());
131
56.9k
}