]> granicus.if.org Git - clang/commitdiff
ConstantBuilder -> ConstantInitBuilder for clarity, and
authorJohn McCall <rjmccall@apple.com>
Mon, 28 Nov 2016 22:18:27 +0000 (22:18 +0000)
committerJohn McCall <rjmccall@apple.com>
Mon, 28 Nov 2016 22:18:27 +0000 (22:18 +0000)
move the member classes up to top level to allow forward
declarations to name them.  NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288079 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGCUDANV.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGOpenMPRuntime.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/ConstantBuilder.h

index d9e14017470eef3dd30fd07dc7691934dfcd2db1..09911d4b0999e88b28a85f5e77822c531804830a 100644 (file)
@@ -88,7 +88,7 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
   else
     i8p = CGM.VoidPtrTy;
 
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto elements = builder.beginStruct();
 
   // reserved
@@ -1076,7 +1076,7 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
   assert(blockInfo.CanBeGlobal);
 
   // Generate the constants for the block literal initializer.
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto fields = builder.beginStruct();
 
   // isa
index b6344310c1977678524a68e7c14e9876664756ba..83febcb4af8cfe91d319306f84fab6b7537ce077 100644 (file)
@@ -298,7 +298,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
         CGM.getTriple().isMacOSX() ? "__NV_CUDA,__fatbin" : ".nvFatBinSegment";
 
     // Create initialized wrapper structure that points to the loaded GPU binary
-    ConstantBuilder Builder(CGM);
+    ConstantInitBuilder Builder(CGM);
     auto Values = Builder.beginStruct(FatbinWrapperTy);
     // Fatbin wrapper magic.
     Values.addInt(IntTy, 0x466243b1);
index 9a99c6e5306bb1bf84e70b6a1e7dfaec7f06d3c3..1f64b8ae268d02afdec4f79c528b5d2d2ac7cc74 100644 (file)
@@ -222,7 +222,7 @@ protected:
   }
 
   /// Push the property attributes into two structure fields. 
-  void PushPropertyAttributes(ConstantBuilder::StructBuilder &Fields,
+  void PushPropertyAttributes(ConstantStructBuilder &Fields,
       ObjCPropertyDecl *property, bool isSynthesized=true, bool
       isDynamic=true) {
     int attrs = property->getPropertyAttributes();
@@ -1204,7 +1204,7 @@ llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
   llvm::Constant *typeName =
     ExportUniqueString(className, "__objc_eh_typename_");
 
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto fields = builder.beginStruct();
   fields.add(BVtable);
   fields.add(typeName);
@@ -1242,7 +1242,7 @@ ConstantAddress CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
   else if (isa->getType() != PtrToIdTy)
     isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Fields = Builder.beginStruct();
   Fields.add(isa);
   Fields.add(MakeConstantString(Str));
@@ -1524,7 +1524,7 @@ GenerateMethodList(StringRef ClassName,
   if (MethodSels.empty())
     return NULLPtr;
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
 
   auto MethodList = Builder.beginStruct();
   MethodList.addNullPointer(CGM.Int8PtrTy);
@@ -1564,7 +1564,7 @@ GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
   if (IvarNames.empty())
     return NULLPtr;
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
 
   // Structure containing array count followed by array.
   auto IvarList = Builder.beginStruct();
@@ -1639,7 +1639,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
       IntPtrTy,               // weak_pointers
       nullptr);
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct(ClassTy);
 
   // Fill in the structure
@@ -1712,7 +1712,7 @@ GenerateProtocolMethodList(ArrayRef<llvm::Constant *> MethodNames,
   // Get the method structure type.
   llvm::StructType *ObjCMethodDescTy =
     llvm::StructType::get(CGM.getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto MethodList = Builder.beginStruct();
   MethodList.addInt(IntTy, MethodNames.size());
   auto Methods = MethodList.beginArray(ObjCMethodDescTy);
@@ -1731,7 +1731,7 @@ GenerateProtocolMethodList(ArrayRef<llvm::Constant *> MethodNames,
 llvm::Constant *
 CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) {
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto ProtocolList = Builder.beginStruct();
   ProtocolList.add(NULLPtr);
   ProtocolList.addInt(LongTy, Protocols.size());
@@ -1770,7 +1770,7 @@ CGObjCGNU::GenerateEmptyProtocol(const std::string &ProtocolName) {
   llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});
   // Protocols are objects containing lists of the methods implemented and
   // protocols adopted.
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct();
 
   // The isa pointer must be set to a magic number so the runtime knows it's
@@ -1869,13 +1869,13 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
         numReqProperties++;
     }
 
-    ConstantBuilder reqPropertyListBuilder(CGM);
+    ConstantInitBuilder reqPropertyListBuilder(CGM);
     auto reqPropertiesList = reqPropertyListBuilder.beginStruct();
     reqPropertiesList.addInt(IntTy, numReqProperties);
     reqPropertiesList.add(NULLPtr);
     auto reqPropertiesArray = reqPropertiesList.beginArray(propertyMetadataTy);
 
-    ConstantBuilder optPropertyListBuilder(CGM);
+    ConstantInitBuilder optPropertyListBuilder(CGM);
     auto optPropertiesList = optPropertyListBuilder.beginStruct();
     optPropertiesList.addInt(IntTy, numOptProperties);
     optPropertiesList.add(NULLPtr);
@@ -1932,7 +1932,7 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
   // protocols adopted.
   // The isa pointer must be set to a magic number so the runtime knows it's
   // the correct layout.
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct();
   Elements.add(
       llvm::ConstantExpr::getIntToPtr(
@@ -1956,7 +1956,7 @@ void CGObjCGNU::GenerateProtocolHolderCategory() {
   SmallVector<Selector, 1> MethodSels;
   SmallVector<llvm::Constant*, 1> MethodTypes;
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct();
 
   const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_Hack";
@@ -1971,7 +1971,7 @@ void CGObjCGNU::GenerateProtocolHolderCategory() {
           ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));
 
   // Protocol list
-  ConstantBuilder ProtocolListBuilder(CGM);
+  ConstantInitBuilder ProtocolListBuilder(CGM);
   auto ProtocolList = ProtocolListBuilder.beginStruct();
   ProtocolList.add(NULLPtr);
   ProtocolList.addInt(LongTy, ExistingProtocols.size());
@@ -2024,7 +2024,7 @@ llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) {
     values.push_back(llvm::ConstantInt::get(Int32Ty, word));
   }
 
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto fields = builder.beginStruct();
   fields.addInt(Int32Ty, values.size());
   auto array = fields.beginArray();
@@ -2068,7 +2068,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
        E = Protos.end(); I != E; ++I)
     Protocols.push_back((*I)->getNameAsString());
 
-  ConstantBuilder Builder(CGM);
+  ConstantInitBuilder Builder(CGM);
   auto Elements = Builder.beginStruct();
   Elements.add(MakeConstantString(CategoryName));
   Elements.add(MakeConstantString(ClassName));
@@ -2107,7 +2107,7 @@ llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OI
     numProperties++;
   }
 
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto propertyList = builder.beginStruct();
   propertyList.addInt(IntTy, numProperties);
   propertyList.add(NULLPtr);
@@ -2207,7 +2207,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
   SmallVector<llvm::Constant*, 16> IvarTypes;
   SmallVector<llvm::Constant*, 16> IvarOffsets;
 
-  ConstantBuilder IvarOffsetBuilder(CGM);
+  ConstantInitBuilder IvarOffsetBuilder(CGM);
   auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
   SmallVector<bool, 16> WeakIvars;
   SmallVector<bool, 16> StrongIvars;
@@ -2463,7 +2463,7 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
 
   Elements.clear();
   // Pointer to an array of selectors used in this module.
-  ConstantBuilder SelectorBuilder(CGM);
+  ConstantInitBuilder SelectorBuilder(CGM);
   auto Selectors = SelectorBuilder.beginArray(SelStructTy);
   std::vector<llvm::GlobalAlias*> SelectorAliases;
   for (SelectorMap::iterator iter = SelectorTable.begin(),
index 62ac3c28f0f9dc72359c023fa9078bcb98329de4..b88c6b1185c86f5b9a2d37e9d86ee2be89fe92a2 100644 (file)
@@ -908,7 +908,7 @@ Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
           llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
     }
 
-    ConstantBuilder builder(CGM);
+    ConstantInitBuilder builder(CGM);
     auto fields = builder.beginStruct(IdentTy);
     fields.addInt(CGM.Int32Ty, 0);
     fields.addInt(CGM.Int32Ty, Flags);
@@ -2814,7 +2814,7 @@ CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
   // Create all device images
   auto *DeviceImageTy = cast<llvm::StructType>(
       CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
-  ConstantBuilder DeviceImagesBuilder(CGM);
+  ConstantInitBuilder DeviceImagesBuilder(CGM);
   auto DeviceImagesEntries = DeviceImagesBuilder.beginArray(DeviceImageTy);
 
   for (unsigned i = 0; i < Devices.size(); ++i) {
@@ -2849,7 +2849,7 @@ CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
   // Create the target region descriptor.
   auto *BinaryDescriptorTy = cast<llvm::StructType>(
       CGM.getTypes().ConvertTypeForMem(getTgtBinaryDescriptorQTy()));
-  ConstantBuilder DescBuilder(CGM);
+  ConstantInitBuilder DescBuilder(CGM);
   auto DescInit = DescBuilder.beginStruct(BinaryDescriptorTy);
   DescInit.addInt(CGM.Int32Ty, Devices.size());
   DescInit.add(llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
@@ -2913,7 +2913,7 @@ void CGOpenMPRuntime::createOffloadEntry(llvm::Constant *ID,
   auto Align = CharUnits::fromQuantity(1);
 
   // Create the entry struct.
-  ConstantBuilder EntryBuilder(CGM);
+  ConstantInitBuilder EntryBuilder(CGM);
   auto EntryInit = EntryBuilder.beginStruct(TgtOffloadEntryType);
   EntryInit.add(AddrPtr);
   EntryInit.add(StrPtr);
index 44eeaac73d177ed96dabe769c82feddd51f43635..0502709389b4b863fed01c3e7448db14628b6d4d 100644 (file)
@@ -743,7 +743,7 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
       Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy, nullptr);
 
   // Construct the constructor and destructor arrays.
-  ConstantBuilder builder(*this);
+  ConstantInitBuilder builder(*this);
   auto ctors = builder.beginArray(CtorStructTy);
   for (const auto &I : Fns) {
     auto ctor = ctors.beginStruct(CtorStructTy);
@@ -3190,7 +3190,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
 
   auto *STy = cast<llvm::StructType>(getTypes().ConvertType(CFTy));
 
-  ConstantBuilder Builder(*this);
+  ConstantInitBuilder Builder(*this);
   auto Fields = Builder.beginStruct(STy);
 
   // Class pointer.
@@ -3336,7 +3336,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
     NSConstantStringType = cast<llvm::StructType>(getTypes().ConvertType(NSTy));
   }
   
-  ConstantBuilder Builder(*this);
+  ConstantInitBuilder Builder(*this);
   auto Fields = Builder.beginStruct(NSConstantStringType);
   
   // Class pointer.
index 798bf913fd932d51e845d15d5ecea70661a577a9..e6aa34e4f9069de59a51999d314b51b114f4633e 100644 (file)
 namespace clang {
 namespace CodeGen {
 
-class ConstantBuilder;
+class ConstantStructBuilder;
+class ConstantArrayBuilder;
 
 /// A convenience builder class for complex constant initializers,
 /// especially for anonymous global structures used by various language
 /// runtimes.
 ///
 /// The basic usage pattern is expected to be something like:
-///    ConstantBuilder builder(CGM);
+///    ConstantInitBuilder builder(CGM);
 ///    auto toplevel = builder.beginStruct();
 ///    toplevel.addInt(CGM.SizeTy, widgets.size());
 ///    auto widgetArray = builder.beginArray();
@@ -45,30 +46,36 @@ class ConstantBuilder;
 ///    toplevel.add(widgetArray.finish());
 ///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
 ///                                                 /*constant*/ true);
-class ConstantBuilder {
+class ConstantInitBuilder {
   CodeGenModule &CGM;
   llvm::SmallVector<llvm::Constant*, 16> Buffer;
   bool Frozen = false;
 
 public:
-  explicit ConstantBuilder(CodeGenModule &CGM) : CGM(CGM) {}
+  explicit ConstantInitBuilder(CodeGenModule &CGM) : CGM(CGM) {}
 
-  ~ConstantBuilder() {
+  ~ConstantInitBuilder() {
     assert(Buffer.empty() && "didn't claim all values out of buffer");
   }
 
-  class ArrayBuilder;
-  class StructBuilder;
-
   class AggregateBuilder {
   protected:
-    ConstantBuilder &Builder;
+    ConstantInitBuilder &Builder;
     AggregateBuilder *Parent;
     size_t Begin;
     bool Finished = false;
     bool Frozen = false;
 
-    AggregateBuilder(ConstantBuilder &builder, AggregateBuilder *parent)
+    llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
+      return Builder.Buffer;
+    }
+
+    const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
+      return Builder.Buffer;
+    }
+
+    AggregateBuilder(ConstantInitBuilder &builder,
+                     AggregateBuilder *parent)
         : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
       if (parent) {
         assert(!parent->Frozen && "parent already has child builder active");
@@ -136,8 +143,8 @@ public:
       return indices;
     }
 
-    ArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
-    StructBuilder beginStruct(llvm::StructType *structTy = nullptr);
+    ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
+    ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
 
   private:
     void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
@@ -158,84 +165,9 @@ public:
     }
   };
 
-  class ArrayBuilder : public AggregateBuilder {
-    llvm::Type *EltTy;
-    friend class ConstantBuilder;
-    ArrayBuilder(ConstantBuilder &builder, AggregateBuilder *parent,
-                 llvm::Type *eltTy)
-      : AggregateBuilder(builder, parent), EltTy(eltTy) {}
-  public:
-    size_t size() const {
-      assert(!Finished);
-      assert(!Frozen);
-      assert(Begin <= Builder.Buffer.size());
-      return Builder.Buffer.size() - Begin;
-    }
-
-    /// Form an array constant from the values that have been added to this
-    /// builder.
-    llvm::Constant *finish() {
-      markFinished();
-
-      auto &buffer = Builder.Buffer;
-      assert((Begin < buffer.size() ||
-              (Begin == buffer.size() && EltTy))
-             && "didn't add any array elements without element type");
-      auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-      auto eltTy = EltTy ? EltTy : elts[0]->getType();
-      auto type = llvm::ArrayType::get(eltTy, elts.size());
-      auto constant = llvm::ConstantArray::get(type, elts);
-      buffer.erase(buffer.begin() + Begin, buffer.end());
-      return constant;
-    }
-
-    template <class... As>
-    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.createGlobal(finish(), std::forward<As>(args)...);
-    }
-  };
-
-  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
-    return ArrayBuilder(*this, nullptr, eltTy);
-  }
-
-  class StructBuilder : public AggregateBuilder {
-    llvm::StructType *Ty;
-    friend class ConstantBuilder;
-    StructBuilder(ConstantBuilder &builder, AggregateBuilder *parent,
-                  llvm::StructType *ty)
-      : AggregateBuilder(builder, parent), Ty(ty) {}
-  public:
-    /// Finish the struct.
-    llvm::Constant *finish(bool packed = false) {
-      markFinished();
-
-      auto &buffer = Builder.Buffer;
-      assert(Begin < buffer.size() && "didn't add any struct elements?");
-      auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-
-      llvm::Constant *constant;
-      if (Ty) {
-        constant = llvm::ConstantStruct::get(Ty, elts);
-      } else {
-        constant = llvm::ConstantStruct::getAnon(elts, packed);
-      }
-
-      buffer.erase(buffer.begin() + Begin, buffer.end());
-      return constant;
-    }
-
-    template <class... As>
-    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.createGlobal(finish(), std::forward<As>(args)...);
-    }
-  };
+  ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
 
-  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
-    return StructBuilder(*this, nullptr, structTy);
-  }
+  ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
 
   llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
                                      StringRef name,
@@ -258,14 +190,99 @@ public:
   }
 };
 
-inline ConstantBuilder::ArrayBuilder
-ConstantBuilder::AggregateBuilder::beginArray(llvm::Type *eltTy) {
-  return ArrayBuilder(Builder, this, eltTy);
+/// A helper class of ConstantInitBuilder, used for building constant
+/// array initializers.
+class ConstantArrayBuilder : public ConstantInitBuilder::AggregateBuilder {
+  llvm::Type *EltTy;
+  friend class ConstantInitBuilder;
+  ConstantArrayBuilder(ConstantInitBuilder &builder,
+                       AggregateBuilder *parent, llvm::Type *eltTy)
+    : AggregateBuilder(builder, parent), EltTy(eltTy) {}
+public:
+  size_t size() const {
+    assert(!Finished);
+    assert(!Frozen);
+    assert(Begin <= getBuffer().size());
+    return getBuffer().size() - Begin;
+  }
+
+  /// Form an array constant from the values that have been added to this
+  /// builder.
+  llvm::Constant *finish() {
+    markFinished();
+
+    auto &buffer = getBuffer();
+    assert((Begin < buffer.size() ||
+            (Begin == buffer.size() && EltTy))
+           && "didn't add any array elements without element type");
+    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+    auto eltTy = EltTy ? EltTy : elts[0]->getType();
+    auto type = llvm::ArrayType::get(eltTy, elts.size());
+    auto constant = llvm::ConstantArray::get(type, elts);
+    buffer.erase(buffer.begin() + Begin, buffer.end());
+    return constant;
+  }
+
+  template <class... As>
+  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
+    assert(!Parent && "finishing non-root builder");
+    return Builder.createGlobal(finish(), std::forward<As>(args)...);
+  }
+};
+
+inline ConstantArrayBuilder
+ConstantInitBuilder::beginArray(llvm::Type *eltTy) {
+  return ConstantArrayBuilder(*this, nullptr, eltTy);
+}
+
+inline ConstantArrayBuilder
+ConstantInitBuilder::AggregateBuilder::beginArray(llvm::Type *eltTy) {
+  return ConstantArrayBuilder(Builder, this, eltTy);
+}
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// struct initializers.
+class ConstantStructBuilder : public ConstantInitBuilder::AggregateBuilder {
+  llvm::StructType *Ty;
+  friend class ConstantInitBuilder;
+  ConstantStructBuilder(ConstantInitBuilder &builder,
+                        AggregateBuilder *parent, llvm::StructType *ty)
+    : AggregateBuilder(builder, parent), Ty(ty) {}
+public:
+  /// Finish the struct.
+  llvm::Constant *finish(bool packed = false) {
+    markFinished();
+
+    auto &buffer = getBuffer();
+    assert(Begin < buffer.size() && "didn't add any struct elements?");
+    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+
+    llvm::Constant *constant;
+    if (Ty) {
+      constant = llvm::ConstantStruct::get(Ty, elts);
+    } else {
+      constant = llvm::ConstantStruct::getAnon(elts, packed);
+    }
+
+    buffer.erase(buffer.begin() + Begin, buffer.end());
+    return constant;
+  }
+
+  template <class... As>
+  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
+    assert(!Parent && "finishing non-root builder");
+    return Builder.createGlobal(finish(), std::forward<As>(args)...);
+  }
+};
+
+inline ConstantStructBuilder
+ConstantInitBuilder::beginStruct(llvm::StructType *structTy) {
+  return ConstantStructBuilder(*this, nullptr, structTy);
 }
 
-inline ConstantBuilder::StructBuilder
-ConstantBuilder::AggregateBuilder::beginStruct(llvm::StructType *structTy) {
-  return StructBuilder(Builder, this, structTy);
+inline ConstantStructBuilder
+ConstantInitBuilder::AggregateBuilder::beginStruct(llvm::StructType *structTy) {
+  return ConstantStructBuilder(Builder, this, structTy);
 }
 
 }  // end namespace CodeGen