Coverage Report

Created: 2018-07-22 10:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/CodeGen/ConstantInitBuilder.h
Line
Count
Source (jump to first uncovered line)
1
//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This class provides a convenient interface for building complex
11
// global initializers of the sort that are frequently required for
12
// language ABIs.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
17
#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
18
19
#include "llvm/ADT/ArrayRef.h"
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/IR/Constants.h"
22
#include "llvm/IR/GlobalValue.h"
23
#include "clang/AST/CharUnits.h"
24
#include "clang/CodeGen/ConstantInitFuture.h"
25
26
#include <vector>
27
28
namespace clang {
29
namespace CodeGen {
30
31
class CodeGenModule;
32
33
/// A convenience builder class for complex constant initializers,
34
/// especially for anonymous global structures used by various language
35
/// runtimes.
36
///
37
/// The basic usage pattern is expected to be something like:
38
///    ConstantInitBuilder builder(CGM);
39
///    auto toplevel = builder.beginStruct();
40
///    toplevel.addInt(CGM.SizeTy, widgets.size());
41
///    auto widgetArray = builder.beginArray();
42
///    for (auto &widget : widgets) {
43
///      auto widgetDesc = widgetArray.beginStruct();
44
///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
45
///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
46
///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
47
///      widgetDesc.finishAndAddTo(widgetArray);
48
///    }
49
///    widgetArray.finishAndAddTo(toplevel);
50
///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
51
///                                                 /*constant*/ true);
52
class ConstantInitBuilderBase {
53
  struct SelfReference {
54
    llvm::GlobalVariable *Dummy;
55
    llvm::SmallVector<llvm::Constant*, 4> Indices;
56
57
0
    SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
58
  };
59
  CodeGenModule &CGM;
60
  llvm::SmallVector<llvm::Constant*, 16> Buffer;
61
  std::vector<SelfReference> SelfReferences;
62
  bool Frozen = false;
63
64
  friend class ConstantInitFuture;
65
  friend class ConstantAggregateBuilderBase;
66
  template <class, class>
67
  friend class ConstantAggregateBuilderTemplateBase;
68
69
protected:
70
33.5k
  explicit ConstantInitBuilderBase(CodeGenModule &CGM) : CGM(CGM) {}
71
72
33.5k
  ~ConstantInitBuilderBase() {
73
33.5k
    assert(Buffer.empty() && "didn't claim all values out of buffer");
74
33.5k
    assert(SelfReferences.empty() && "didn't apply all self-references");
75
33.5k
  }
76
77
private:
78
  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
79
                                     const llvm::Twine &name,
80
                                     CharUnits alignment,
81
                                     bool constant = false,
82
                                     llvm::GlobalValue::LinkageTypes linkage
83
                                       = llvm::GlobalValue::InternalLinkage,
84
                                     unsigned addressSpace = 0);
85
86
  ConstantInitFuture createFuture(llvm::Constant *initializer);
87
88
  void setGlobalInitializer(llvm::GlobalVariable *GV,
89
                            llvm::Constant *initializer);
90
91
  void resolveSelfReferences(llvm::GlobalVariable *GV);
92
93
  void abandon(size_t newEnd);
94
};
95
96
/// A concrete base class for struct and array aggregate
97
/// initializer builders.
98
class ConstantAggregateBuilderBase {
99
protected:
100
  ConstantInitBuilderBase &Builder;
101
  ConstantAggregateBuilderBase *Parent;
102
  size_t Begin;
103
  mutable size_t CachedOffsetEnd = 0;
104
  bool Finished = false;
105
  bool Frozen = false;
106
  bool Packed = false;
107
  mutable CharUnits CachedOffsetFromGlobal;
108
109
36.1k
  llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
110
36.1k
    return Builder.Buffer;
111
36.1k
  }
112
113
918
  const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
114
918
    return Builder.Buffer;
115
918
  }
116
117
  ConstantAggregateBuilderBase(ConstantInitBuilderBase &builder,
118
                               ConstantAggregateBuilderBase *parent)
119
36.6k
      : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
120
36.6k
    if (parent) {
121
13.5k
      assert(!parent->Frozen && "parent already has child builder active");
122
13.5k
      parent->Frozen = true;
123
23.1k
    } else {
124
23.1k
      assert(!builder.Frozen && "builder already has child builder active");
125
23.1k
      builder.Frozen = true;
126
23.1k
    }
127
36.6k
  }
128
129
36.6k
  ~ConstantAggregateBuilderBase() {
130
36.6k
    assert(Finished && "didn't finish aggregate builder");
131
36.6k
  }
132
133
36.6k
  void markFinished() {
134
36.6k
    assert(!Frozen && "child builder still active");
135
36.6k
    assert(!Finished && "builder already finished");
136
36.6k
    Finished = true;
137
36.6k
    if (Parent) {
138
13.5k
      assert(Parent->Frozen &&
139
13.5k
             "parent not frozen while child builder active");
140
13.5k
      Parent->Frozen = false;
141
23.1k
    } else {
142
23.1k
      assert(Builder.Frozen &&
143
23.1k
             "builder not frozen while child builder active");
144
23.1k
      Builder.Frozen = false;
145
23.1k
    }
146
36.6k
  }
147
148
public:
149
  // Not copyable.
150
  ConstantAggregateBuilderBase(const ConstantAggregateBuilderBase &) = delete;
151
  ConstantAggregateBuilderBase &operator=(const ConstantAggregateBuilderBase &)
152
    = delete;
153
154
  // Movable, mostly to allow returning.  But we have to write this out
155
  // properly to satisfy the assert in the destructor.
156
  ConstantAggregateBuilderBase(ConstantAggregateBuilderBase &&other)
157
    : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
158
      CachedOffsetEnd(other.CachedOffsetEnd),
159
      Finished(other.Finished), Frozen(other.Frozen), Packed(other.Packed),
160
      CachedOffsetFromGlobal(other.CachedOffsetFromGlobal) {
161
    other.Finished = true;
162
  }
163
  ConstantAggregateBuilderBase &operator=(ConstantAggregateBuilderBase &&other)
164
    = delete;
165
166
  /// Return the number of elements that have been added to
167
  /// this struct or array.
168
918
  size_t size() const {
169
918
    assert(!this->Finished && "cannot query after finishing builder");
170
918
    assert(!this->Frozen && "cannot query while sub-builder is active");
171
918
    assert(this->Begin <= this->getBuffer().size());
172
918
    return this->getBuffer().size() - this->Begin;
173
918
  }
174
175
  /// Return true if no elements have yet been added to this struct or array.
176
467
  bool empty() const {
177
467
    return size() == 0;
178
467
  }
179
180
  /// Abandon this builder completely.
181
542
  void abandon() {
182
542
    markFinished();
183
542
    Builder.abandon(Begin);
184
542
  }
185
186
  /// Add a new value to this initializer.
187
142k
  void add(llvm::Constant *value) {
188
142k
    assert(value && "adding null value to constant initializer");
189
142k
    assert(!Finished && "cannot add more values after finishing builder");
190
142k
    assert(!Frozen && "cannot add values while subbuilder is active");
191
142k
    Builder.Buffer.push_back(value);
192
142k
  }
193
194
  /// Add an integer value of type size_t.
195
  void addSize(CharUnits size);
196
197
  /// Add an integer value of a specific type.
198
  void addInt(llvm::IntegerType *intTy, uint64_t value,
199
13.7k
              bool isSigned = false) {
200
13.7k
    add(llvm::ConstantInt::get(intTy, value, isSigned));
201
13.7k
  }
202
203
  /// Add a null pointer of a specific type.
204
4.00k
  void addNullPointer(llvm::PointerType *ptrTy) {
205
4.00k
    add(llvm::ConstantPointerNull::get(ptrTy));
206
4.00k
  }
207
208
  /// Add a bitcast of a value to a specific type.
209
3.18k
  void addBitCast(llvm::Constant *value, llvm::Type *type) {
210
3.18k
    add(llvm::ConstantExpr::getBitCast(value, type));
211
3.18k
  }
212
213
  /// Add a bunch of new values to this initializer.
214
93
  void addAll(llvm::ArrayRef<llvm::Constant *> values) {
215
93
    assert(!Finished && "cannot add more values after finishing builder");
216
93
    assert(!Frozen && "cannot add values while subbuilder is active");
217
93
    Builder.Buffer.append(values.begin(), values.end());
218
93
  }
219
220
  /// Add a relative offset to the given target address, i.e. the
221
  /// static difference between the target address and the address
222
  /// of the relative offset.  The target must be known to be defined
223
  /// in the current linkage unit.  The offset will have the given
224
  /// integer type, which must be no wider than intptr_t.  Some
225
  /// targets may not fully support this operation.
226
  void addRelativeOffset(llvm::IntegerType *type, llvm::Constant *target) {
227
    add(getRelativeOffset(type, target));
228
  }
229
230
  /// Add a relative offset to the target address, plus a small
231
  /// constant offset.  This is primarily useful when the relative
232
  /// offset is known to be a multiple of (say) four and therefore
233
  /// the tag can be used to express an extra two bits of information.
234
  void addTaggedRelativeOffset(llvm::IntegerType *type,
235
                               llvm::Constant *address,
236
                               unsigned tag) {
237
    llvm::Constant *offset = getRelativeOffset(type, address);
238
    if (tag) {
239
      offset = llvm::ConstantExpr::getAdd(offset,
240
                                          llvm::ConstantInt::get(type, tag));
241
    }
242
    add(offset);
243
  }
244
245
  /// Return the offset from the start of the initializer to the
246
  /// next position, assuming no padding is required prior to it.
247
  ///
248
  /// This operation will not succeed if any unsized placeholders are
249
  /// currently in place in the initializer.
250
0
  CharUnits getNextOffsetFromGlobal() const {
251
0
    assert(!Finished && "cannot add more values after finishing builder");
252
0
    assert(!Frozen && "cannot add values while subbuilder is active");
253
0
    return getOffsetFromGlobalTo(Builder.Buffer.size());
254
0
  }
255
256
  /// An opaque class to hold the abstract position of a placeholder.
257
  class PlaceholderPosition {
258
    size_t Index;
259
    friend class ConstantAggregateBuilderBase;
260
631
    PlaceholderPosition(size_t index) : Index(index) {}
261
  };
262
263
  /// Add a placeholder value to the structure.  The returned position
264
  /// can be used to set the value later; it will not be invalidated by
265
  /// any intermediate operations except (1) filling the same position or
266
  /// (2) finishing the entire builder.
267
  ///
268
  /// This is useful for emitting certain kinds of structure which
269
  /// contain some sort of summary field, generally a count, before any
270
  /// of the data.  By emitting a placeholder first, the structure can
271
  /// be emitted eagerly.
272
631
  PlaceholderPosition addPlaceholder() {
273
631
    assert(!Finished && "cannot add more values after finishing builder");
274
631
    assert(!Frozen && "cannot add values while subbuilder is active");
275
631
    Builder.Buffer.push_back(nullptr);
276
631
    return Builder.Buffer.size() - 1;
277
631
  }
278
279
  /// Add a placeholder, giving the expected type that will be filled in.
280
  PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType);
281
282
  /// Fill a previously-added placeholder.
283
  void fillPlaceholderWithInt(PlaceholderPosition position,
284
                              llvm::IntegerType *type, uint64_t value,
285
360
                              bool isSigned = false) {
286
360
    fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
287
360
  }
288
289
  /// Fill a previously-added placeholder.
290
360
  void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
291
360
    assert(!Finished && "cannot change values after finishing builder");
292
360
    assert(!Frozen && "cannot add values while subbuilder is active");
293
360
    llvm::Constant *&slot = Builder.Buffer[position.Index];
294
360
    assert(slot == nullptr && "placeholder already filled");
295
360
    slot = value;
296
360
  }
297
298
  /// Produce an address which will eventually point to the next
299
  /// position to be filled.  This is computed with an indexed
300
  /// getelementptr rather than by computing offsets.
301
  ///
302
  /// The returned pointer will have type T*, where T is the given
303
  /// position.
304
  llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
305
306
  llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
307
0
                           llvm::SmallVectorImpl<llvm::Constant*> &indices) {
308
0
    getGEPIndicesTo(indices, Builder.Buffer.size());
309
0
    return indices;
310
0
  }
311
312
protected:
313
  llvm::Constant *finishArray(llvm::Type *eltTy);
314
  llvm::Constant *finishStruct(llvm::StructType *structTy);
315
316
private:
317
  void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
318
                       size_t position) const;
319
320
  llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
321
                                    llvm::Constant *target);
322
323
  CharUnits getOffsetFromGlobalTo(size_t index) const;
324
};
325
326
template <class Impl, class Traits>
327
class ConstantAggregateBuilderTemplateBase
328
    : public Traits::AggregateBuilderBase {
329
  using super = typename Traits::AggregateBuilderBase;
330
public:
331
  using InitBuilder = typename Traits::InitBuilder;
332
  using ArrayBuilder = typename Traits::ArrayBuilder;
333
  using StructBuilder = typename Traits::StructBuilder;
334
  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
335
336
protected:
337
  ConstantAggregateBuilderTemplateBase(InitBuilder &builder,
338
                                       AggregateBuilderBase *parent)
339
36.6k
    : super(builder, parent) {}
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::ConstantAggregateBuilderTemplateBase(clang::CodeGen::ConstantInitBuilder&, clang::CodeGen::ConstantAggregateBuilderBase*)
Line
Count
Source
339
26.2k
    : super(builder, parent) {}
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::ConstantAggregateBuilderTemplateBase(clang::CodeGen::ConstantInitBuilder&, clang::CodeGen::ConstantAggregateBuilderBase*)
Line
Count
Source
339
10.4k
    : super(builder, parent) {}
340
341
36.1k
  Impl &asImpl() { return *static_cast<Impl*>(this); }
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::asImpl()
Line
Count
Source
341
25.9k
  Impl &asImpl() { return *static_cast<Impl*>(this); }
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::asImpl()
Line
Count
Source
341
10.1k
  Impl &asImpl() { return *static_cast<Impl*>(this); }
342
343
public:
344
7.23k
  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
345
7.23k
    return ArrayBuilder(static_cast<InitBuilder&>(this->Builder), this, eltTy);
346
7.23k
  }
347
348
6.27k
  StructBuilder beginStruct(llvm::StructType *ty = nullptr) {
349
6.27k
    return StructBuilder(static_cast<InitBuilder&>(this->Builder), this, ty);
350
6.27k
  }
351
352
  /// Given that this builder was created by beginning an array or struct
353
  /// component on the given parent builder, finish the array/struct
354
  /// component and add it to the parent.
355
  ///
356
  /// It is an intentional choice that the parent is passed in explicitly
357
  /// despite it being redundant with information already kept in the
358
  /// builder.  This aids in readability by making it easier to find the
359
  /// places that add components to a builder, as well as "bookending"
360
  /// the sub-builder more explicitly.
361
13.2k
  void finishAndAddTo(AggregateBuilderBase &parent) {
362
13.2k
    assert(this->Parent == &parent && "adding to non-parent builder");
363
13.2k
    parent.add(asImpl().finishImpl());
364
13.2k
  }
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndAddTo(clang::CodeGen::ConstantAggregateBuilderBase&)
Line
Count
Source
361
6.27k
  void finishAndAddTo(AggregateBuilderBase &parent) {
362
6.27k
    assert(this->Parent == &parent && "adding to non-parent builder");
363
6.27k
    parent.add(asImpl().finishImpl());
364
6.27k
  }
clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndAddTo(clang::CodeGen::ConstantAggregateBuilderBase&)
Line
Count
Source
361
6.96k
  void finishAndAddTo(AggregateBuilderBase &parent) {
362
6.96k
    assert(this->Parent == &parent && "adding to non-parent builder");
363
6.96k
    parent.add(asImpl().finishImpl());
364
6.96k
  }
365
366
  /// Given that this builder was created by beginning an array or struct
367
  /// directly on a ConstantInitBuilder, finish the array/struct and
368
  /// create a global variable with it as the initializer.
369
  template <class... As>
370
17.1k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
17.1k
    assert(!this->Parent && "finishing non-root builder");
372
17.1k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
17.1k
                                      std::forward<As>(args)...);
374
17.1k
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [23], clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes, unsigned int&>(char const (&&&) [23], clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&, unsigned int&&&)
Line
Count
Source
370
1.01k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
1.01k
    assert(!this->Parent && "finishing non-root builder");
372
1.01k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
1.01k
                                      std::forward<As>(args)...);
374
1.01k
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [23], clang::CharUnits const&, bool, llvm::GlobalValue::LinkageTypes, unsigned int&>(char const (&&&) [23], clang::CharUnits const&&&, bool&&, llvm::GlobalValue::LinkageTypes&&, unsigned int&&&)
Line
Count
Source
370
252
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
252
    assert(!this->Parent && "finishing non-root builder");
372
252
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
252
                                      std::forward<As>(args)...);
374
252
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::CharUnits, bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, clang::CharUnits&&, bool&&)
Line
Count
Source
370
8
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
8
    assert(!this->Parent && "finishing non-root builder");
372
8
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
8
                                      std::forward<As>(args)...);
374
8
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [18], clang::CharUnits>(char const (&&&) [18], clang::CharUnits&&)
Line
Count
Source
370
25
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
25
    assert(!this->Parent && "finishing non-root builder");
372
25
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
25
                                      std::forward<As>(args)...);
374
25
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [20], clang::CharUnits>(char const (&&&) [20], clang::CharUnits&&)
Line
Count
Source
370
80
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
80
    assert(!this->Parent && "finishing non-root builder");
372
80
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
80
                                      std::forward<As>(args)...);
374
80
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [1], clang::CharUnits>(char const (&&&) [1], clang::CharUnits&&)
Line
Count
Source
370
135
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
135
    assert(!this->Parent && "finishing non-root builder");
372
135
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
135
                                      std::forward<As>(args)...);
374
135
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [14], clang::CharUnits>(char const (&&&) [14], clang::CharUnits&&)
Line
Count
Source
370
3
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
3
    assert(!this->Parent && "finishing non-root builder");
372
3
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
3
                                      std::forward<As>(args)...);
374
3
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [18], clang::CharUnits>(char const (&&&) [18], clang::CharUnits&&)
Line
Count
Source
370
3
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
3
    assert(!this->Parent && "finishing non-root builder");
372
3
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
3
                                      std::forward<As>(args)...);
374
3
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [20], clang::CharUnits>(char const (&&&) [20], clang::CharUnits&&)
Line
Count
Source
370
45
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
45
    assert(!this->Parent && "finishing non-root builder");
372
45
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
45
                                      std::forward<As>(args)...);
374
45
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [10], clang::CharUnits&>(char const (&&&) [10], clang::CharUnits&&&)
Line
Count
Source
370
7
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
7
    assert(!this->Parent && "finishing non-root builder");
372
7
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
7
                                      std::forward<As>(args)...);
374
7
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [14], clang::CharUnits>(char const (&&&) [14], clang::CharUnits&&)
Line
Count
Source
370
18
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
18
    assert(!this->Parent && "finishing non-root builder");
372
18
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
18
                                      std::forward<As>(args)...);
374
18
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
174
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
174
    assert(!this->Parent && "finishing non-root builder");
372
174
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
174
                                      std::forward<As>(args)...);
374
174
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [15], clang::CharUnits>(char const (&&&) [15], clang::CharUnits&&)
Line
Count
Source
370
3
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
3
    assert(!this->Parent && "finishing non-root builder");
372
3
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
3
                                      std::forward<As>(args)...);
374
3
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [16], clang::CharUnits>(char const (&&&) [16], clang::CharUnits&&)
Line
Count
Source
370
12
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
12
    assert(!this->Parent && "finishing non-root builder");
372
12
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
12
                                      std::forward<As>(args)...);
374
12
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::CharUnits>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, clang::CharUnits&&)
Line
Count
Source
370
7
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
7
    assert(!this->Parent && "finishing non-root builder");
372
7
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
7
                                      std::forward<As>(args)...);
374
7
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [11], clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(char const (&&&) [11], clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
6
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
6
    assert(!this->Parent && "finishing non-root builder");
372
6
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
6
                                      std::forward<As>(args)...);
374
6
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::StringRef&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::StringRef&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
38
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
38
    assert(!this->Parent && "finishing non-root builder");
372
38
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
38
                                      std::forward<As>(args)...);
374
38
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
3
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
3
    assert(!this->Parent && "finishing non-root builder");
372
3
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
3
                                      std::forward<As>(args)...);
374
3
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::StringRef, clang::CharUnits&, bool, llvm::GlobalValue::LinkageTypes>(llvm::StringRef&&, clang::CharUnits&&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
2
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
2
    assert(!this->Parent && "finishing non-root builder");
372
2
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
2
                                      std::forward<As>(args)...);
374
2
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [16], clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(char const (&&&) [16], clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
2
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
2
    assert(!this->Parent && "finishing non-root builder");
372
2
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
2
                                      std::forward<As>(args)...);
374
2
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [20], clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(char const (&&&) [20], clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
1
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
1
    assert(!this->Parent && "finishing non-root builder");
372
1
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
1
                                      std::forward<As>(args)...);
374
1
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [27], clang::CharUnits>(char const (&&&) [27], clang::CharUnits&&)
Line
Count
Source
370
4
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
4
    assert(!this->Parent && "finishing non-root builder");
372
4
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
4
                                      std::forward<As>(args)...);
374
4
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine&, clang::CharUnits&, bool, llvm::GlobalValue::LinkageTypes>(llvm::Twine&&&, clang::CharUnits&&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
749
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
749
    assert(!this->Parent && "finishing non-root builder");
372
749
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
749
                                      std::forward<As>(args)...);
374
749
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const (&) [19], clang::CharUnits&, bool, llvm::GlobalValue::LinkageTypes>(char const (&&&) [19], clang::CharUnits&&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
270
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
270
    assert(!this->Parent && "finishing non-root builder");
372
270
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
270
                                      std::forward<As>(args)...);
374
270
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::Twine&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
745
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
745
    assert(!this->Parent && "finishing non-root builder");
372
745
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
745
                                      std::forward<As>(args)...);
374
745
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes&>(llvm::Twine&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&&)
Line
Count
Source
370
39
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
39
    assert(!this->Parent && "finishing non-root builder");
372
39
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
39
                                      std::forward<As>(args)...);
374
39
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::Twine&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
44
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
44
    assert(!this->Parent && "finishing non-root builder");
372
44
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
44
                                      std::forward<As>(args)...);
374
44
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::StringRef, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::StringRef&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
50
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
50
    assert(!this->Parent && "finishing non-root builder");
372
50
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
50
                                      std::forward<As>(args)...);
374
50
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::SmallString<64u>&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::SmallString<64u>&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
988
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
988
    assert(!this->Parent && "finishing non-root builder");
372
988
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
988
                                      std::forward<As>(args)...);
374
988
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine const&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(llvm::Twine const&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
8.17k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
8.17k
    assert(!this->Parent && "finishing non-root builder");
372
8.17k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
8.17k
                                      std::forward<As>(args)...);
374
8.17k
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, clang::CharUnits, bool>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&&, clang::CharUnits&&, bool&&)
Line
Count
Source
370
1.09k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
1.09k
    assert(!this->Parent && "finishing non-root builder");
372
1.09k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
1.09k
                                      std::forward<As>(args)...);
374
1.09k
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantStructBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<llvm::Twine const&, clang::CharUnits, bool>(llvm::Twine const&&&, clang::CharUnits&&, bool&&)
Line
Count
Source
370
1.09k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
1.09k
    assert(!this->Parent && "finishing non-root builder");
372
1.09k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
1.09k
                                      std::forward<As>(args)...);
374
1.09k
  }
llvm::GlobalVariable* clang::CodeGen::ConstantAggregateBuilderTemplateBase<clang::CodeGen::ConstantArrayBuilder, clang::CodeGen::ConstantInitBuilderTraits>::finishAndCreateGlobal<char const*&, clang::CharUnits, bool, llvm::GlobalValue::LinkageTypes>(char const*&&&, clang::CharUnits&&, bool&&, llvm::GlobalValue::LinkageTypes&&)
Line
Count
Source
370
2.06k
  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
371
2.06k
    assert(!this->Parent && "finishing non-root builder");
372
2.06k
    return this->Builder.createGlobal(asImpl().finishImpl(),
373
2.06k
                                      std::forward<As>(args)...);
374
2.06k
  }
375
376
  /// Given that this builder was created by beginning an array or struct
377
  /// directly on a ConstantInitBuilder, finish the array/struct and
378
  /// set it as the initializer of the given global variable.
379
5.74k
  void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
380
5.74k
    assert(!this->Parent && "finishing non-root builder");
381
5.74k
    return this->Builder.setGlobalInitializer(global, asImpl().finishImpl());
382
5.74k
  }
383
384
  /// Given that this builder was created by beginning an array or struct
385
  /// directly on a ConstantInitBuilder, finish the array/struct and
386
  /// return a future which can be used to install the initializer in
387
  /// a global later.
388
  ///
389
  /// This is useful for allowing a finished initializer to passed to
390
  /// an API which will build the global.  However, the "future" preserves
391
  /// a dependency on the original builder; it is an error to pass it aside.
392
  ConstantInitFuture finishAndCreateFuture() {
393
    assert(!this->Parent && "finishing non-root builder");
394
    return this->Builder.createFuture(asImpl().finishImpl());
395
  }
396
};
397
398
template <class Traits>
399
class ConstantArrayBuilderTemplateBase
400
  : public ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder,
401
                                                Traits> {
402
  using super =
403
    ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder, Traits>;
404
405
public:
406
  using InitBuilder = typename Traits::InitBuilder;
407
  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
408
409
private:
410
  llvm::Type *EltTy;
411
412
  template <class, class>
413
  friend class ConstantAggregateBuilderTemplateBase;
414
415
protected:
416
  ConstantArrayBuilderTemplateBase(InitBuilder &builder,
417
                                   AggregateBuilderBase *parent,
418
                                   llvm::Type *eltTy)
419
10.4k
    : super(builder, parent), EltTy(eltTy) {}
420
421
private:
422
  /// Form an array constant from the values that have been added to this
423
  /// builder.
424
10.1k
  llvm::Constant *finishImpl() {
425
10.1k
    return AggregateBuilderBase::finishArray(EltTy);
426
10.1k
  }
427
};
428
429
/// A template class designed to allow other frontends to
430
/// easily customize the builder classes used by ConstantInitBuilder,
431
/// and thus to extend the API to work with the abstractions they
432
/// prefer.  This would probably not be necessary if C++ just
433
/// supported extension methods.
434
template <class Traits>
435
class ConstantStructBuilderTemplateBase
436
  : public ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,
437
                                                Traits> {
438
  using super =
439
    ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,Traits>;
440
441
public:
442
  using InitBuilder = typename Traits::InitBuilder;
443
  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
444
445
private:
446
  llvm::StructType *StructTy;
447
448
  template <class, class>
449
  friend class ConstantAggregateBuilderTemplateBase;
450
451
protected:
452
  ConstantStructBuilderTemplateBase(InitBuilder &builder,
453
                                    AggregateBuilderBase *parent,
454
                                    llvm::StructType *structTy)
455
26.2k
    : super(builder, parent), StructTy(structTy) {
456
26.2k
    if (structTy) 
this->Packed = structTy->isPacked()18.3k
;
457
26.2k
  }
458
459
public:
460
  void setPacked(bool packed) {
461
    this->Packed = packed;
462
  }
463
464
  /// Use the given type for the struct if its element count is correct.
465
  /// Don't add more elements after calling this.
466
  void suggestType(llvm::StructType *structTy) {
467
    if (this->size() == structTy->getNumElements()) {
468
      StructTy = structTy;
469
    }
470
  }
471
472
private:
473
  /// Form an array constant from the values that have been added to this
474
  /// builder.
475
25.9k
  llvm::Constant *finishImpl() {
476
25.9k
    return AggregateBuilderBase::finishStruct(StructTy);
477
25.9k
  }
478
};
479
480
/// A template class designed to allow other frontends to
481
/// easily customize the builder classes used by ConstantInitBuilder,
482
/// and thus to extend the API to work with the abstractions they
483
/// prefer.  This would probably not be necessary if C++ just
484
/// supported extension methods.
485
template <class Traits>
486
class ConstantInitBuilderTemplateBase : public ConstantInitBuilderBase {
487
protected:
488
  ConstantInitBuilderTemplateBase(CodeGenModule &CGM)
489
33.5k
    : ConstantInitBuilderBase(CGM) {}
490
491
public:
492
  using InitBuilder = typename Traits::InitBuilder;
493
  using ArrayBuilder = typename Traits::ArrayBuilder;
494
  using StructBuilder = typename Traits::StructBuilder;
495
496
3.22k
  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
497
3.22k
    return ArrayBuilder(static_cast<InitBuilder&>(*this), nullptr, eltTy);
498
3.22k
  }
499
500
19.9k
  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
501
19.9k
    return StructBuilder(static_cast<InitBuilder&>(*this), nullptr, structTy);
502
19.9k
  }
503
};
504
505
class ConstantInitBuilder;
506
class ConstantStructBuilder;
507
class ConstantArrayBuilder;
508
509
struct ConstantInitBuilderTraits {
510
  using InitBuilder = ConstantInitBuilder;
511
  using AggregateBuilderBase = ConstantAggregateBuilderBase;
512
  using ArrayBuilder = ConstantArrayBuilder;
513
  using StructBuilder = ConstantStructBuilder;
514
};
515
516
/// The standard implementation of ConstantInitBuilder used in Clang.
517
class ConstantInitBuilder
518
    : public ConstantInitBuilderTemplateBase<ConstantInitBuilderTraits> {
519
public:
520
  explicit ConstantInitBuilder(CodeGenModule &CGM) :
521
33.5k
    ConstantInitBuilderTemplateBase(CGM) {}
522
};
523
524
/// A helper class of ConstantInitBuilder, used for building constant
525
/// array initializers.
526
class ConstantArrayBuilder
527
    : public ConstantArrayBuilderTemplateBase<ConstantInitBuilderTraits> {
528
  template <class Traits>
529
  friend class ConstantInitBuilderTemplateBase;
530
531
  // The use of explicit qualification is a GCC workaround.
532
  template <class Impl, class Traits>
533
  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
534
535
  ConstantArrayBuilder(ConstantInitBuilder &builder,
536
                       ConstantAggregateBuilderBase *parent,
537
                       llvm::Type *eltTy)
538
10.4k
    : ConstantArrayBuilderTemplateBase(builder, parent, eltTy) {}
539
};
540
541
/// A helper class of ConstantInitBuilder, used for building constant
542
/// struct initializers.
543
class ConstantStructBuilder
544
    : public ConstantStructBuilderTemplateBase<ConstantInitBuilderTraits> {
545
  template <class Traits>
546
  friend class ConstantInitBuilderTemplateBase;
547
548
  // The use of explicit qualification is a GCC workaround.
549
  template <class Impl, class Traits>
550
  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
551
552
  ConstantStructBuilder(ConstantInitBuilder &builder,
553
                        ConstantAggregateBuilderBase *parent,
554
                        llvm::StructType *structTy)
555
26.2k
    : ConstantStructBuilderTemplateBase(builder, parent, structTy) {}
556
};
557
558
}  // end namespace CodeGen
559
}  // end namespace clang
560
561
#endif