r288079 - ConstantBuilder -> ConstantInitBuilder for clarity, and

John McCall via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 28 14:18:27 PST 2016


Author: rjmccall
Date: Mon Nov 28 16:18:27 2016
New Revision: 288079

URL: http://llvm.org/viewvc/llvm-project?rev=288079&view=rev
Log:
ConstantBuilder -> ConstantInitBuilder for clarity, and
move the member classes up to top level to allow forward
declarations to name them.  NFC.

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGCUDANV.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/ConstantBuilder.h

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Nov 28 16:18:27 2016
@@ -88,7 +88,7 @@ static llvm::Constant *buildBlockDescrip
   else
     i8p = CGM.VoidPtrTy;
 
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto elements = builder.beginStruct();
 
   // reserved
@@ -1076,7 +1076,7 @@ static llvm::Constant *buildGlobalBlock(
   assert(blockInfo.CanBeGlobal);
 
   // Generate the constants for the block literal initializer.
-  ConstantBuilder builder(CGM);
+  ConstantInitBuilder builder(CGM);
   auto fields = builder.beginStruct();
 
   // isa

Modified: cfe/trunk/lib/CodeGen/CGCUDANV.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCUDANV.cpp?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCUDANV.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCUDANV.cpp Mon Nov 28 16:18:27 2016
@@ -298,7 +298,7 @@ llvm::Function *CGNVCUDARuntime::makeMod
         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);

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Mon Nov 28 16:18:27 2016
@@ -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
   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::GenerateConst
   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
   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::GenerateClass
       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
   // 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
 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 s
   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 O
         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 O
   // 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::GenerateProtocolHolderCa
   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::GenerateProtocolHolderCa
           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(
     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 O
        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::GeneratePrope
     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 ObjC
   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::ModuleInitFun
 
   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(),

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Mon Nov 28 16:18:27 2016
@@ -908,7 +908,7 @@ Address CGOpenMPRuntime::getOrCreateDefa
           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::createOffloadingBinaryD
   // 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::createOffloadingBinaryD
   // 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
   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);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Nov 28 16:18:27 2016
@@ -743,7 +743,7 @@ void CodeGenModule::EmitCtorList(CtorLis
       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
 
   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(c
     NSConstantStringType = cast<llvm::StructType>(getTypes().ConvertType(NSTy));
   }
   
-  ConstantBuilder Builder(*this);
+  ConstantInitBuilder Builder(*this);
   auto Fields = Builder.beginStruct(NSConstantStringType);
   
   // Class pointer.

Modified: cfe/trunk/lib/CodeGen/ConstantBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.h?rev=288079&r1=288078&r2=288079&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ConstantBuilder.h (original)
+++ cfe/trunk/lib/CodeGen/ConstantBuilder.h Mon Nov 28 16:18:27 2016
@@ -24,14 +24,15 @@
 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;
-    }
+  ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
 
-    template <class... As>
-    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.createGlobal(finish(), std::forward<As>(args)...);
-    }
-  };
-
-  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




More information about the cfe-commits mailing list