Coverage Report

Created: 2019-07-24 05:18

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