Coverage Report

Created: 2017-09-21 03:39

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/Simple.h
Line
Count
Source (jump to first uncovered line)
1
//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// \brief Provide simple implementations for Atoms and File.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLD_CORE_SIMPLE_H
16
#define LLD_CORE_SIMPLE_H
17
18
#include "lld/Core/AbsoluteAtom.h"
19
#include "lld/Core/Atom.h"
20
#include "lld/Core/DefinedAtom.h"
21
#include "lld/Core/File.h"
22
#include "lld/Core/Reference.h"
23
#include "lld/Core/SharedLibraryAtom.h"
24
#include "lld/Core/UndefinedAtom.h"
25
#include "llvm/ADT/SmallVector.h"
26
#include "llvm/ADT/StringRef.h"
27
#include "llvm/ADT/ilist.h"
28
#include "llvm/ADT/ilist_node.h"
29
#include "llvm/Support/Allocator.h"
30
#include "llvm/Support/Casting.h"
31
#include "llvm/Support/ErrorHandling.h"
32
#include <algorithm>
33
#include <cassert>
34
#include <cstdint>
35
#include <functional>
36
37
namespace lld {
38
39
class SimpleFile : public File {
40
public:
41
  SimpleFile(StringRef path, File::Kind kind)
42
1.05k
    : File(path, kind) {}
43
44
1.05k
  ~SimpleFile() override {
45
1.05k
    _defined.clear();
46
1.05k
    _undefined.clear();
47
1.05k
    _shared.clear();
48
1.05k
    _absolute.clear();
49
1.05k
  }
50
51
1.37k
  void addAtom(DefinedAtom &a) {
52
1.37k
    _defined.push_back(OwningAtomPtr<DefinedAtom>(&a));
53
1.37k
  }
54
375
  void addAtom(UndefinedAtom &a) {
55
375
    _undefined.push_back(OwningAtomPtr<UndefinedAtom>(&a));
56
375
  }
57
138
  void addAtom(SharedLibraryAtom &a) {
58
138
    _shared.push_back(OwningAtomPtr<SharedLibraryAtom>(&a));
59
138
  }
60
0
  void addAtom(AbsoluteAtom &a) {
61
0
    _absolute.push_back(OwningAtomPtr<AbsoluteAtom>(&a));
62
0
  }
63
64
930
  void addAtom(const Atom &atom) {
65
930
    if (auto *
p930
= dyn_cast<DefinedAtom>(&atom)) {
66
748
      addAtom(const_cast<DefinedAtom &>(*p));
67
930
    } else 
if (auto *182
p182
= dyn_cast<UndefinedAtom>(&atom)) {
68
44
      addAtom(const_cast<UndefinedAtom &>(*p));
69
182
    } else 
if (auto *138
p138
= dyn_cast<SharedLibraryAtom>(&atom)) {
70
138
      addAtom(const_cast<SharedLibraryAtom &>(*p));
71
138
    } else 
if (auto *0
p0
= dyn_cast<AbsoluteAtom>(&atom)) {
72
0
      addAtom(const_cast<AbsoluteAtom &>(*p));
73
0
    } else {
74
0
      llvm_unreachable("atom has unknown definition kind");
75
182
    }
76
930
  }
77
78
20
  void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {
79
20
    auto &atoms = _defined;
80
20
    auto newEnd = std::remove_if(atoms.begin(), atoms.end(),
81
245
                                 [&pred](OwningAtomPtr<DefinedAtom> &p) {
82
245
                                   return pred(p.get());
83
245
                                 });
84
20
    atoms.erase(newEnd, atoms.end());
85
20
  }
86
87
1.48k
  const AtomRange<DefinedAtom> defined() const override { return _defined; }
88
89
673
  const AtomRange<UndefinedAtom> undefined() const override {
90
673
    return _undefined;
91
673
  }
92
93
706
  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
94
706
    return _shared;
95
706
  }
96
97
506
  const AtomRange<AbsoluteAtom> absolute() const override {
98
506
    return _absolute;
99
506
  }
100
101
925
  void clearAtoms() override {
102
925
    _defined.clear();
103
925
    _undefined.clear();
104
925
    _shared.clear();
105
925
    _absolute.clear();
106
925
  }
107
108
private:
109
  AtomVector<DefinedAtom> _defined;
110
  AtomVector<UndefinedAtom> _undefined;
111
  AtomVector<SharedLibraryAtom> _shared;
112
  AtomVector<AbsoluteAtom> _absolute;
113
};
114
115
class SimpleReference : public Reference,
116
                        public llvm::ilist_node<SimpleReference> {
117
public:
118
  SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch,
119
                  Reference::KindValue value, uint64_t off, const Atom *t,
120
                  Reference::Addend a)
121
870
      : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) {
122
870
  }
123
  SimpleReference()
124
      : Reference(Reference::KindNamespace::all, Reference::KindArch::all, 0),
125
0
        _target(nullptr), _offsetInAtom(0), _addend(0) {}
126
127
4.89k
  uint64_t offsetInAtom() const override { return _offsetInAtom; }
128
129
5.17k
  const Atom *target() const override {
130
5.17k
    assert(_target);
131
5.17k
    return _target;
132
5.17k
  }
133
134
1.42k
  Addend addend() const override { return _addend; }
135
0
  void setAddend(Addend a) override { _addend = a; }
136
637
  void setTarget(const Atom *newAtom) override { _target = newAtom; }
137
138
private:
139
  const Atom *_target;
140
  uint64_t _offsetInAtom;
141
  Addend _addend;
142
};
143
144
class SimpleDefinedAtom : public DefinedAtom {
145
public:
146
  explicit SimpleDefinedAtom(const File &f)
147
855
      : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {}
148
149
855
  ~SimpleDefinedAtom() override {
150
855
    _references.clearAndLeakNodesUnsafely();
151
855
  }
152
153
2.60k
  const File &file() const override { return _file; }
154
155
231
  StringRef name() const override { return StringRef(); }
156
157
488
  uint64_t ordinal() const override { return _ordinal; }
158
159
156
  Scope scope() const override { return DefinedAtom::scopeLinkageUnit; }
160
161
293
  Interposable interposable() const override {
162
293
    return DefinedAtom::interposeNo;
163
293
  }
164
165
8
  Merge merge() const override { return DefinedAtom::mergeNo; }
166
167
2
  Alignment alignment() const override { return 1; }
168
169
930
  SectionChoice sectionChoice() const override {
170
930
    return DefinedAtom::sectionBasedOnContent;
171
930
  }
172
173
252
  StringRef customSectionName() const override { return StringRef(); }
174
16
  DeadStripKind deadStrip() const override {
175
16
    return DefinedAtom::deadStripNormal;
176
16
  }
177
178
5.77k
  DefinedAtom::reference_iterator begin() const override {
179
5.77k
    const void *it =
180
5.77k
        reinterpret_cast<const void *>(_references.begin().getNodePtr());
181
5.77k
    return reference_iterator(*this, it);
182
5.77k
  }
183
184
5.81k
  DefinedAtom::reference_iterator end() const override {
185
5.81k
    const void *it =
186
5.81k
        reinterpret_cast<const void *>(_references.end().getNodePtr());
187
5.81k
    return reference_iterator(*this, it);
188
5.81k
  }
189
190
6.00k
  const Reference *derefIterator(const void *it) const override {
191
6.00k
    return &*RefList::const_iterator(
192
6.00k
        *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
193
6.00k
  }
194
195
5.62k
  void incrementIterator(const void *&it) const override {
196
5.62k
    RefList::const_iterator ref(
197
5.62k
        *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
198
5.62k
    it = reinterpret_cast<const void *>(std::next(ref).getNodePtr());
199
5.62k
  }
200
201
  void addReference(Reference::KindNamespace ns,
202
                    Reference::KindArch arch,
203
                    Reference::KindValue kindValue, uint64_t off,
204
870
                    const Atom *target, Reference::Addend a) override {
205
870
    assert(target && "trying to create reference to nothing");
206
870
    auto node = new (_file.allocator())
207
870
        SimpleReference(ns, arch, kindValue, off, target, a);
208
870
    _references.push_back(node);
209
870
  }
210
211
  /// Sort references in a canonical order (by offset, then by kind).
212
500
  void sortReferences() const {
213
500
    // Cannot sort a linked  list, so move elements into a temporary vector,
214
500
    // sort the vector, then reconstruct the list.
215
500
    llvm::SmallVector<SimpleReference *, 16> elements;
216
600
    for (SimpleReference &node : _references) {
217
600
      elements.push_back(&node);
218
600
    }
219
500
    std::sort(elements.begin(), elements.end(),
220
1.21k
        [] (const SimpleReference *lhs, const SimpleReference *rhs) -> bool {
221
1.21k
          uint64_t lhsOffset = lhs->offsetInAtom();
222
1.21k
          uint64_t rhsOffset = rhs->offsetInAtom();
223
1.21k
          if (rhsOffset != lhsOffset)
224
1.20k
            return (lhsOffset < rhsOffset);
225
6
          
if (6
rhs->kindNamespace() != lhs->kindNamespace()6
)
226
0
            return (lhs->kindNamespace() < rhs->kindNamespace());
227
6
          
if (6
rhs->kindArch() != lhs->kindArch()6
)
228
0
            return (lhs->kindArch() < rhs->kindArch());
229
6
          return (lhs->kindValue() < rhs->kindValue());
230
1.21k
        });
231
500
    _references.clearAndLeakNodesUnsafely();
232
600
    for (SimpleReference *node : elements) {
233
600
      _references.push_back(node);
234
600
    }
235
500
  }
236
237
0
  void setOrdinal(uint64_t ord) { _ordinal = ord; }
238
239
private:
240
  typedef llvm::ilist<SimpleReference> RefList;
241
242
  const File &_file;
243
  uint64_t _ordinal;
244
  mutable RefList _references;
245
};
246
247
class SimpleUndefinedAtom : public UndefinedAtom {
248
public:
249
331
  SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) {
250
331
    assert(!name.empty() && "UndefinedAtoms must have a name");
251
331
  }
252
253
486
  ~SimpleUndefinedAtom() override = default;
254
255
  /// file - returns the File that produced/owns this Atom
256
58
  const File &file() const override { return _file; }
257
258
  /// name - The name of the atom. For a function atom, it is the (mangled)
259
  /// name of the function.
260
1.08k
  StringRef name() const override { return _name; }
261
262
200
  CanBeNull canBeNull() const override { return UndefinedAtom::canBeNullNever; }
263
264
private:
265
  const File &_file;
266
  StringRef _name;
267
};
268
269
} // end namespace lld
270
271
#endif // LLD_CORE_SIMPLE_H