<div dir="ltr"><div><div><div><div>Hello John,<br><br></div>This change has introduced alignment problems for some variables.<br><br>The build bots are broken.<br><a href="http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/355">http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/355</a><br><a href="http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/308">http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/308</a><br><br></div>Could you take care of the issue, please?<br><br></div>Thanks<br><br></div>Galina<br><br><div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Nov 19, 2016 at 12:17 AM, John McCall via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rjmccall<br>
Date: Sat Nov 19 02:17:24 2016<br>
New Revision: 287437<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=287437&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=287437&view=rev</a><br>
Log:<br>
Introduce a helper class for building complex constant initializers.  NFC.<br>
<br>
I've adopted this in most of the places it makes sense, but v-tables<br>
and CGObjCMac will need a second pass.<br>
<br>
Added:<br>
    cfe/trunk/lib/CodeGen/<wbr>ConstantBuilder.h<br>
Modified:<br>
    cfe/trunk/include/clang/AST/<wbr>DeclObjC.h<br>
    cfe/trunk/lib/CodeGen/<wbr>CGBlocks.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CGCUDANV.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CGObjCGNU.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CGOpenMPRuntime.cpp<br>
    cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>DeclObjC.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/DeclObjC.h?rev=<wbr>287437&r1=287436&r2=287437&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>DeclObjC.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>DeclObjC.h Sat Nov 19 02:17:24 2016<br>
@@ -870,6 +870,9 @@ public:<br>
   PropertyControl getPropertyImplementation() const {<br>
     return PropertyControl(<wbr>PropertyImplementation);<br>
   }<br>
+  bool isOptional() const {<br>
+    return getPropertyImplementation() == PropertyControl::Optional;<br>
+  }<br>
<br>
   void setPropertyIvarDecl(<wbr>ObjCIvarDecl *Ivar) {<br>
     PropertyIvarDecl = Ivar;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CGBlocks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGBlocks.cpp?rev=287437&r1=<wbr>287436&r2=287437&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CGBlocks.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CGBlocks.cpp Sat Nov 19 02:17:24 2016<br>
@@ -16,6 +16,7 @@<br>
 #include "CGObjCRuntime.h"<br>
 #include "CodeGenFunction.h"<br>
 #include "CodeGenModule.h"<br>
+#include "ConstantBuilder.h"<br>
 #include "clang/AST/DeclObjC.h"<br>
 #include "llvm/ADT/SmallSet.h"<br>
 #include "llvm/IR/CallSite.h"<br>
@@ -77,63 +78,63 @@ static llvm::Constant *buildBlockDescrip<br>
                                             const CGBlockInfo &blockInfo) {<br>
   ASTContext &C = CGM.getContext();<br>
<br>
-  llvm::Type *ulong = CGM.getTypes().ConvertType(C.<wbr>UnsignedLongTy);<br>
-  llvm::Type *i8p = nullptr;<br>
+  llvm::IntegerType *ulong =<br>
+    cast<llvm::IntegerType>(CGM.<wbr>getTypes().ConvertType(C.<wbr>UnsignedLongTy));<br>
+  llvm::PointerType *i8p = nullptr;<br>
   if (CGM.getLangOpts().OpenCL)<br>
     i8p =<br>
       llvm::Type::getInt8PtrTy(<br>
            CGM.getLLVMContext(), C.getTargetAddressSpace(<wbr>LangAS::opencl_constant));<br>
   else<br>
-    i8p = CGM.getTypes().ConvertType(C.<wbr>VoidPtrTy);<br>
+    i8p = CGM.VoidPtrTy;<br>
<br>
-  SmallVector<llvm::Constant*, 6> elements;<br>
+  ConstantBuilder builder(CGM);<br>
+  auto elements = builder.beginStruct();<br>
<br>
   // reserved<br>
-  elements.push_back(llvm::<wbr>ConstantInt::get(ulong, 0));<br>
+  elements.addInt(ulong, 0);<br>
<br>
   // Size<br>
   // FIXME: What is the right way to say this doesn't fit?  We should give<br>
   // a user diagnostic in that case.  Better fix would be to change the<br>
   // API to size_t.<br>
-  elements.push_back(llvm::<wbr>ConstantInt::get(ulong,<br>
-                                            blockInfo.BlockSize.<wbr>getQuantity()));<br>
+  elements.addInt(ulong, blockInfo.BlockSize.<wbr>getQuantity());<br>
<br>
   // Optional copy/dispose helpers.<br>
   if (blockInfo.NeedsCopyDispose) {<br>
     // copy_func_helper_decl<br>
-    elements.push_back(<wbr>buildCopyHelper(CGM, blockInfo));<br>
+    elements.add(buildCopyHelper(<wbr>CGM, blockInfo));<br>
<br>
     // destroy_func_decl<br>
-    elements.push_back(<wbr>buildDisposeHelper(CGM, blockInfo));<br>
+    elements.add(<wbr>buildDisposeHelper(CGM, blockInfo));<br>
   }<br>
<br>
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.<br>
   std::string typeAtEncoding =<br>
     CGM.getContext().<wbr>getObjCEncodingForBlock(<wbr>blockInfo.getBlockExpr());<br>
-  elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<br>
+  elements.add(llvm::<wbr>ConstantExpr::getBitCast(<br>
     CGM.GetAddrOfConstantCString(<wbr>typeAtEncoding).getPointer(), i8p));<br>
<br>
   // GC layout.<br>
   if (C.getLangOpts().ObjC1) {<br>
     if (CGM.getLangOpts().getGC() != LangOptions::NonGC)<br>
-      elements.push_back(CGM.<wbr>getObjCRuntime().<wbr>BuildGCBlockLayout(CGM, blockInfo));<br>
+      elements.add(CGM.<wbr>getObjCRuntime().<wbr>BuildGCBlockLayout(CGM, blockInfo));<br>
     else<br>
-      elements.push_back(CGM.<wbr>getObjCRuntime().<wbr>BuildRCBlockLayout(CGM, blockInfo));<br>
+      elements.add(CGM.<wbr>getObjCRuntime().<wbr>BuildRCBlockLayout(CGM, blockInfo));<br>
   }<br>
   else<br>
-    elements.push_back(llvm::<wbr>Constant::getNullValue(i8p));<br>
-<br>
-  llvm::Constant *init = llvm::ConstantStruct::getAnon(<wbr>elements);<br>
+    elements.addNullPointer(i8p);<br>
<br>
   unsigned AddrSpace = 0;<br>
   if (C.getLangOpts().OpenCL)<br>
     AddrSpace = C.getTargetAddressSpace(<wbr>LangAS::opencl_constant);<br>
+<br>
   llvm::GlobalVariable *global =<br>
-    new llvm::GlobalVariable(CGM.<wbr>getModule(), init->getType(), true,<br>
-                             llvm::GlobalValue::<wbr>InternalLinkage,<br>
-                             init, "__block_descriptor_tmp", nullptr,<br>
-                             llvm::GlobalValue::<wbr>NotThreadLocal,<br>
-                             AddrSpace);<br>
+    elements.<wbr>finishAndCreateGlobal("__<wbr>block_descriptor_tmp",<br>
+                                   CGM.getPointerAlign(),<br>
+                                   /*constant*/ true,<br>
+                                   llvm::GlobalValue::<wbr>InternalLinkage,<br>
+                                   AddrSpace);<br>
<br>
   return llvm::ConstantExpr::<wbr>getBitCast(global, CGM.getBlockDescriptorType());<br>
 }<br>
@@ -1080,36 +1081,31 @@ static llvm::Constant *buildGlobalBlock(<br>
   assert(blockInfo.CanBeGlobal);<br>
<br>
   // Generate the constants for the block literal initializer.<br>
-  llvm::Constant *fields[BlockHeaderSize];<br>
+  ConstantBuilder builder(CGM);<br>
+  auto fields = builder.beginStruct();<br>
<br>
   // isa<br>
-  fields[0] = CGM.getNSConcreteGlobalBlock()<wbr>;<br>
+  fields.add(CGM.<wbr>getNSConcreteGlobalBlock());<br>
<br>
   // __flags<br>
   BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;<br>
   if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET;<br>
<br>
-  fields[1] = llvm::ConstantInt::get(CGM.<wbr>IntTy, flags.getBitMask());<br>
+  fields.addInt(CGM.IntTy, flags.getBitMask());<br>
<br>
   // Reserved<br>
-  fields[2] = llvm::Constant::getNullValue(<wbr>CGM.IntTy);<br>
+  fields.addInt(CGM.IntTy, 0);<br>
<br>
   // Function<br>
-  fields[3] = blockFn;<br>
+  fields.add(blockFn);<br>
<br>
   // Descriptor<br>
-  fields[4] = buildBlockDescriptor(CGM, blockInfo);<br>
-<br>
-  llvm::Constant *init = llvm::ConstantStruct::getAnon(<wbr>fields);<br>
+  fields.add(<wbr>buildBlockDescriptor(CGM, blockInfo));<br>
<br>
-  llvm::GlobalVariable *literal =<br>
-    new llvm::GlobalVariable(CGM.<wbr>getModule(),<br>
-                             init->getType(),<br>
-                             /*constant*/ true,<br>
-                             llvm::GlobalVariable::<wbr>InternalLinkage,<br>
-                             init,<br>
-                             "__block_literal_global");<br>
-  literal->setAlignment(<wbr>blockInfo.BlockAlign.<wbr>getQuantity());<br>
+  llvm::Constant *literal =<br>
+    fields.finishAndCreateGlobal("<wbr>__block_literal_global",<br>
+                                 blockInfo.BlockAlign,<br>
+                                 /*constant*/ true);<br>
<br>
   // Return a constant of the appropriately-casted type.<br>
   llvm::Type *requiredType =<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CGCUDANV.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCUDANV.cpp?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGCUDANV.cpp?rev=287437&r1=<wbr>287436&r2=287437&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CGCUDANV.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CGCUDANV.cpp Sat Nov 19 02:17:24 2016<br>
@@ -15,6 +15,7 @@<br>
 #include "CGCUDARuntime.h"<br>
 #include "CodeGenFunction.h"<br>
 #include "CodeGenModule.h"<br>
+#include "ConstantBuilder.h"<br>
 #include "clang/AST/Decl.h"<br>
 #include "llvm/IR/BasicBlock.h"<br>
 #include "llvm/IR/CallSite.h"<br>
@@ -29,7 +30,8 @@ namespace {<br>
 class CGNVCUDARuntime : public CGCUDARuntime {<br>
<br>
 private:<br>
-  llvm::Type *IntTy, *SizeTy, *VoidTy;<br>
+  llvm::IntegerType *IntTy, *SizeTy;<br>
+  llvm::Type *VoidTy;<br>
   llvm::PointerType *CharPtrTy, *VoidPtrTy, *VoidPtrPtrTy;<br>
<br>
   /// Convenience reference to LLVM Context<br>
@@ -95,9 +97,9 @@ CGNVCUDARuntime::<wbr>CGNVCUDARuntime(CodeGen<br>
   CodeGen::CodeGenTypes &Types = CGM.getTypes();<br>
   ASTContext &Ctx = CGM.getContext();<br>
<br>
-  IntTy = Types.ConvertType(Ctx.IntTy);<br>
-  SizeTy = Types.ConvertType(Ctx.<wbr>getSizeType());<br>
-  VoidTy = llvm::Type::getVoidTy(Context)<wbr>;<br>
+  IntTy = CGM.IntTy;<br>
+  SizeTy = CGM.SizeTy;<br>
+  VoidTy = CGM.VoidTy;<br>
<br>
   CharPtrTy = llvm::PointerType::getUnqual(<wbr>Types.ConvertType(Ctx.CharTy))<wbr>;<br>
   VoidPtrTy = cast<llvm::PointerType>(Types.<wbr>ConvertType(Ctx.VoidPtrTy));<br>
@@ -296,16 +298,21 @@ llvm::Function *CGNVCUDARuntime::makeMod<br>
         CGM.getTriple().isMacOSX() ? "__NV_CUDA,__fatbin" : ".nvFatBinSegment";<br>
<br>
     // Create initialized wrapper structure that points to the loaded GPU binary<br>
-    llvm::Constant *Values[] = {<br>
-        llvm::ConstantInt::get(IntTy, 0x466243b1), // Fatbin wrapper magic.<br>
-        llvm::ConstantInt::get(IntTy, 1),          // Fatbin version.<br>
-        makeConstantString(<wbr>GpuBinaryOrErr.get()-><wbr>getBuffer(), // Data.<br>
-                           "", FatbinConstantName, 8),<br>
-        llvm::ConstantPointerNull::<wbr>get(VoidPtrTy)}; // Unused in fatbin v1.<br>
-    llvm::GlobalVariable *FatbinWrapper = new llvm::GlobalVariable(<br>
-        TheModule, FatbinWrapperTy, true, llvm::GlobalValue::<wbr>InternalLinkage,<br>
-        llvm::ConstantStruct::get(<wbr>FatbinWrapperTy, Values),<br>
-        "__cuda_fatbin_wrapper");<br>
+    ConstantBuilder Builder(CGM);<br>
+    auto Values = Builder.beginStruct(<wbr>FatbinWrapperTy);<br>
+    // Fatbin wrapper magic.<br>
+    Values.addInt(IntTy, 0x466243b1);<br>
+    // Fatbin version.<br>
+    Values.addInt(IntTy, 1);<br>
+    // Data.<br>
+    Values.add(makeConstantString(<wbr>GpuBinaryOrErr.get()-><wbr>getBuffer(),<br>
+                                  "", FatbinConstantName, 8));<br>
+    // Unused in fatbin v1.<br>
+    Values.add(llvm::<wbr>ConstantPointerNull::get(<wbr>VoidPtrTy));<br>
+    llvm::GlobalVariable *FatbinWrapper =<br>
+      Values.finishAndCreateGlobal("<wbr>__cuda_fatbin_wrapper",<br>
+                                   CGM.getPointerAlign(),<br>
+                                   /*constant*/ true);<br>
     FatbinWrapper->setSection(<wbr>FatbinSectionName);<br>
<br>
     // GpuBinaryHandle = __cudaRegisterFatBinary(&<wbr>FatbinWrapper);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CGObjCGNU.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGObjCGNU.cpp?rev=287437&r1=<wbr>287436&r2=287437&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CGObjCGNU.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CGObjCGNU.cpp Sat Nov 19 02:17:24 2016<br>
@@ -18,6 +18,7 @@<br>
 #include "CGCleanup.h"<br>
 #include "CodeGenFunction.h"<br>
 #include "CodeGenModule.h"<br>
+#include "ConstantBuilder.h"<br>
 #include "clang/AST/ASTContext.h"<br>
 #include "clang/AST/Decl.h"<br>
 #include "clang/AST/DeclObjC.h"<br>
@@ -190,47 +191,17 @@ protected:<br>
   /// Generates a global structure, initialized by the elements in the vector.<br>
   /// The element types must match the types of the structure elements in the<br>
   /// first argument.<br>
-  llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,<br>
-                                   ArrayRef<llvm::Constant *> V,<br>
+  llvm::GlobalVariable *MakeGlobal(llvm::Constant *C,<br>
                                    CharUnits Align,<br>
                                    StringRef Name="",<br>
                                    llvm::GlobalValue::<wbr>LinkageTypes linkage<br>
                                          =llvm::GlobalValue::<wbr>InternalLinkage) {<br>
-    llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);<br>
-    auto GV = new llvm::GlobalVariable(<wbr>TheModule, Ty, false,<br>
+    auto GV = new llvm::GlobalVariable(<wbr>TheModule, C->getType(), false,<br>
                                        linkage, C, Name);<br>
     GV->setAlignment(Align.<wbr>getQuantity());<br>
     return GV;<br>
   }<br>
<br>
-  /// Generates a global array.  The vector must contain the same number of<br>
-  /// elements that the array type declares, of the type specified as the array<br>
-  /// element type.<br>
-  llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,<br>
-                                   ArrayRef<llvm::Constant *> V,<br>
-                                   CharUnits Align,<br>
-                                   StringRef Name="",<br>
-                                   llvm::GlobalValue::<wbr>LinkageTypes linkage<br>
-                                         =llvm::GlobalValue::<wbr>InternalLinkage) {<br>
-    llvm::Constant *C = llvm::ConstantArray::get(Ty, V);<br>
-    auto GV = new llvm::GlobalVariable(<wbr>TheModule, Ty, false,<br>
-                                       linkage, C, Name);<br>
-    GV->setAlignment(Align.<wbr>getQuantity());<br>
-    return GV;<br>
-  }<br>
-<br>
-  /// Generates a global array, inferring the array type from the specified<br>
-  /// element type and the size of the initialiser.<br>
-  llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty,<br>
-                                        ArrayRef<llvm::Constant *> V,<br>
-                                        CharUnits Align,<br>
-                                        StringRef Name="",<br>
-                                        llvm::GlobalValue::<wbr>LinkageTypes linkage<br>
-                                         =llvm::GlobalValue::<wbr>InternalLinkage) {<br>
-    llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());<br>
-    return MakeGlobal(ArrayTy, V, Align, Name, linkage);<br>
-  }<br>
-<br>
   /// Returns a property name and encoding string.<br>
   llvm::Constant *MakePropertyEncodingString(<wbr>const ObjCPropertyDecl *PD,<br>
                                              const Decl *Container) {<br>
@@ -251,7 +222,7 @@ protected:<br>
   }<br>
<br>
   /// Push the property attributes into two structure fields.<br>
-  void PushPropertyAttributes(std::<wbr>vector<llvm::Constant*> &Fields,<br>
+  void PushPropertyAttributes(<wbr>ConstantBuilder::StructBuilder &Fields,<br>
       ObjCPropertyDecl *property, bool isSynthesized=true, bool<br>
       isDynamic=true) {<br>
     int attrs = property-><wbr>getPropertyAttributes();<br>
@@ -263,7 +234,7 @@ protected:<br>
       attrs &= ~ObjCPropertyDecl::OBJC_PR_<wbr>strong;<br>
     }<br>
     // The first flags field has the same attribute values as clang uses internally<br>
-    Fields.push_back(llvm::<wbr>ConstantInt::get(Int8Ty, attrs & 0xff));<br>
+    Fields.addInt(Int8Ty, attrs & 0xff);<br>
     attrs >>= 8;<br>
     attrs <<= 2;<br>
     // For protocol properties, synthesized and dynamic have no meaning, so we<br>
@@ -273,10 +244,10 @@ protected:<br>
     attrs |= isDynamic ? (1<<1) : 0;<br>
     // The second field is the next four fields left shifted by two, with the<br>
     // low bit set to indicate whether the field is synthesized or dynamic.<br>
-    Fields.push_back(llvm::<wbr>ConstantInt::get(Int8Ty, attrs & 0xff));<br>
+    Fields.addInt(Int8Ty, attrs & 0xff);<br>
     // Two padding fields<br>
-    Fields.push_back(llvm::<wbr>ConstantInt::get(Int8Ty, 0));<br>
-    Fields.push_back(llvm::<wbr>ConstantInt::get(Int8Ty, 0));<br>
+    Fields.addInt(Int8Ty, 0);<br>
+    Fields.addInt(Int8Ty, 0);<br>
   }<br>
<br>
   /// Ensures that the value has the required type, by inserting a bitcast if<br>
@@ -1233,14 +1204,15 @@ llvm::Constant *CGObjCGNUstep::GetEHType<br>
   llvm::Constant *typeName =<br>
     ExportUniqueString(className, "__objc_eh_typename_");<br>
<br>
-  std::vector<llvm::Constant*> fields;<br>
-  fields.push_back(BVtable);<br>
-  fields.push_back(typeName);<br>
-  llvm::Constant *TI =<br>
-      MakeGlobal(llvm::StructType::<wbr>get(PtrToInt8Ty, PtrToInt8Ty, nullptr),<br>
-                 fields, CGM.getPointerAlign(),<br>
-                 "__objc_eh_typeinfo_" + className,<br>
-          llvm::GlobalValue::<wbr>LinkOnceODRLinkage);<br>
+  ConstantBuilder builder(CGM);<br>
+  auto fields = builder.beginStruct();<br>
+  fields.add(BVtable);<br>
+  fields.add(typeName);<br>
+  llvm::Constant *TI =<br>
+    fields.finishAndCreateGlobal("<wbr>__objc_eh_typeinfo_" + className,<br>
+                                 CGM.getPointerAlign(),<br>
+                                 /*constant*/ false,<br>
+                                 llvm::GlobalValue::<wbr>LinkOnceODRLinkage);<br>
   return llvm::ConstantExpr::<wbr>getBitCast(TI, PtrToInt8Ty);<br>
 }<br>
<br>
@@ -1270,13 +1242,13 @@ ConstantAddress CGObjCGNU::GenerateConst<br>
   else if (isa->getType() != PtrToIdTy)<br>
     isa = llvm::ConstantExpr::<wbr>getBitCast(isa, PtrToIdTy);<br>
<br>
-  std::vector<llvm::Constant*> Ivars;<br>
-  Ivars.push_back(isa);<br>
-  Ivars.push_back(<wbr>MakeConstantString(Str));<br>
-  Ivars.push_back(llvm::<wbr>ConstantInt::get(IntTy, Str.size()));<br>
-  llvm::Constant *ObjCStr = MakeGlobal(<br>
-    llvm::StructType::get(<wbr>PtrToIdTy, PtrToInt8Ty, IntTy, nullptr),<br>
-    Ivars, Align, ".objc_str");<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Fields = Builder.beginStruct();<br>
+  Fields.add(isa);<br>
+  Fields.add(MakeConstantString(<wbr>Str));<br>
+  Fields.addInt(IntTy, Str.size());<br>
+  llvm::Constant *ObjCStr =<br>
+    Fields.finishAndCreateGlobal("<wbr>.objc_str", Align);<br>
   ObjCStr = llvm::ConstantExpr::<wbr>getBitCast(ObjCStr, PtrToInt8Ty);<br>
   ObjCStrings[Str] = ObjCStr;<br>
   ConstantStrings.push_back(<wbr>ObjCStr);<br>
@@ -1551,13 +1523,20 @@ GenerateMethodList(StringRef ClassName,<br>
                    bool isClassMethodList) {<br>
   if (MethodSels.empty())<br>
     return NULLPtr;<br>
+<br>
+  ConstantBuilder Builder(CGM);<br>
+<br>
+  auto MethodList = Builder.beginStruct();<br>
+  MethodList.addNullPointer(CGM.<wbr>Int8PtrTy);<br>
+  MethodList.addInt(Int32Ty, MethodTypes.size());<br>
+<br>
   // Get the method structure type.<br>
   llvm::StructType *ObjCMethodTy = llvm::StructType::get(<br>
     PtrToInt8Ty, // Really a selector, but the runtime creates it us.<br>
     PtrToInt8Ty, // Method types<br>
     IMPTy, //Method pointer<br>
     nullptr);<br>
-  std::vector<llvm::Constant*> Methods;<br>
+  auto Methods = MethodList.beginArray();<br>
   for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {<br>
     llvm::Constant *Method =<br>
       TheModule.getFunction(<wbr>SymbolNameForMethod(ClassName, CategoryName,<br>
@@ -1567,34 +1546,14 @@ GenerateMethodList(StringRef ClassName,<br>
     llvm::Constant *C = MakeConstantString(MethodSels[<wbr>i].getAsString());<br>
     Method = llvm::ConstantExpr::<wbr>getBitCast(Method,<br>
         IMPTy);<br>
-    Methods.push_back(<br>
+    Methods.add(<br>
         llvm::ConstantStruct::get(<wbr>ObjCMethodTy, {C, MethodTypes[i], Method}));<br>
   }<br>
-<br>
-  // Array of method structures<br>
-  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(<wbr>ObjCMethodTy,<br>
-                                                            Methods.size());<br>
-  llvm::Constant *MethodArray = llvm::ConstantArray::get(<wbr>ObjCMethodArrayTy,<br>
-                                                         Methods);<br>
-<br>
-  // Structure containing list pointer, array and array count<br>
-  llvm::StructType *ObjCMethodListTy = llvm::StructType::create(<wbr>VMContext);<br>
-  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(<wbr>ObjCMethodListTy);<br>
-  ObjCMethodListTy->setBody(<br>
-      NextPtrTy,<br>
-      IntTy,<br>
-      ObjCMethodArrayTy,<br>
-      nullptr);<br>
-<br>
-  Methods.clear();<br>
-  Methods.push_back(llvm::<wbr>ConstantPointerNull::get(<br>
-        llvm::PointerType::getUnqual(<wbr>ObjCMethodListTy)));<br>
-  Methods.push_back(llvm::<wbr>ConstantInt::get(Int32Ty, MethodTypes.size()));<br>
-  Methods.push_back(MethodArray)<wbr>;<br>
+  MethodList.add(Methods.finish(<wbr>));<br>
<br>
   // Create an instance of the structure<br>
-  return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),<br>
-                    ".objc_method_list");<br>
+  return MethodList.<wbr>finishAndCreateGlobal(".objc_<wbr>method_list",<br>
+                                          CGM.getPointerAlign());<br>
 }<br>
<br>
 /// Generates an IvarList.  Used in construction of a objc_class.<br>
@@ -1602,35 +1561,36 @@ llvm::Constant *CGObjCGNU::<br>
 GenerateIvarList(ArrayRef<<wbr>llvm::Constant *> IvarNames,<br>
                  ArrayRef<llvm::Constant *> IvarTypes,<br>
                  ArrayRef<llvm::Constant *> IvarOffsets) {<br>
-  if (IvarNames.size() == 0)<br>
+  if (IvarNames.empty())<br>
     return NULLPtr;<br>
-  // Get the method structure type.<br>
+<br>
+  ConstantBuilder Builder(CGM);<br>
+<br>
+  // Structure containing array count followed by array.<br>
+  auto IvarList = Builder.beginStruct();<br>
+  IvarList.addInt(IntTy, (int)IvarNames.size());<br>
+<br>
+  // Get the ivar structure type.<br>
   llvm::StructType *ObjCIvarTy = llvm::StructType::get(<br>
     PtrToInt8Ty,<br>
     PtrToInt8Ty,<br>
     IntTy,<br>
     nullptr);<br>
-  std::vector<llvm::Constant*> Ivars;<br>
+<br>
+  // Array of ivar structures.<br>
+  auto Ivars = IvarList.beginArray(<wbr>ObjCIvarTy);<br>
   for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {<br>
-    Ivars.push_back(llvm::<wbr>ConstantStruct::get(<br>
-        ObjCIvarTy, {IvarNames[i], IvarTypes[i], IvarOffsets[i]}));<br>
+    auto Ivar = Ivars.beginStruct(ObjCIvarTy);<br>
+    Ivar.add(IvarNames[i]);<br>
+    Ivar.add(IvarTypes[i]);<br>
+    Ivar.add(IvarOffsets[i]);<br>
+    Ivars.add(Ivar.finish());<br>
   }<br>
-<br>
-  // Array of method structures<br>
-  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(<wbr>ObjCIvarTy,<br>
-      IvarNames.size());<br>
-<br>
-  llvm::Constant *Elements[] = {<br>
-      llvm::ConstantInt::get(IntTy, (int)IvarNames.size()),<br>
-      llvm::ConstantArray::get(<wbr>ObjCIvarArrayTy, Ivars)};<br>
-  // Structure containing array and array count<br>
-  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,<br>
-    ObjCIvarArrayTy,<br>
-    nullptr);<br>
+  IvarList.add(Ivars.finish());<br>
<br>
   // Create an instance of the structure<br>
-  return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),<br>
-                    ".objc_ivar_list");<br>
+  return IvarList.<wbr>finishAndCreateGlobal(".objc_<wbr>ivar_list",<br>
+                                        CGM.getPointerAlign());<br>
 }<br>
<br>
 /// Generate a class structure<br>
@@ -1678,34 +1638,55 @@ llvm::Constant *CGObjCGNU::GenerateClass<br>
       IntPtrTy,               // strong_pointers<br>
       IntPtrTy,               // weak_pointers<br>
       nullptr);<br>
-  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);<br>
+<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Elements = Builder.beginStruct(ClassTy);<br>
+<br>
   // Fill in the structure<br>
-  std::vector<llvm::Constant*> Elements;<br>
-  Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>MetaClass, PtrToInt8Ty));<br>
-  Elements.push_back(SuperClass)<wbr>;<br>
-  Elements.push_back(<wbr>MakeConstantString(Name, ".class_name"));<br>
-  Elements.push_back(Zero);<br>
-  Elements.push_back(llvm::<wbr>ConstantInt::get(LongTy, info));<br>
+<br>
+  // isa<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<wbr>MetaClass, PtrToInt8Ty));<br>
+  // super_class<br>
+  Elements.add(SuperClass);<br>
+  // name<br>
+  Elements.add(<wbr>MakeConstantString(Name, ".class_name"));<br>
+  // version<br>
+  Elements.addInt(LongTy, 0);<br>
+  // info<br>
+  Elements.addInt(LongTy, info);<br>
+  // instance_size<br>
   if (isMeta) {<br>
     llvm::DataLayout td(&TheModule);<br>
-    Elements.push_back(<br>
-        llvm::ConstantInt::get(LongTy,<br>
-                               td.getTypeSizeInBits(ClassTy) /<br>
-                                 CGM.getContext().getCharWidth(<wbr>)));<br>
+    Elements.addInt(LongTy,<br>
+                    td.getTypeSizeInBits(ClassTy) /<br>
+                      CGM.getContext().getCharWidth(<wbr>));<br>
   } else<br>
-    Elements.push_back(<wbr>InstanceSize);<br>
-  Elements.push_back(IVars);<br>
-  Elements.push_back(Methods);<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>Protocols, PtrTy));<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(llvm::<wbr>ConstantInt::get(LongTy, 1));<br>
-  Elements.push_back(<wbr>IvarOffsets);<br>
-  Elements.push_back(Properties)<wbr>;<br>
-  Elements.push_back(<wbr>StrongIvarBitmap);<br>
-  Elements.push_back(<wbr>WeakIvarBitmap);<br>
+    Elements.add(InstanceSize);<br>
+  // ivars<br>
+  Elements.add(IVars);<br>
+  // methods<br>
+  Elements.add(Methods);<br>
+  // These are all filled in by the runtime, so we pretend<br>
+  // dtable<br>
+  Elements.add(NULLPtr);<br>
+  // subclass_list<br>
+  Elements.add(NULLPtr);<br>
+  // sibling_class<br>
+  Elements.add(NULLPtr);<br>
+  // protocols<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<wbr>Protocols, PtrTy));<br>
+  // gc_object_type<br>
+  Elements.add(NULLPtr);<br>
+  // abi_version<br>
+  Elements.addInt(LongTy, 1);<br>
+  // ivar_offsets<br>
+  Elements.add(IvarOffsets);<br>
+  // properties<br>
+  Elements.add(Properties);<br>
+  // strong_pointers<br>
+  Elements.add(StrongIvarBitmap)<wbr>;<br>
+  // weak_pointers<br>
+  Elements.add(WeakIvarBitmap);<br>
   // Create an instance of the structure<br>
   // This is now an externally visible symbol, so that we can speed up class<br>
   // messages in the next ABI.  We may already have some weak references to<br>
@@ -1714,13 +1695,13 @@ llvm::Constant *CGObjCGNU::GenerateClass<br>
           std::string(Name));<br>
   llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(<wbr>ClassSym);<br>
   llvm::Constant *Class =<br>
-    MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,<br>
-               llvm::GlobalValue::<wbr>ExternalLinkage);<br>
+    Elements.<wbr>finishAndCreateGlobal(<wbr>ClassSym, CGM.getPointerAlign(), false,<br>
+                                   llvm::GlobalValue::<wbr>ExternalLinkage);<br>
   if (ClassRef) {<br>
-      ClassRef->replaceAllUsesWith(<wbr>llvm::ConstantExpr::<wbr>getBitCast(Class,<br>
+    ClassRef->replaceAllUsesWith(<wbr>llvm::ConstantExpr::<wbr>getBitCast(Class,<br>
                   ClassRef->getType()));<br>
-      ClassRef->removeFromParent();<br>
-      Class->setName(ClassSym);<br>
+    ClassRef->removeFromParent();<br>
+    Class->setName(ClassSym);<br>
   }<br>
   return Class;<br>
 }<br>
@@ -1729,38 +1710,33 @@ llvm::Constant *CGObjCGNU::<br>
 GenerateProtocolMethodList(<wbr>ArrayRef<llvm::Constant *> MethodNames,<br>
                            ArrayRef<llvm::Constant *> MethodTypes) {<br>
   // Get the method structure type.<br>
-  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(<br>
-    PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.<br>
-    PtrToInt8Ty,<br>
-    nullptr);<br>
-  std::vector<llvm::Constant*> Methods;<br>
+  llvm::StructType *ObjCMethodDescTy =<br>
+    llvm::StructType::get(CGM.<wbr>getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto MethodList = Builder.beginStruct();<br>
+  MethodList.addInt(IntTy, MethodNames.size());<br>
+  auto Methods = MethodList.beginArray(<wbr>ObjCMethodDescTy);<br>
   for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {<br>
-    Methods.push_back(llvm::<wbr>ConstantStruct::get(<br>
-        ObjCMethodDescTy, {MethodNames[i], MethodTypes[i]}));<br>
-  }<br>
-  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(<wbr>ObjCMethodDescTy,<br>
-      MethodNames.size());<br>
-  llvm::Constant *Array = llvm::ConstantArray::get(<wbr>ObjCMethodArrayTy,<br>
-                                                   Methods);<br>
-  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(<br>
-      IntTy, ObjCMethodArrayTy, nullptr);<br>
-  Methods.clear();<br>
-  Methods.push_back(llvm::<wbr>ConstantInt::get(IntTy, MethodNames.size()));<br>
-  Methods.push_back(Array);<br>
-  return MakeGlobal(<wbr>ObjCMethodDescListTy, Methods, CGM.getPointerAlign(),<br>
-                    ".objc_method_list");<br>
+    auto Method = Methods.beginStruct(<wbr>ObjCMethodDescTy);<br>
+    Method.add(MethodNames[i]);<br>
+    Method.add(MethodTypes[i]);<br>
+    Methods.add(Method.finish());<br>
+  }<br>
+  MethodList.add(Methods.finish(<wbr>));<br>
+  return MethodList.<wbr>finishAndCreateGlobal(".objc_<wbr>method_list",<br>
+                                          CGM.getPointerAlign());<br>
 }<br>
<br>
 // Create the protocol list structure used in classes, categories and so on<br>
-llvm::Constant *CGObjCGNU::<wbr>GenerateProtocolList(ArrayRef<<wbr>std::string>Protocols){<br>
-  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(<wbr>PtrToInt8Ty,<br>
-      Protocols.size());<br>
-  llvm::StructType *ProtocolListTy = llvm::StructType::get(<br>
-      PtrTy, //Should be a recurisve pointer, but it's always NULL here.<br>
-      SizeTy,<br>
-      ProtocolArrayTy,<br>
-      nullptr);<br>
-  std::vector<llvm::Constant*> Elements;<br>
+llvm::Constant *<br>
+CGObjCGNU::<wbr>GenerateProtocolList(ArrayRef<<wbr>std::string> Protocols) {<br>
+<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto ProtocolList = Builder.beginStruct();<br>
+  ProtocolList.add(NULLPtr);<br>
+  ProtocolList.addInt(LongTy, Protocols.size());<br>
+<br>
+  auto Elements = ProtocolList.beginArray(<wbr>PtrToInt8Ty);<br>
   for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();<br>
       iter != endIter ; iter++) {<br>
     llvm::Constant *protocol = nullptr;<br>
@@ -1773,16 +1749,11 @@ llvm::Constant *CGObjCGNU::GenerateProto<br>
     }<br>
     llvm::Constant *Ptr = llvm::ConstantExpr::<wbr>getBitCast(protocol,<br>
                                                            PtrToInt8Ty);<br>
-    Elements.push_back(Ptr);<br>
+    Elements.add(Ptr);<br>
   }<br>
-  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(<wbr>ProtocolArrayTy,<br>
-      Elements);<br>
-  Elements.clear();<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(llvm::<wbr>ConstantInt::get(LongTy, Protocols.size()));<br>
-  Elements.push_back(<wbr>ProtocolArray);<br>
-  return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),<br>
-                    ".objc_protocol_list");<br>
+  ProtocolList.add(Elements.<wbr>finish());<br>
+  return ProtocolList.<wbr>finishAndCreateGlobal(".objc_<wbr>protocol_list",<br>
+                                            CGM.getPointerAlign());<br>
 }<br>
<br>
 llvm::Value *CGObjCGNU::<wbr>GenerateProtocolRef(<wbr>CodeGenFunction &CGF,<br>
@@ -1793,33 +1764,28 @@ llvm::Value *CGObjCGNU::GenerateProtocol<br>
   return CGF.Builder.CreateBitCast(<wbr>protocol, llvm::PointerType::getUnqual(<wbr>T));<br>
 }<br>
<br>
-llvm::Constant *CGObjCGNU::<wbr>GenerateEmptyProtocol(<br>
-  const std::string &ProtocolName) {<br>
-  SmallVector<std::string, 0> EmptyStringVector;<br>
-  SmallVector<llvm::Constant*, 0> EmptyConstantVector;<br>
-<br>
-  llvm::Constant *ProtocolList = GenerateProtocolList(<wbr>EmptyStringVector);<br>
-  llvm::Constant *MethodList =<br>
-    GenerateProtocolMethodList(<wbr>EmptyConstantVector, EmptyConstantVector);<br>
+llvm::Constant *<br>
+CGObjCGNU::<wbr>GenerateEmptyProtocol(const std::string &ProtocolName) {<br>
+  llvm::Constant *ProtocolList = GenerateProtocolList({});<br>
+  llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});<br>
   // Protocols are objects containing lists of the methods implemented and<br>
   // protocols adopted.<br>
-  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,<br>
-      PtrToInt8Ty,<br>
-      ProtocolList->getType(),<br>
-      MethodList->getType(),<br>
-      MethodList->getType(),<br>
-      MethodList->getType(),<br>
-      MethodList->getType(),<br>
-      nullptr);<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Elements = Builder.beginStruct();<br>
+<br>
   // The isa pointer must be set to a magic number so the runtime knows it's<br>
   // the correct layout.<br>
-  llvm::Constant *Elements[] = {<br>
-      llvm::ConstantExpr::<wbr>getIntToPtr(<br>
-          llvm::ConstantInt::get(<wbr>Int32Ty, ProtocolVersion), IdTy),<br>
-      MakeConstantString(<wbr>ProtocolName, ".objc_protocol_name"), ProtocolList,<br>
-      MethodList, MethodList, MethodList, MethodList};<br>
-  return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),<br>
-                    ".objc_protocol");<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getIntToPtr(<br>
+          llvm::ConstantInt::get(<wbr>Int32Ty, ProtocolVersion), IdTy));<br>
+<br>
+  Elements.add(<wbr>MakeConstantString(<wbr>ProtocolName, ".objc_protocol_name"));<br>
+  Elements.add(ProtocolList);<br>
+  Elements.add(MethodList);<br>
+  Elements.add(MethodList);<br>
+  Elements.add(MethodList);<br>
+  Elements.add(MethodList);<br>
+  return Elements.<wbr>finishAndCreateGlobal(".objc_<wbr>protocol",<br>
+                                        CGM.getPointerAlign());<br>
 }<br>
<br>
 void CGObjCGNU::GenerateProtocol(<wbr>const ObjCProtocolDecl *PD) {<br>
@@ -1886,142 +1852,143 @@ void CGObjCGNU::GenerateProtocol(<wbr>const O<br>
   // The isSynthesized value is always set to 0 in a protocol.  It exists to<br>
   // simplify the runtime library by allowing it to use the same data<br>
   // structures for protocol metadata everywhere.<br>
-  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(<br>
-          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br>
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);<br>
-  std::vector<llvm::Constant*> Properties;<br>
-  std::vector<llvm::Constant*> OptionalProperties;<br>
<br>
-  // Add all of the property methods need adding to the method list and to the<br>
-  // property metadata list.<br>
-  for (auto *property : PD->instance_properties()) {<br>
-    std::vector<llvm::Constant*> Fields;<br>
-<br>
-    Fields.push_back(<wbr>MakePropertyEncodingString(<wbr>property, nullptr));<br>
-    PushPropertyAttributes(Fields, property);<br>
+  llvm::Constant *PropertyList;<br>
+  llvm::Constant *OptionalPropertyList;<br>
+  {<br>
+    llvm::StructType *propertyMetadataTy =<br>
+      llvm::StructType::get(CGM.<wbr>getLLVMContext(),<br>
+        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br>
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });<br>
+<br>
+    unsigned numReqProperties = 0, numOptProperties = 0;<br>
+    for (auto property : PD->instance_properties()) {<br>
+      if (property->isOptional())<br>
+        numOptProperties++;<br>
+      else<br>
+        numReqProperties++;<br>
+    }<br>
+<br>
+    ConstantBuilder reqPropertyListBuilder(CGM);<br>
+    auto reqPropertiesList = reqPropertyListBuilder.<wbr>beginStruct();<br>
+    reqPropertiesList.addInt(<wbr>IntTy, numReqProperties);<br>
+    reqPropertiesList.add(NULLPtr)<wbr>;<br>
+    auto reqPropertiesArray = reqPropertiesList.beginArray(<wbr>propertyMetadataTy);<br>
+<br>
+    ConstantBuilder optPropertyListBuilder(CGM);<br>
+    auto optPropertiesList = optPropertyListBuilder.<wbr>beginStruct();<br>
+    optPropertiesList.addInt(<wbr>IntTy, numOptProperties);<br>
+    optPropertiesList.add(NULLPtr)<wbr>;<br>
+    auto optPropertiesArray = optPropertiesList.beginArray(<wbr>propertyMetadataTy);<br>
+<br>
+    // Add all of the property methods need adding to the method list and to the<br>
+    // property metadata list.<br>
+    for (auto *property : PD->instance_properties()) {<br>
+      auto &propertiesArray =<br>
+        (property->isOptional() ? optPropertiesArray : reqPropertiesArray);<br>
+      auto fields = propertiesArray.beginStruct(<wbr>propertyMetadataTy);<br>
+<br>
+      fields.add(<wbr>MakePropertyEncodingString(<wbr>property, nullptr));<br>
+      PushPropertyAttributes(fields, property);<br>
+<br>
+      if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr>)) {<br>
+        std::string typeStr;<br>
+        Context.<wbr>getObjCEncodingForMethodDecl(<wbr>getter, typeStr);<br>
+        llvm::Constant *typeEncoding = MakeConstantString(typeStr);<br>
+        InstanceMethodTypes.push_back(<wbr>typeEncoding);<br>
+        fields.add(MakeConstantString(<wbr>getter->getSelector().<wbr>getAsString()));<br>
+        fields.add(typeEncoding);<br>
+      } else {<br>
+        fields.add(NULLPtr);<br>
+        fields.add(NULLPtr);<br>
+      }<br>
+      if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr>)) {<br>
+        std::string typeStr;<br>
+        Context.<wbr>getObjCEncodingForMethodDecl(<wbr>setter, typeStr);<br>
+        llvm::Constant *typeEncoding = MakeConstantString(typeStr);<br>
+        InstanceMethodTypes.push_back(<wbr>typeEncoding);<br>
+        fields.add(MakeConstantString(<wbr>setter->getSelector().<wbr>getAsString()));<br>
+        fields.add(typeEncoding);<br>
+      } else {<br>
+        fields.add(NULLPtr);<br>
+        fields.add(NULLPtr);<br>
+      }<br>
<br>
-    if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr>)) {<br>
-      std::string TypeStr;<br>
-      Context.<wbr>getObjCEncodingForMethodDecl(<wbr>getter,TypeStr);<br>
-      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);<br>
-      InstanceMethodTypes.push_back(<wbr>TypeEncoding);<br>
-      Fields.push_back(<wbr>MakeConstantString(getter-><wbr>getSelector().getAsString()));<br>
-      Fields.push_back(TypeEncoding)<wbr>;<br>
-    } else {<br>
-      Fields.push_back(NULLPtr);<br>
-      Fields.push_back(NULLPtr);<br>
-    }<br>
-    if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr>)) {<br>
-      std::string TypeStr;<br>
-      Context.<wbr>getObjCEncodingForMethodDecl(<wbr>setter,TypeStr);<br>
-      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);<br>
-      InstanceMethodTypes.push_back(<wbr>TypeEncoding);<br>
-      Fields.push_back(<wbr>MakeConstantString(setter-><wbr>getSelector().getAsString()));<br>
-      Fields.push_back(TypeEncoding)<wbr>;<br>
-    } else {<br>
-      Fields.push_back(NULLPtr);<br>
-      Fields.push_back(NULLPtr);<br>
-    }<br>
-    if (property-><wbr>getPropertyImplementation() == ObjCPropertyDecl::Optional) {<br>
-      OptionalProperties.push_back(<wbr>llvm::ConstantStruct::get(<wbr>PropertyMetadataTy, Fields));<br>
-    } else {<br>
-      Properties.push_back(llvm::<wbr>ConstantStruct::get(<wbr>PropertyMetadataTy, Fields));<br>
+      propertiesArray.add(fields.<wbr>finish());<br>
     }<br>
+<br>
+    reqPropertiesList.add(<wbr>reqPropertiesArray.finish());<br>
+    PropertyList =<br>
+      reqPropertiesList.<wbr>finishAndCreateGlobal(".objc_<wbr>property_list",<br>
+                                              CGM.getPointerAlign());<br>
+<br>
+    optPropertiesList.add(<wbr>optPropertiesArray.finish());<br>
+    OptionalPropertyList =<br>
+      optPropertiesList.<wbr>finishAndCreateGlobal(".objc_<wbr>property_list",<br>
+                                              CGM.getPointerAlign());<br>
   }<br>
-  llvm::Constant *PropertyArray = llvm::ConstantArray::get(<br>
-      llvm::ArrayType::get(<wbr>PropertyMetadataTy, Properties.size()), Properties);<br>
-  llvm::Constant* PropertyListInitFields[] =<br>
-    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};<br>
-<br>
-  llvm::Constant *PropertyListInit =<br>
-      llvm::ConstantStruct::getAnon(<wbr>PropertyListInitFields);<br>
-  llvm::Constant *PropertyList = new llvm::GlobalVariable(<wbr>TheModule,<br>
-      PropertyListInit->getType(), false, llvm::GlobalValue::<wbr>InternalLinkage,<br>
-      PropertyListInit, ".objc_property_list");<br>
-<br>
-  llvm::Constant *OptionalPropertyArray =<br>
-      llvm::ConstantArray::get(llvm:<wbr>:ArrayType::get(<wbr>PropertyMetadataTy,<br>
-          OptionalProperties.size()) , OptionalProperties);<br>
-  llvm::Constant* OptionalPropertyListInitFields<wbr>[] = {<br>
-      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,<br>
-      OptionalPropertyArray };<br>
-<br>
-  llvm::Constant *OptionalPropertyListInit =<br>
-      llvm::ConstantStruct::getAnon(<wbr>OptionalPropertyListInitFields<wbr>);<br>
-  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(<wbr>TheModule,<br>
-          OptionalPropertyListInit-><wbr>getType(), false,<br>
-          llvm::GlobalValue::<wbr>InternalLinkage, OptionalPropertyListInit,<br>
-          ".objc_property_list");<br>
<br>
   // Protocols are objects containing lists of the methods implemented and<br>
   // protocols adopted.<br>
-  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,<br>
-      PtrToInt8Ty,<br>
-      ProtocolList->getType(),<br>
-      InstanceMethodList->getType(),<br>
-      ClassMethodList->getType(),<br>
-      OptionalInstanceMethodList-><wbr>getType(),<br>
-      OptionalClassMethodList-><wbr>getType(),<br>
-      PropertyList->getType(),<br>
-      OptionalPropertyList->getType(<wbr>),<br>
-      nullptr);<br>
   // The isa pointer must be set to a magic number so the runtime knows it's<br>
   // the correct layout.<br>
-  llvm::Constant *Elements[] = {<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Elements = Builder.beginStruct();<br>
+  Elements.add(<br>
       llvm::ConstantExpr::<wbr>getIntToPtr(<br>
-          llvm::ConstantInt::get(<wbr>Int32Ty, ProtocolVersion), IdTy),<br>
-      MakeConstantString(<wbr>ProtocolName, ".objc_protocol_name"), ProtocolList,<br>
-      InstanceMethodList, ClassMethodList, OptionalInstanceMethodList,<br>
-      OptionalClassMethodList, PropertyList, OptionalPropertyList};<br>
+          llvm::ConstantInt::get(<wbr>Int32Ty, ProtocolVersion), IdTy));<br>
+  Elements.add(<br>
+      MakeConstantString(<wbr>ProtocolName, ".objc_protocol_name"));<br>
+  Elements.add(ProtocolList);<br>
+  Elements.add(<wbr>InstanceMethodList);<br>
+  Elements.add(ClassMethodList);<br>
+  Elements.add(<wbr>OptionalInstanceMethodList);<br>
+  Elements.add(<wbr>OptionalClassMethodList);<br>
+  Elements.add(PropertyList);<br>
+  Elements.add(<wbr>OptionalPropertyList);<br>
   ExistingProtocols[<wbr>ProtocolName] =<br>
-    llvm::ConstantExpr::<wbr>getBitCast(MakeGlobal(<wbr>ProtocolTy, Elements,<br>
-          CGM.getPointerAlign(), ".objc_protocol"), IdTy);<br>
+    llvm::ConstantExpr::<wbr>getBitCast(<br>
+      Elements.<wbr>finishAndCreateGlobal(".objc_<wbr>protocol", CGM.getPointerAlign()),<br>
+      IdTy);<br>
 }<br>
 void CGObjCGNU::<wbr>GenerateProtocolHolderCategory<wbr>() {<br>
   // Collect information about instance methods<br>
   SmallVector<Selector, 1> MethodSels;<br>
   SmallVector<llvm::Constant*, 1> MethodTypes;<br>
<br>
-  std::vector<llvm::Constant*> Elements;<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Elements = Builder.beginStruct();<br>
+<br>
   const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_<wbr>Hack";<br>
   const std::string CategoryName = "AnotherHack";<br>
-  Elements.push_back(<wbr>MakeConstantString(<wbr>CategoryName));<br>
-  Elements.push_back(<wbr>MakeConstantString(ClassName))<wbr>;<br>
+  Elements.add(<wbr>MakeConstantString(<wbr>CategoryName));<br>
+  Elements.add(<wbr>MakeConstantString(ClassName))<wbr>;<br>
   // Instance method list<br>
-  Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>GenerateMethodList(<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<wbr>GenerateMethodList(<br>
           ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));<br>
   // Class method list<br>
-  Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>GenerateMethodList(<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<wbr>GenerateMethodList(<br>
           ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));<br>
+<br>
   // Protocol list<br>
-  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,<br>
-      ExistingProtocols.size());<br>
-  llvm::StructType *ProtocolListTy = llvm::StructType::get(<br>
-      PtrTy, //Should be a recurisve pointer, but it's always NULL here.<br>
-      SizeTy,<br>
-      ProtocolArrayTy,<br>
-      nullptr);<br>
-  std::vector<llvm::Constant*> ProtocolElements;<br>
-  for (llvm::StringMapIterator<llvm:<wbr>:Constant*> iter =<br>
-       ExistingProtocols.begin(), endIter = ExistingProtocols.end();<br>
+  ConstantBuilder ProtocolListBuilder(CGM);<br>
+  auto ProtocolList = ProtocolListBuilder.<wbr>beginStruct();<br>
+  ProtocolList.add(NULLPtr);<br>
+  ProtocolList.addInt(LongTy, ExistingProtocols.size());<br>
+  auto ProtocolElements = ProtocolList.beginArray(PtrTy)<wbr>;<br>
+  for (auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();<br>
        iter != endIter ; iter++) {<br>
     llvm::Constant *Ptr = llvm::ConstantExpr::<wbr>getBitCast(iter->getValue(),<br>
             PtrTy);<br>
-    ProtocolElements.push_back(<wbr>Ptr);<br>
+    ProtocolElements.add(Ptr);<br>
   }<br>
-  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(<wbr>ProtocolArrayTy,<br>
-      ProtocolElements);<br>
-  ProtocolElements.clear();<br>
-  ProtocolElements.push_back(<wbr>NULLPtr);<br>
-  ProtocolElements.push_back(<wbr>llvm::ConstantInt::get(LongTy,<br>
-              ExistingProtocols.size()));<br>
-  ProtocolElements.push_back(<wbr>ProtocolArray);<br>
-  Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>MakeGlobal(ProtocolListTy,<br>
-                  ProtocolElements, CGM.getPointerAlign(),<br>
-                  ".objc_protocol_list"), PtrTy));<br>
+  ProtocolList.add(<wbr>ProtocolElements.finish());<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<br>
+                   ProtocolList.<wbr>finishAndCreateGlobal(".objc_<wbr>protocol_list",<br>
+                                                      CGM.getPointerAlign()),<br>
+                   PtrTy));<br>
   Categories.push_back(llvm::<wbr>ConstantExpr::getBitCast(<br>
-        MakeGlobal(llvm::StructType::<wbr>get(PtrToInt8Ty, PtrToInt8Ty,<br>
-            PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),<br>
+        Elements.<wbr>finishAndCreateGlobal("", CGM.getPointerAlign()),<br>
         PtrTy));<br>
 }<br>
<br>
@@ -2056,13 +2023,16 @@ llvm::Constant *CGObjCGNU::MakeBitField(<br>
     }<br>
     values.push_back(llvm::<wbr>ConstantInt::get(Int32Ty, word));<br>
   }<br>
-  llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());<br>
-  llvm::Constant *array = llvm::ConstantArray::get(<wbr>arrayTy, values);<br>
-  llvm::Constant *fields[2] = {<br>
-      llvm::ConstantInt::get(<wbr>Int32Ty, values.size()),<br>
-      array };<br>
-  llvm::Constant *GS = MakeGlobal(llvm::StructType::<wbr>get(Int32Ty, arrayTy,<br>
-        nullptr), fields, CharUnits::fromQuantity(4));<br>
+<br>
+  ConstantBuilder builder(CGM);<br>
+  auto fields = builder.beginStruct();<br>
+  fields.addInt(Int32Ty, values.size());<br>
+  auto array = fields.beginArray();<br>
+  for (auto v : values) array.add(v);<br>
+  fields.add(array.finish());<br>
+<br>
+  llvm::Constant *GS =<br>
+    fields.finishAndCreateGlobal("<wbr>", CharUnits::fromQuantity(4));<br>
   llvm::Constant *ptr = llvm::ConstantExpr::<wbr>getPtrToInt(GS, IntPtrTy);<br>
   return ptr;<br>
 }<br>
@@ -2098,23 +2068,25 @@ void CGObjCGNU::GenerateCategory(<wbr>const O<br>
        E = Protos.end(); I != E; ++I)<br>
     Protocols.push_back((*I)-><wbr>getNameAsString());<br>
<br>
-  llvm::Constant *Elements[] = {<br>
-      MakeConstantString(<wbr>CategoryName), MakeConstantString(ClassName),<br>
-      // Instance method list<br>
-      llvm::ConstantExpr::<wbr>getBitCast(<br>
+  ConstantBuilder Builder(CGM);<br>
+  auto Elements = Builder.beginStruct();<br>
+  Elements.add(<wbr>MakeConstantString(<wbr>CategoryName));<br>
+  Elements.add(<wbr>MakeConstantString(ClassName))<wbr>;<br>
+  // Instance method list<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<br>
           GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,<br>
                              InstanceMethodTypes, false),<br>
-          PtrTy),<br>
-      // Class method list<br>
-      llvm::ConstantExpr::<wbr>getBitCast(GenerateMethodList(<wbr>ClassName, CategoryName,<br>
-                                                        ClassMethodSels,<br>
-                                                        ClassMethodTypes, true),<br>
-                                     PtrTy),<br>
-      // Protocol list<br>
-      llvm::ConstantExpr::<wbr>getBitCast(<wbr>GenerateProtocolList(<wbr>Protocols), PtrTy)};<br>
+          PtrTy));<br>
+  // Class method list<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<br>
+                 GenerateMethodList(ClassName, CategoryName,<br>
+                                    ClassMethodSels, ClassMethodTypes, true),<br>
+                  PtrTy));<br>
+  // Protocol list<br>
+  Elements.add(llvm::<wbr>ConstantExpr::getBitCast(<br>
+                 GenerateProtocolList(<wbr>Protocols), PtrTy));<br>
   Categories.push_back(llvm::<wbr>ConstantExpr::getBitCast(<br>
-        MakeGlobal(llvm::StructType::<wbr>get(PtrToInt8Ty, PtrToInt8Ty,<br>
-            PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),<br>
+        Elements.<wbr>finishAndCreateGlobal("", CGM.getPointerAlign()),<br>
         PtrTy));<br>
 }<br>
<br>
@@ -2124,23 +2096,35 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br>
   ASTContext &Context = CGM.getContext();<br>
   // Property metadata: name, attributes, attributes2, padding1, padding2,<br>
   // setter name, setter types, getter name, getter types.<br>
-  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(<br>
-          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br>
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);<br>
-  std::vector<llvm::Constant*> Properties;<br>
+  llvm::StructType *propertyMetadataTy =<br>
+    llvm::StructType::get(CGM.<wbr>getLLVMContext(),<br>
+        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br>
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });<br>
+<br>
+  unsigned numProperties = 0;<br>
+  for (auto *propertyImpl : OID->property_impls()) {<br>
+    (void) propertyImpl;<br>
+    numProperties++;<br>
+  }<br>
+<br>
+  ConstantBuilder builder(CGM);<br>
+  auto propertyList = builder.beginStruct();<br>
+  propertyList.addInt(IntTy, numProperties);<br>
+  propertyList.add(NULLPtr);<br>
+  auto properties = propertyList.beginArray(<wbr>propertyMetadataTy);<br>
<br>
   // Add all of the property methods need adding to the method list and to the<br>
   // property metadata list.<br>
   for (auto *propertyImpl : OID->property_impls()) {<br>
-    std::vector<llvm::Constant*> Fields;<br>
+    auto fields = properties.beginStruct(<wbr>propertyMetadataTy);<br>
     ObjCPropertyDecl *property = propertyImpl->getPropertyDecl(<wbr>);<br>
     bool isSynthesized = (propertyImpl-><wbr>getPropertyImplementation() ==<br>
         ObjCPropertyImplDecl::<wbr>Synthesize);<br>
     bool isDynamic = (propertyImpl-><wbr>getPropertyImplementation() ==<br>
         ObjCPropertyImplDecl::Dynamic)<wbr>;<br>
<br>
-    Fields.push_back(<wbr>MakePropertyEncodingString(<wbr>property, OID));<br>
-    PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);<br>
+    fields.add(<wbr>MakePropertyEncodingString(<wbr>property, OID));<br>
+    PushPropertyAttributes(fields, property, isSynthesized, isDynamic);<br>
     if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr>)) {<br>
       std::string TypeStr;<br>
       Context.<wbr>getObjCEncodingForMethodDecl(<wbr>getter,TypeStr);<br>
@@ -2149,11 +2133,11 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br>
         InstanceMethodTypes.push_back(<wbr>TypeEncoding);<br>
         InstanceMethodSels.push_back(<wbr>getter->getSelector());<br>
       }<br>
-      Fields.push_back(<wbr>MakeConstantString(getter-><wbr>getSelector().getAsString()));<br>
-      Fields.push_back(TypeEncoding)<wbr>;<br>
+      fields.add(MakeConstantString(<wbr>getter->getSelector().<wbr>getAsString()));<br>
+      fields.add(TypeEncoding);<br>
     } else {<br>
-      Fields.push_back(NULLPtr);<br>
-      Fields.push_back(NULLPtr);<br>
+      fields.add(NULLPtr);<br>
+      fields.add(NULLPtr);<br>
     }<br>
     if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr>)) {<br>
       std::string TypeStr;<br>
@@ -2163,26 +2147,18 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br>
         InstanceMethodTypes.push_back(<wbr>TypeEncoding);<br>
         InstanceMethodSels.push_back(<wbr>setter->getSelector());<br>
       }<br>
-      Fields.push_back(<wbr>MakeConstantString(setter-><wbr>getSelector().getAsString()));<br>
-      Fields.push_back(TypeEncoding)<wbr>;<br>
+      fields.add(MakeConstantString(<wbr>setter->getSelector().<wbr>getAsString()));<br>
+      fields.add(TypeEncoding);<br>
     } else {<br>
-      Fields.push_back(NULLPtr);<br>
-      Fields.push_back(NULLPtr);<br>
+      fields.add(NULLPtr);<br>
+      fields.add(NULLPtr);<br>
     }<br>
-    Properties.push_back(llvm::<wbr>ConstantStruct::get(<wbr>PropertyMetadataTy, Fields));<br>
+    properties.add(fields.finish()<wbr>);<br>
   }<br>
-  llvm::ArrayType *PropertyArrayTy =<br>
-      llvm::ArrayType::get(<wbr>PropertyMetadataTy, Properties.size());<br>
-  llvm::Constant *PropertyArray = llvm::ConstantArray::get(<wbr>PropertyArrayTy,<br>
-          Properties);<br>
-  llvm::Constant* PropertyListInitFields[] =<br>
-    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};<br>
-<br>
-  llvm::Constant *PropertyListInit =<br>
-      llvm::ConstantStruct::getAnon(<wbr>PropertyListInitFields);<br>
-  return new llvm::GlobalVariable(<wbr>TheModule, PropertyListInit->getType(), false,<br>
-          llvm::GlobalValue::<wbr>InternalLinkage, PropertyListInit,<br>
-          ".objc_property_list");<br>
+  propertyList.add(properties.<wbr>finish());<br>
+<br>
+  return propertyList.<wbr>finishAndCreateGlobal(".objc_<wbr>property_list",<br>
+                                            CGM.getPointerAlign());<br>
 }<br>
<br>
 void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {<br>
@@ -2231,7 +2207,8 @@ void CGObjCGNU::GenerateClass(const ObjC<br>
   SmallVector<llvm::Constant*, 16> IvarTypes;<br>
   SmallVector<llvm::Constant*, 16> IvarOffsets;<br>
<br>
-  std::vector<llvm::Constant*> IvarOffsetValues;<br>
+  ConstantBuilder IvarOffsetBuilder(CGM);<br>
+  auto IvarOffsetValues = IvarOffsetBuilder.beginArray(<wbr>PtrToIntTy);<br>
   SmallVector<bool, 16> WeakIvars;<br>
   SmallVector<bool, 16> StrongIvars;<br>
<br>
@@ -2275,7 +2252,7 @@ void CGObjCGNU::GenerateClass(const ObjC<br>
           "__objc_ivar_offset_value_" + ClassName +"." +<br>
           IVD->getNameAsString());<br>
       IvarOffsets.push_back(<wbr>OffsetValue);<br>
-      IvarOffsetValues.push_back(<wbr>OffsetVar);<br>
+      IvarOffsetValues.add(<wbr>OffsetVar);<br>
       Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers()<wbr>.getObjCLifetime();<br>
       switch (lt) {<br>
         case Qualifiers::OCL_Strong:<br>
@@ -2294,8 +2271,8 @@ void CGObjCGNU::GenerateClass(const ObjC<br>
   llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);<br>
   llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);<br>
   llvm::GlobalVariable *IvarOffsetArray =<br>
-    MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),<br>
-                    ".ivar.offsets");<br>
+    IvarOffsetValues.<wbr>finishAndCreateGlobal(".ivar.<wbr>offsets",<br>
+                                           CGM.getPointerAlign());<br>
<br>
   // Collect information about instance methods<br>
   SmallVector<Selector, 16> InstanceMethodSels;<br>
@@ -2461,21 +2438,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
     if (StringClass.empty()) StringClass = "NXConstantString";<br>
<br>
     Elements.push_back(<wbr>MakeConstantString(<wbr>StringClass,<br>
-                ".objc_static_class_name"));<br>
+                                          ".objc_static_class_name"));<br>
     Elements.push_back(llvm::<wbr>ConstantArray::get(<wbr>StaticsArrayTy,<br>
-       ConstantStrings));<br>
-    llvm::StructType *StaticsListTy =<br>
-      llvm::StructType::get(<wbr>PtrToInt8Ty, StaticsArrayTy, nullptr);<br>
-    llvm::Type *StaticsListPtrTy =<br>
-      llvm::PointerType::getUnqual(<wbr>StaticsListTy);<br>
-    Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),<br>
-                         ".objc_statics");<br>
+                                                ConstantStrings));<br>
+    Statics = MakeGlobal(llvm::<wbr>ConstantStruct::getAnon(<wbr>Elements),<br>
+                         CGM.getPointerAlign(), ".objc_statics");<br>
+    llvm::Type *StaticsListPtrTy = Statics->getType();<br>
     llvm::ArrayType *StaticsListArrayTy =<br>
       llvm::ArrayType::get(<wbr>StaticsListPtrTy, 2);<br>
     Elements.clear();<br>
     Elements.push_back(Statics);<br>
     Elements.push_back(llvm::<wbr>Constant::getNullValue(<wbr>StaticsListPtrTy));<br>
-    Statics = MakeGlobal(StaticsListArrayTy, Elements,<br>
+    Statics = MakeGlobal(llvm::<wbr>ConstantArray::get(<wbr>StaticsListArrayTy, Elements),<br>
                          CGM.getPointerAlign(), ".objc_statics_ptr");<br>
     Statics = llvm::ConstantExpr::<wbr>getBitCast(Statics, PtrTy);<br>
   }<br>
@@ -2489,7 +2463,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
<br>
   Elements.clear();<br>
   // Pointer to an array of selectors used in this module.<br>
-  std::vector<llvm::Constant*> Selectors;<br>
+  ConstantBuilder SelectorBuilder(CGM);<br>
+  auto Selectors = SelectorBuilder.beginArray(<wbr>SelStructTy);<br>
   std::vector<llvm::GlobalAlias*<wbr>> SelectorAliases;<br>
   for (SelectorMap::iterator iter = SelectorTable.begin(),<br>
       iterEnd = SelectorTable.end(); iter != iterEnd ; ++iter) {<br>
@@ -2505,10 +2480,10 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
       if (!i->first.empty())<br>
         SelectorTypeEncoding = MakeConstantString(i->first, ".objc_sel_types");<br>
<br>
-      Elements.push_back(SelName);<br>
-      Elements.push_back(<wbr>SelectorTypeEncoding);<br>
-      Selectors.push_back(llvm::<wbr>ConstantStruct::get(<wbr>SelStructTy, Elements));<br>
-      Elements.clear();<br>
+      auto SelStruct = Selectors.beginStruct(<wbr>SelStructTy);<br>
+      SelStruct.add(SelName);<br>
+      SelStruct.add(<wbr>SelectorTypeEncoding);<br>
+      Selectors.add(SelStruct.<wbr>finish());<br>
<br>
       // Store the selector alias for later replacement<br>
       SelectorAliases.push_back(i-><wbr>second);<br>
@@ -2519,16 +2494,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
   // because the selector list has a length field.  Unfortunately, the GCC<br>
   // runtime decides to ignore the length field and expects a NULL terminator,<br>
   // and GCC cooperates with this by always setting the length to 0.<br>
-  Elements.push_back(NULLPtr);<br>
-  Elements.push_back(NULLPtr);<br>
-  Selectors.push_back(llvm::<wbr>ConstantStruct::get(<wbr>SelStructTy, Elements));<br>
-  Elements.clear();<br>
+  {<br>
+    auto SelStruct = Selectors.beginStruct(<wbr>SelStructTy);<br>
+    SelStruct.add(NULLPtr);<br>
+    SelStruct.add(NULLPtr);<br>
+    Selectors.add(SelStruct.<wbr>finish());<br>
+  }<br>
<br>
   // Number of static selectors<br>
   Elements.push_back(llvm::<wbr>ConstantInt::get(LongTy, SelectorCount));<br>
   llvm::GlobalVariable *SelectorList =<br>
-      MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),<br>
-                      ".objc_selector_list");<br>
+      Selectors.<wbr>finishAndCreateGlobal(".objc_<wbr>selector_list",<br>
+                                      CGM.getPointerAlign());<br>
   Elements.push_back(llvm::<wbr>ConstantExpr::getBitCast(<wbr>SelectorList,<br>
     SelStructPtrTy));<br>
<br>
@@ -2562,7 +2539,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
   Elements.push_back(ClassList);<br>
   // Construct the symbol table<br>
   llvm::Constant *SymTab =<br>
-    MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());<br>
+    MakeGlobal(llvm::<wbr>ConstantStruct::get(SymTabTy, Elements),<br>
+               CGM.getPointerAlign());<br>
<br>
   // The symbol table is contained in a module which has some version-checking<br>
   // constants<br>
@@ -2603,7 +2581,9 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br>
         break;<br>
     }<br>
<br>
-  llvm::Value *Module = MakeGlobal(ModuleTy, Elements, CGM.getPointerAlign());<br>
+  llvm::Value *Module =<br>
+    MakeGlobal(llvm::<wbr>ConstantStruct::get(ModuleTy, Elements),<br>
+               CGM.getPointerAlign());<br>
<br>
   // Create the load function calling the runtime entry point with the module<br>
   // structure<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CGOpenMPRuntime.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGOpenMPRuntime.cpp?rev=<wbr>287437&r1=287436&r2=287437&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CGOpenMPRuntime.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CGOpenMPRuntime.cpp Sat Nov 19 02:17:24 2016<br>
@@ -15,6 +15,7 @@<br>
 #include "CGCleanup.h"<br>
 #include "CGOpenMPRuntime.h"<br>
 #include "CodeGenFunction.h"<br>
+#include "ConstantBuilder.h"<br>
 #include "clang/AST/Decl.h"<br>
 #include "clang/AST/StmtOpenMP.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
@@ -906,18 +907,19 @@ Address CGOpenMPRuntime::<wbr>getOrCreateDefa<br>
       DefaultOpenMPPSource =<br>
           llvm::ConstantExpr::<wbr>getBitCast(<wbr>DefaultOpenMPPSource, CGM.Int8PtrTy);<br>
     }<br>
-    auto DefaultOpenMPLocation = new llvm::GlobalVariable(<br>
-        CGM.getModule(), IdentTy, /*isConstant*/ true,<br>
-        llvm::GlobalValue::<wbr>PrivateLinkage, /*Initializer*/ nullptr);<br>
+<br>
+    ConstantBuilder builder(CGM);<br>
+    auto fields = builder.beginStruct(IdentTy);<br>
+    fields.addInt(CGM.Int32Ty, 0);<br>
+    fields.addInt(CGM.Int32Ty, Flags);<br>
+    fields.addInt(CGM.Int32Ty, 0);<br>
+    fields.addInt(CGM.Int32Ty, 0);<br>
+    fields.add(<wbr>DefaultOpenMPPSource);<br>
+    auto DefaultOpenMPLocation =<br>
+      fields.finishAndCreateGlobal("<wbr>", Align, /*isConstant*/ true,<br>
+                                   llvm::GlobalValue::<wbr>PrivateLinkage);<br>
     DefaultOpenMPLocation-><wbr>setUnnamedAddr(llvm::<wbr>GlobalValue::UnnamedAddr::<wbr>Global);<br>
-    DefaultOpenMPLocation-><wbr>setAlignment(Align.<wbr>getQuantity());<br>
<br>
-    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.<wbr>Int32Ty, 0, true);<br>
-    llvm::Constant *Values[] = {Zero,<br>
-                                llvm::ConstantInt::get(CGM.<wbr>Int32Ty, Flags),<br>
-                                Zero, Zero, DefaultOpenMPPSource};<br>
-    llvm::Constant *Init = llvm::ConstantStruct::get(<wbr>IdentTy, Values);<br>
-    DefaultOpenMPLocation-><wbr>setInitializer(Init);<br>
     OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;<br>
   }<br>
   return Address(Entry, Align);<br>
@@ -2810,9 +2812,10 @@ CGOpenMPRuntime::<wbr>createOffloadingBinaryD<br>
       ".omp_offloading.entries_end")<wbr>;<br>
<br>
   // Create all device images<br>
-  llvm::SmallVector<llvm::<wbr>Constant *, 4> DeviceImagesEntires;<br>
   auto *DeviceImageTy = cast<llvm::StructType>(<br>
       CGM.getTypes().<wbr>ConvertTypeForMem(<wbr>getTgtDeviceImageQTy()));<br>
+  ConstantBuilder DeviceImagesBuilder(CGM);<br>
+  auto DeviceImagesEntries = DeviceImagesBuilder.<wbr>beginArray(DeviceImageTy);<br>
<br>
   for (unsigned i = 0; i < Devices.size(); ++i) {<br>
     StringRef T = Devices[i].getTriple();<br>
@@ -2824,22 +2827,19 @@ CGOpenMPRuntime::<wbr>createOffloadingBinaryD<br>
         M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::<wbr>ExternalLinkage,<br>
         /*Initializer=*/nullptr, Twine(".omp_offloading.img_<wbr>end.") + Twine(T));<br>
<br>
-    llvm::Constant *Dev =<br>
-        llvm::ConstantStruct::get(<wbr>DeviceImageTy, ImgBegin, ImgEnd,<br>
-                                  HostEntriesBegin, HostEntriesEnd, nullptr);<br>
-    DeviceImagesEntires.push_back(<wbr>Dev);<br>
+    auto Dev = DeviceImagesEntries.<wbr>beginStruct(DeviceImageTy);<br>
+    Dev.add(ImgBegin);<br>
+    Dev.add(ImgEnd);<br>
+    Dev.add(HostEntriesBegin);<br>
+    Dev.add(HostEntriesEnd);<br>
+    DeviceImagesEntries.add(Dev.<wbr>finish());<br>
   }<br>
<br>
   // Create device images global array.<br>
-  llvm::ArrayType *DeviceImagesInitTy =<br>
-      llvm::ArrayType::get(<wbr>DeviceImageTy, DeviceImagesEntires.size());<br>
-  llvm::Constant *DeviceImagesInit =<br>
-      llvm::ConstantArray::get(<wbr>DeviceImagesInitTy, DeviceImagesEntires);<br>
-<br>
-  llvm::GlobalVariable *DeviceImages = new llvm::GlobalVariable(<br>
-      M, DeviceImagesInitTy, /*isConstant=*/true,<br>
-      llvm::GlobalValue::<wbr>InternalLinkage, DeviceImagesInit,<br>
-      ".omp_offloading.device_<wbr>images");<br>
+  llvm::GlobalVariable *DeviceImages =<br>
+    DeviceImagesEntries.<wbr>finishAndCreateGlobal(".omp_<wbr>offloading.device_images",<br>
+                                              CGM.getPointerAlign(),<br>
+                                              /*isConstant=*/true);<br>
   DeviceImages->setUnnamedAddr(<wbr>llvm::GlobalValue::<wbr>UnnamedAddr::Global);<br>
<br>
   // This is a Zero array to be used in the creation of the constant expressions<br>
@@ -2849,16 +2849,18 @@ CGOpenMPRuntime::<wbr>createOffloadingBinaryD<br>
   // Create the target region descriptor.<br>
   auto *BinaryDescriptorTy = cast<llvm::StructType>(<br>
       CGM.getTypes().<wbr>ConvertTypeForMem(<wbr>getTgtBinaryDescriptorQTy()));<br>
-  llvm::Constant *TargetRegionsDescriptorInit = llvm::ConstantStruct::get(<br>
-      BinaryDescriptorTy, llvm::ConstantInt::get(CGM.<wbr>Int32Ty, Devices.size()),<br>
-      llvm::ConstantExpr::<wbr>getGetElementPtr(<wbr>DeviceImagesInitTy, DeviceImages,<br>
-                                           Index),<br>
-      HostEntriesBegin, HostEntriesEnd, nullptr);<br>
-<br>
-  auto *Desc = new llvm::GlobalVariable(<br>
-      M, BinaryDescriptorTy, /*isConstant=*/true,<br>
-      llvm::GlobalValue::<wbr>InternalLinkage, TargetRegionsDescriptorInit,<br>
-      ".omp_offloading.descriptor");<br>
+  ConstantBuilder DescBuilder(CGM);<br>
+  auto DescInit = DescBuilder.beginStruct(<wbr>BinaryDescriptorTy);<br>
+  DescInit.addInt(CGM.Int32Ty, Devices.size());<br>
+  DescInit.add(llvm::<wbr>ConstantExpr::<wbr>getGetElementPtr(DeviceImages-<wbr>>getValueType(),<br>
+                                                    DeviceImages,<br>
+                                                    Index));<br>
+  DescInit.add(HostEntriesBegin)<wbr>;<br>
+  DescInit.add(HostEntriesEnd);<br>
+<br>
+  auto *Desc = DescInit.<wbr>finishAndCreateGlobal(".omp_<wbr>offloading.descriptor",<br>
+                                              CGM.getPointerAlign(),<br>
+                                              /*isConstant=*/true);<br>
<br>
   // Emit code to register or unregister the descriptor at execution<br>
   // startup or closing, respectively.<br>
@@ -2906,19 +2908,24 @@ void CGOpenMPRuntime::<wbr>createOffloadEntry<br>
   Str->setUnnamedAddr(llvm::<wbr>GlobalValue::UnnamedAddr::<wbr>Global);<br>
   llvm::Constant *StrPtr = llvm::ConstantExpr::<wbr>getBitCast(Str, CGM.Int8PtrTy);<br>
<br>
+  // We can't have any padding between symbols, so we need to have 1-byte<br>
+  // alignment.<br>
+  auto Align = CharUnits::fromQuantity(1);<br>
+<br>
   // Create the entry struct.<br>
-  llvm::Constant *EntryInit = llvm::ConstantStruct::get(<br>
-      TgtOffloadEntryType, AddrPtr, StrPtr,<br>
-      llvm::ConstantInt::get(CGM.<wbr>SizeTy, Size), nullptr);<br>
-  llvm::GlobalVariable *Entry = new llvm::GlobalVariable(<br>
-      M, TgtOffloadEntryType, true, llvm::GlobalValue::<wbr>ExternalLinkage,<br>
-      EntryInit, ".omp_offloading.entry");<br>
+  ConstantBuilder EntryBuilder(CGM);<br>
+  auto EntryInit = EntryBuilder.beginStruct(<wbr>TgtOffloadEntryType);<br>
+  EntryInit.add(AddrPtr);<br>
+  EntryInit.add(StrPtr);<br>
+  EntryInit.addInt(CGM.SizeTy, Size);<br>
+  llvm::GlobalVariable *Entry =<br>
+    EntryInit.<wbr>finishAndCreateGlobal(".omp_<wbr>offloading.entry",<br>
+                                    Align,<br>
+                                    /*constant*/ true,<br>
+                                    llvm::GlobalValue::<wbr>ExternalLinkage);<br>
<br>
   // The entry has to be created in the section the linker expects it to be.<br>
   Entry->setSection(".omp_<wbr>offloading.entries");<br>
-  // We can't have any padding between symbols, so we need to have 1-byte<br>
-  // alignment.<br>
-  Entry->setAlignment(1);<br>
 }<br>
<br>
 void CGOpenMPRuntime::<wbr>createOffloadEntriesAndInfoMet<wbr>adata() {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=287437&r1=287436&r2=287437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp?rev=287437&<wbr>r1=287436&r2=287437&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>CodeGenModule.cpp Sat Nov 19 02:17:24 2016<br>
@@ -24,6 +24,7 @@<br>
 #include "CodeGenFunction.h"<br>
 #include "CodeGenPGO.h"<br>
 #include "CodeGenTBAA.h"<br>
+#include "ConstantBuilder.h"<br>
 #include "CoverageMappingGen.h"<br>
 #include "TargetInfo.h"<br>
 #include "clang/AST/ASTContext.h"<br>
@@ -731,6 +732,8 @@ void CodeGenModule::AddGlobalDtor(<wbr>llvm::<br>
 }<br>
<br>
 void CodeGenModule::EmitCtorList(<wbr>CtorList &Fns, const char *GlobalName) {<br>
+  if (Fns.empty()) return;<br>
+<br>
   // Ctor function type is void()*.<br>
   llvm::FunctionType* CtorFTy = llvm::FunctionType::get(<wbr>VoidTy, false);<br>
   llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(<wbr>CtorFTy);<br>
@@ -740,24 +743,22 @@ void CodeGenModule::EmitCtorList(<wbr>CtorLis<br>
       Int32Ty, llvm::PointerType::getUnqual(<wbr>CtorFTy), VoidPtrTy, nullptr);<br>
<br>
   // Construct the constructor and destructor arrays.<br>
-  SmallVector<llvm::Constant *, 8> Ctors;<br>
+  ConstantBuilder builder(*this);<br>
+  auto ctors = builder.beginArray(<wbr>CtorStructTy);<br>
   for (const auto &I : Fns) {<br>
-    llvm::Constant *S[] = {<br>
-        llvm::ConstantInt::get(<wbr>Int32Ty, I.Priority, false),<br>
-        llvm::ConstantExpr::<wbr>getBitCast(I.Initializer, CtorPFTy),<br>
-        (I.AssociatedData<br>
-             ? llvm::ConstantExpr::<wbr>getBitCast(I.AssociatedData, VoidPtrTy)<br>
-             : llvm::Constant::getNullValue(<wbr>VoidPtrTy))};<br>
-    Ctors.push_back(llvm::<wbr>ConstantStruct::get(<wbr>CtorStructTy, S));<br>
+    auto ctor = ctors.beginStruct(<wbr>CtorStructTy);<br>
+    ctor.addInt(Int32Ty, I.Priority);<br>
+    ctor.add(llvm::ConstantExpr::<wbr>getBitCast(I.Initializer, CtorPFTy));<br>
+    if (I.AssociatedData)<br>
+      ctor.add(llvm::ConstantExpr::<wbr>getBitCast(I.AssociatedData, VoidPtrTy));<br>
+    else<br>
+      ctor.addNullPointer(VoidPtrTy)<wbr>;<br>
+    ctors.add(ctor.finish());<br>
   }<br>
<br>
-  if (!Ctors.empty()) {<br>
-    llvm::ArrayType *AT = llvm::ArrayType::get(<wbr>CtorStructTy, Ctors.size());<br>
-    new llvm::GlobalVariable(<wbr>TheModule, AT, false,<br>
-                             llvm::GlobalValue::<wbr>AppendingLinkage,<br>
-                             llvm::ConstantArray::get(AT, Ctors),<br>
-                             GlobalName);<br>
-  }<br>
+  (void) ctors.finishAndCreateGlobal(<wbr>GlobalName, getPointerAlign(),<br>
+                                     /*constant*/ false,<br>
+                                     llvm::GlobalValue::<wbr>AppendingLinkage);<br>
   Fns.clear();<br>
 }<br>
<br>
@@ -3190,15 +3191,14 @@ CodeGenModule::<wbr>GetAddrOfConstantCFString<br>
<br>
   auto *STy = cast<llvm::StructType>(<wbr>getTypes().ConvertType(CFTy));<br>
<br>
-  llvm::Constant *Fields[4];<br>
+  ConstantBuilder Builder(*this);<br>
+  auto Fields = Builder.beginStruct(STy);<br>
<br>
   // Class pointer.<br>
-  Fields[0] = cast<llvm::ConstantExpr>(<wbr>CFConstantStringClassRef);<br>
+  Fields.add(cast<llvm::<wbr>ConstantExpr>(<wbr>CFConstantStringClassRef));<br>
<br>
   // Flags.<br>
-  llvm::Type *Ty = getTypes().ConvertType(<wbr>getContext().UnsignedIntTy);<br>
-  Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0)<br>
-                      : llvm::ConstantInt::get(Ty, 0x07C8);<br>
+  Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8);<br>
<br>
   // String pointer.<br>
   llvm::Constant *C = nullptr;<br>
@@ -3232,25 +3232,24 @@ CodeGenModule::<wbr>GetAddrOfConstantCFString<br>
                            : "__TEXT,__cstring,cstring_<wbr>literals");<br>
<br>
   // String.<br>
-  Fields[2] =<br>
+  llvm::Constant *Str =<br>
       llvm::ConstantExpr::<wbr>getGetElementPtr(GV-><wbr>getValueType(), GV, Zeros);<br>
<br>
   if (isUTF16)<br>
     // Cast the UTF16 string to the correct type.<br>
-    Fields[2] = llvm::ConstantExpr::<wbr>getBitCast(Fields[2], Int8PtrTy);<br>
+    Str = llvm::ConstantExpr::<wbr>getBitCast(Str, Int8PtrTy);<br>
+  Fields.add(Str);<br>
<br>
   // String length.<br>
-  Ty = getTypes().ConvertType(<wbr>getContext().LongTy);<br>
-  Fields[3] = llvm::ConstantInt::get(Ty, StringLength);<br>
+  auto Ty = getTypes().ConvertType(<wbr>getContext().LongTy);<br>
+  Fields.addInt(cast<llvm::<wbr>IntegerType>(Ty), StringLength);<br>
<br>
   CharUnits Alignment = getPointerAlign();<br>
<br>
   // The struct.<br>
-  C = llvm::ConstantStruct::get(STy, Fields);<br>
-  GV = new llvm::GlobalVariable(<wbr>getModule(), C->getType(), /*isConstant=*/false,<br>
-                                llvm::GlobalVariable::<wbr>PrivateLinkage, C,<br>
-                                "_unnamed_cfstring_");<br>
-  GV->setAlignment(Alignment.<wbr>getQuantity());<br>
+  GV = Fields.finishAndCreateGlobal("<wbr>_unnamed_cfstring_", Alignment,<br>
+                                    /*isConstant=*/false,<br>
+                                    llvm::GlobalVariable::<wbr>PrivateLinkage);<br>
   switch (getTriple().getObjectFormat()<wbr>) {<br>
   case llvm::Triple::<wbr>UnknownObjectFormat:<br>
     llvm_unreachable("unknown file format");<br>
@@ -3338,19 +3337,18 @@ CodeGenModule::<wbr>GetAddrOfConstantString(c<br>
     NSConstantStringType = cast<llvm::StructType>(<wbr>getTypes().ConvertType(NSTy));<br>
   }<br>
<br>
-  llvm::Constant *Fields[3];<br>
+  ConstantBuilder Builder(*this);<br>
+  auto Fields = Builder.beginStruct(<wbr>NSConstantStringType);<br>
<br>
   // Class pointer.<br>
-  Fields[0] = cast<llvm::ConstantExpr>(V);<br>
+  Fields.add(cast<llvm::<wbr>ConstantExpr>(V));<br>
<br>
   // String pointer.<br>
   llvm::Constant *C =<br>
       llvm::ConstantDataArray::<wbr>getString(VMContext, Entry.first());<br>
<br>
-  llvm::GlobalValue::<wbr>LinkageTypes Linkage;<br>
-  bool isConstant;<br>
-  Linkage = llvm::GlobalValue::<wbr>PrivateLinkage;<br>
-  isConstant = !LangOpts.WritableStrings;<br>
+  llvm::GlobalValue::<wbr>LinkageTypes Linkage = llvm::GlobalValue::<wbr>PrivateLinkage;<br>
+  bool isConstant = !LangOpts.WritableStrings;<br>
<br>
   auto *GV = new llvm::GlobalVariable(<wbr>getModule(), C->getType(), isConstant,<br>
                                       Linkage, C, ".str");<br>
@@ -3359,20 +3357,17 @@ CodeGenModule::<wbr>GetAddrOfConstantString(c<br>
   // of the string is via this class initializer.<br>
   CharUnits Align = getContext().<wbr>getTypeAlignInChars(<wbr>getContext().CharTy);<br>
   GV->setAlignment(Align.<wbr>getQuantity());<br>
-  Fields[1] =<br>
-      llvm::ConstantExpr::<wbr>getGetElementPtr(GV-><wbr>getValueType(), GV, Zeros);<br>
+  Fields.add(<br>
+      llvm::ConstantExpr::<wbr>getGetElementPtr(GV-><wbr>getValueType(), GV, Zeros));<br>
<br>
   // String length.<br>
-  llvm::Type *Ty = getTypes().ConvertType(<wbr>getContext().UnsignedIntTy);<br>
-  Fields[2] = llvm::ConstantInt::get(Ty, StringLength);<br>
+  Fields.addInt(IntTy, StringLength);<br>
<br>
   // The struct.<br>
   CharUnits Alignment = getPointerAlign();<br>
-  C = llvm::ConstantStruct::get(<wbr>NSConstantStringType, Fields);<br>
-  GV = new llvm::GlobalVariable(<wbr>getModule(), C->getType(), true,<br>
-                                llvm::GlobalVariable::<wbr>PrivateLinkage, C,<br>
-                                "_unnamed_nsstring_");<br>
-  GV->setAlignment(Alignment.<wbr>getQuantity());<br>
+  GV = Fields.finishAndCreateGlobal("<wbr>_unnamed_nsstring_", Alignment,<br>
+                                    /*constant*/ true,<br>
+                                    llvm::GlobalVariable::<wbr>PrivateLinkage);<br>
   const char *NSStringSection = "__OBJC,__cstring_object,<wbr>regular,no_dead_strip";<br>
   const char *NSStringNonFragileABISection =<br>
       "__DATA,__objc_stringobj,<wbr>regular,no_dead_strip";<br>
<br>
Added: cfe/trunk/lib/CodeGen/<wbr>ConstantBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.h?rev=287437&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>ConstantBuilder.h?rev=287437&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/<wbr>ConstantBuilder.h (added)<br>
+++ cfe/trunk/lib/CodeGen/<wbr>ConstantBuilder.h Sat Nov 19 02:17:24 2016<br>
@@ -0,0 +1,274 @@<br>
+//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+//<br>
+// This class provides a convenient interface for building complex<br>
+// global initializers.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_LIB_CODEGEN_<wbr>CONSTANTBUILDER_H<br>
+#define LLVM_CLANG_LIB_CODEGEN_<wbr>CONSTANTBUILDER_H<br>
+<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/SmallVector.h"<br>
+#include "llvm/IR/Constants.h"<br>
+<br>
+#include "CodeGenModule.h"<br>
+<br>
+namespace clang {<br>
+namespace CodeGen {<br>
+<br>
+class ConstantBuilder;<br>
+<br>
+/// A convenience builder class for complex constant initializers,<br>
+/// especially for anonymous global structures used by various language<br>
+/// runtimes.<br>
+///<br>
+/// The basic usage pattern is expected to be something like:<br>
+///    ConstantBuilder builder(CGM);<br>
+///    auto toplevel = builder.beginStruct();<br>
+///    toplevel.addInt(CGM.SizeTy, widgets.size());<br>
+///    auto widgetArray = builder.beginArray();<br>
+///    for (auto &widget : widgets) {<br>
+///      auto widgetDesc = widgetArray.beginStruct();<br>
+///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());<br>
+///      widgetDesc.add(CGM.<wbr>GetAddrOfConstantString(<wbr>widget.getName()));<br>
+///      widgetDesc.add(CGM.<wbr>GetAddrOfGlobal(widget.<wbr>getInitializerDecl()));<br>
+///      widgetArray.add(widgetDesc.<wbr>finish());<br>
+///    }<br>
+///    toplevel.add(widgetArray.<wbr>finish());<br>
+///    auto global = toplevel.<wbr>finishAndCreateGlobal("WIDGET_<wbr>LIST", Align,<br>
+///                                                 /*constant*/ true);<br>
+class ConstantBuilder {<br>
+  CodeGenModule &CGM;<br>
+  llvm::SmallVector<llvm::<wbr>Constant*, 16> Buffer;<br>
+  bool Frozen = false;<br>
+<br>
+public:<br>
+  explicit ConstantBuilder(CodeGenModule &CGM) : CGM(CGM) {}<br>
+<br>
+  ~ConstantBuilder() {<br>
+    assert(Buffer.empty() && "didn't claim all values out of buffer");<br>
+  }<br>
+<br>
+  class ArrayBuilder;<br>
+  class StructBuilder;<br>
+<br>
+  class AggregateBuilder {<br>
+  protected:<br>
+    ConstantBuilder &Builder;<br>
+    AggregateBuilder *Parent;<br>
+    size_t Begin;<br>
+    bool Finished = false;<br>
+    bool Frozen = false;<br>
+<br>
+    AggregateBuilder(<wbr>ConstantBuilder &builder, AggregateBuilder *parent)<br>
+        : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {<br>
+      if (parent) {<br>
+        assert(!parent->Frozen && "parent already has child builder active");<br>
+        parent->Frozen = true;<br>
+      } else {<br>
+        assert(!builder.Frozen && "builder already has child builder active");<br>
+        builder.Frozen = true;<br>
+      }<br>
+    }<br>
+<br>
+    ~AggregateBuilder() {<br>
+      assert(Finished && "didn't claim value from aggregate builder");<br>
+    }<br>
+<br>
+    void markFinished() {<br>
+      assert(!Frozen && "child builder still active");<br>
+      assert(!Finished && "builder already finished");<br>
+      Finished = true;<br>
+      if (Parent) {<br>
+        assert(Parent->Frozen &&<br>
+               "parent not frozen while child builder active");<br>
+        Parent->Frozen = false;<br>
+      } else {<br>
+        assert(Builder.Frozen &&<br>
+               "builder not frozen while child builder active");<br>
+        Builder.Frozen = false;<br>
+      }<br>
+    }<br>
+<br>
+  public:<br>
+    // Not copyable.<br>
+    AggregateBuilder(const AggregateBuilder &) = delete;<br>
+    AggregateBuilder &operator=(const AggregateBuilder &) = delete;<br>
+<br>
+    // Movable, mostly to allow returning.  But we have to write this out<br>
+    // properly to satisfy the assert in the destructor.<br>
+    AggregateBuilder(<wbr>AggregateBuilder &&other)<br>
+      : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),<br>
+        Finished(other.Finished), Frozen(other.Frozen) {<br>
+      other.Finished = false;<br>
+    }<br>
+    AggregateBuilder &operator=(AggregateBuilder &&other) = delete;<br>
+<br>
+    void add(llvm::Constant *value) {<br>
+      assert(!Finished && "cannot add more values after finishing builder");<br>
+      Builder.Buffer.push_back(<wbr>value);<br>
+    }<br>
+<br>
+    void addSize(CharUnits size) {<br>
+      add(Builder.CGM.getSize(size))<wbr>;<br>
+    }<br>
+<br>
+    void addInt(llvm::IntegerType *intTy, uint64_t value,<br>
+                bool isSigned = false) {<br>
+      add(llvm::ConstantInt::get(<wbr>intTy, value, isSigned));<br>
+    }<br>
+<br>
+    void addNullPointer(llvm::<wbr>PointerType *ptrTy) {<br>
+      add(llvm::ConstantPointerNull:<wbr>:get(ptrTy));<br>
+    }<br>
+<br>
+    ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition<wbr>(<br>
+                             llvm::SmallVectorImpl<llvm::<wbr>Constant*> &indices) {<br>
+      getGEPIndicesTo(indices, Builder.Buffer.size());<br>
+      return indices;<br>
+    }<br>
+<br>
+    ArrayBuilder beginArray(llvm::Type *eltTy = nullptr);<br>
+    StructBuilder beginStruct(llvm::StructType *structTy = nullptr);<br>
+<br>
+  private:<br>
+    void getGEPIndicesTo(llvm::<wbr>SmallVectorImpl<llvm::<wbr>Constant*> &indices,<br>
+                         size_t position) const {<br>
+      // Recurse on the parent builder if present.<br>
+      if (Parent) {<br>
+        Parent->getGEPIndicesTo(<wbr>indices, Begin);<br>
+<br>
+      // Otherwise, add an index to drill into the first level of pointer.<br>
+      } else {<br>
+        assert(indices.empty());<br>
+        indices.push_back(llvm::<wbr>ConstantInt::get(Builder.CGM.<wbr>SizeTy, 0));<br>
+      }<br>
+<br>
+      assert(position >= Begin);<br>
+      indices.push_back(llvm::<wbr>ConstantInt::get(Builder.CGM.<wbr>SizeTy,<br>
+                                               position - Begin));<br>
+    }<br>
+  };<br>
+<br>
+  class ArrayBuilder : public AggregateBuilder {<br>
+    llvm::Type *EltTy;<br>
+    friend class ConstantBuilder;<br>
+    ArrayBuilder(ConstantBuilder &builder, AggregateBuilder *parent,<br>
+                 llvm::Type *eltTy)<br>
+      : AggregateBuilder(builder, parent), EltTy(eltTy) {}<br>
+  public:<br>
+    size_t size() const {<br>
+      assert(!Finished);<br>
+      assert(!Frozen);<br>
+      assert(Begin <= Builder.Buffer.size());<br>
+      return Builder.Buffer.size() - Begin;<br>
+    }<br>
+<br>
+    /// Form an array constant from the values that have been added to this<br>
+    /// builder.<br>
+    llvm::Constant *finish() {<br>
+      markFinished();<br>
+<br>
+      auto &buffer = Builder.Buffer;<br>
+      assert((Begin < buffer.size() ||<br>
+              (Begin == buffer.size() && EltTy))<br>
+             && "didn't add any array elements without element type");<br>
+      auto elts = llvm::makeArrayRef(buffer).<wbr>slice(Begin);<br>
+      auto eltTy = EltTy ? EltTy : elts[0]->getType();<br>
+      auto type = llvm::ArrayType::get(eltTy, elts.size());<br>
+      auto constant = llvm::ConstantArray::get(type, elts);<br>
+      buffer.erase(buffer.begin() + Begin, buffer.end());<br>
+      return constant;<br>
+    }<br>
+<br>
+    template <class... As><br>
+    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {<br>
+      assert(!Parent && "finishing non-root builder");<br>
+      return Builder.createGlobal(finish(), std::forward<As>(args)...);<br>
+    }<br>
+  };<br>
+<br>
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {<br>
+    return ArrayBuilder(*this, nullptr, eltTy);<br>
+  }<br>
+<br>
+  class StructBuilder : public AggregateBuilder {<br>
+    llvm::StructType *Ty;<br>
+    friend class ConstantBuilder;<br>
+    StructBuilder(ConstantBuilder &builder, AggregateBuilder *parent,<br>
+                  llvm::StructType *ty)<br>
+      : AggregateBuilder(builder, parent), Ty(ty) {}<br>
+  public:<br>
+    /// Finish the struct.<br>
+    llvm::Constant *finish(bool packed = false) {<br>
+      markFinished();<br>
+<br>
+      auto &buffer = Builder.Buffer;<br>
+      assert(Begin < buffer.size() && "didn't add any struct elements?");<br>
+      auto elts = llvm::makeArrayRef(buffer).<wbr>slice(Begin);<br>
+<br>
+      llvm::Constant *constant;<br>
+      if (Ty) {<br>
+        constant = llvm::ConstantStruct::get(Ty, elts);<br>
+      } else {<br>
+        constant = llvm::ConstantStruct::getAnon(<wbr>elts, packed);<br>
+      }<br>
+<br>
+      buffer.erase(buffer.begin() + Begin, buffer.end());<br>
+      return constant;<br>
+    }<br>
+<br>
+    template <class... As><br>
+    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {<br>
+      assert(!Parent && "finishing non-root builder");<br>
+      return Builder.createGlobal(finish(), std::forward<As>(args)...);<br>
+    }<br>
+  };<br>
+<br>
+  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {<br>
+    return StructBuilder(*this, nullptr, structTy);<br>
+  }<br>
+<br>
+  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,<br>
+                                     StringRef name,<br>
+                                     CharUnits alignment,<br>
+                                     bool constant = false,<br>
+                                     llvm::GlobalValue::<wbr>LinkageTypes linkage<br>
+                                       = llvm::GlobalValue::<wbr>InternalLinkage,<br>
+                                     unsigned addressSpace = 0) {<br>
+    auto GV = new llvm::GlobalVariable(CGM.<wbr>getModule(),<br>
+                                       initializer->getType(),<br>
+                                       constant,<br>
+                                       linkage,<br>
+                                       initializer,<br>
+                                       name,<br>
+                                       /*insert before*/ nullptr,<br>
+                                       llvm::GlobalValue::<wbr>NotThreadLocal,<br>
+                                       addressSpace);<br>
+    GV->setAlignment(alignment.<wbr>getQuantity());<br>
+    return GV;<br>
+  }<br>
+};<br>
+<br>
+inline ConstantBuilder::ArrayBuilder<br>
+ConstantBuilder::<wbr>AggregateBuilder::beginArray(<wbr>llvm::Type *eltTy) {<br>
+  return ArrayBuilder(Builder, this, eltTy);<br>
+}<br>
+<br>
+inline ConstantBuilder::StructBuilder<br>
+ConstantBuilder::<wbr>AggregateBuilder::beginStruct(<wbr>llvm::StructType *structTy) {<br>
+  return StructBuilder(Builder, this, structTy);<br>
+}<br>
+<br>
+}  // end namespace CodeGen<br>
+}  // end namespace clang<br>
+<br>
+#endif<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>