<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 21, 2016, at 3:01 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com" class="">gkistanova@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">This revision also added few warning to this builder:<br class=""><a href="http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/388" class="">http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/388</a><br class=""><br class="">/home/buildbot/Buildbot/Slave1a/clang-3stage-ubuntu/llvm.src/tools/clang/lib/CodeGen/CGBlocks.cpp:193:23: warning: unused variable 'BlockHeaderSize' [-Wunused-const-variable]<br class="">1 warning generated.<br class="">/home/buildbot/Buildbot/Slave1a/clang-3stage-ubuntu/llvm.src/tools/clang/lib/CodeGen/CGBlocks.cpp:193:23: warning: unused variable 'BlockHeaderSize' [-Wunused-const-variable]<br class="">1 warning generated.<br class=""><br class="">Please have a look at this?<br class=""></div></div></blockquote><div><br class=""></div>Fixed in r287691.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class="">Thanks<br class=""><br class="">Galina<br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sat, Nov 19, 2016 at 4:11 PM, Galina Kistanova <span dir="ltr" class=""><<a href="mailto:gkistanova@gmail.com" target="_blank" class="">gkistanova@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class=""><div class=""><div class="">Thanks, John!<br class=""></div>That fixed the problem.<br class=""><br class=""><br class=""></div>Thanks<br class=""><br class=""></div>Galina<br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote"><div class=""><div class="h5">On Sat, Nov 19, 2016 at 1:22 PM, John McCall <span dir="ltr" class=""><<a href="mailto:rjmccall@apple.com" target="_blank" class="">rjmccall@apple.com</a>></span> wrote:<br class=""></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class="h5"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 19, 2016, at 1:06 PM, Galina Kistanova <<a href="mailto:gkistanova@gmail.com" target="_blank" class="">gkistanova@gmail.com</a>> wrote:</div><br class="m_2058076283102365739m_-8481798216384043103Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><div class="">Hello John,<br class=""><br class=""></div>This change has introduced alignment problems for some variables.<br class=""><br class="">The build bots are broken.<br class=""><a href="http://lab.llvm.org:8011/builders/clang-3stage-ubuntu/builds/355" target="_blank" class="">http://lab.llvm.org:8011/build<wbr class="">ers/clang-3stage-ubuntu/builds<wbr class="">/355</a><br class=""><a href="http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/308" target="_blank" class="">http://lab.llvm.org:8011/build<wbr class="">ers/clang-with-lto-ubuntu/<wbr class="">builds/308</a><br class=""><br class=""></div>Could you take care of the issue, please?<br class=""></div></div></div></div></blockquote><div class=""><br class=""></div>Please let me know if r287458 fixes the problem.</div><div class=""><br class=""></div><div class="">John.</div></div></div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div>Thanks<br class=""><br class=""></div>Galina<br class=""><br class=""><div class=""><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote"><div class=""><div class="h5">On Sat, Nov 19, 2016 at 12:17 AM, John McCall via cfe-commits <span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span> wrote:<br class=""></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""><div class="h5">Author: rjmccall<br class="">
Date: Sat Nov 19 02:17:24 2016<br class="">
New Revision: 287437<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=287437&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject?rev=287437&view=rev</a><br class="">
Log:<br class="">
Introduce a helper class for building complex constant initializers.  NFC.<br class="">
<br class="">
I've adopted this in most of the places it makes sense, but v-tables<br class="">
and CGObjCMac will need a second pass.<br class="">
<br class="">
Added:<br class="">
    cfe/trunk/lib/CodeGen/Constant<wbr class="">Builder.h<br class="">
Modified:<br class="">
    cfe/trunk/include/clang/AST/De<wbr class="">clObjC.h<br class="">
    cfe/trunk/lib/CodeGen/CGBlocks<wbr class="">.cpp<br class="">
    cfe/trunk/lib/CodeGen/CGCUDANV<wbr class="">.cpp<br class="">
    cfe/trunk/lib/CodeGen/CGObjCGN<wbr class="">U.cpp<br class="">
    cfe/trunk/lib/CodeGen/CGOpenMP<wbr class="">Runtime.cpp<br class="">
    cfe/trunk/lib/CodeGen/CodeGenM<wbr class="">odule.cpp<br class="">
<br class="">
Modified: cfe/trunk/include/clang/AST/De<wbr class="">clObjC.h<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/include/clang/<wbr class="">AST/DeclObjC.h?rev=287437&r1=2<wbr class="">87436&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/include/clang/AST/De<wbr class="">clObjC.h (original)<br class="">
+++ cfe/trunk/include/clang/AST/De<wbr class="">clObjC.h Sat Nov 19 02:17:24 2016<br class="">
@@ -870,6 +870,9 @@ public:<br class="">
   PropertyControl getPropertyImplementation() const {<br class="">
     return PropertyControl(PropertyImplem<wbr class="">entation);<br class="">
   }<br class="">
+  bool isOptional() const {<br class="">
+    return getPropertyImplementation() == PropertyControl::Optional;<br class="">
+  }<br class="">
<br class="">
   void setPropertyIvarDecl(ObjCIvarDe<wbr class="">cl *Ivar) {<br class="">
     PropertyIvarDecl = Ivar;<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGBlocks<wbr class="">.cpp<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/CG<wbr class="">Blocks.cpp?rev=287437&r1=28743<wbr class="">6&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGBlocks<wbr class="">.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGBlocks<wbr class="">.cpp Sat Nov 19 02:17:24 2016<br class="">
@@ -16,6 +16,7 @@<br class="">
 #include "CGObjCRuntime.h"<br class="">
 #include "CodeGenFunction.h"<br class="">
 #include "CodeGenModule.h"<br class="">
+#include "ConstantBuilder.h"<br class="">
 #include "clang/AST/DeclObjC.h"<br class="">
 #include "llvm/ADT/SmallSet.h"<br class="">
 #include "llvm/IR/CallSite.h"<br class="">
@@ -77,63 +78,63 @@ static llvm::Constant *buildBlockDescrip<br class="">
                                             const CGBlockInfo &blockInfo) {<br class="">
   ASTContext &C = CGM.getContext();<br class="">
<br class="">
-  llvm::Type *ulong = CGM.getTypes().ConvertType(C.U<wbr class="">nsignedLongTy);<br class="">
-  llvm::Type *i8p = nullptr;<br class="">
+  llvm::IntegerType *ulong =<br class="">
+    cast<llvm::IntegerType>(CGM.ge<wbr class="">tTypes().ConvertType(C.Unsigne<wbr class="">dLongTy));<br class="">
+  llvm::PointerType *i8p = nullptr;<br class="">
   if (CGM.getLangOpts().OpenCL)<br class="">
     i8p =<br class="">
       llvm::Type::getInt8PtrTy(<br class="">
            CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS<wbr class="">::opencl_constant));<br class="">
   else<br class="">
-    i8p = CGM.getTypes().ConvertType(C.V<wbr class="">oidPtrTy);<br class="">
+    i8p = CGM.VoidPtrTy;<br class="">
<br class="">
-  SmallVector<llvm::Constant*, 6> elements;<br class="">
+  ConstantBuilder builder(CGM);<br class="">
+  auto elements = builder.beginStruct();<br class="">
<br class="">
   // reserved<br class="">
-  elements.push_back(llvm::Const<wbr class="">antInt::get(ulong, 0));<br class="">
+  elements.addInt(ulong, 0);<br class="">
<br class="">
   // Size<br class="">
   // FIXME: What is the right way to say this doesn't fit?  We should give<br class="">
   // a user diagnostic in that case.  Better fix would be to change the<br class="">
   // API to size_t.<br class="">
-  elements.push_back(llvm::Const<wbr class="">antInt::get(ulong,<br class="">
-                                            blockInfo.BlockSize.getQuantit<wbr class="">y()));<br class="">
+  elements.addInt(ulong, blockInfo.BlockSize.getQuantit<wbr class="">y());<br class="">
<br class="">
   // Optional copy/dispose helpers.<br class="">
   if (blockInfo.NeedsCopyDispose) {<br class="">
     // copy_func_helper_decl<br class="">
-    elements.push_back(buildCopyHe<wbr class="">lper(CGM, blockInfo));<br class="">
+    elements.add(buildCopyHelper(C<wbr class="">GM, blockInfo));<br class="">
<br class="">
     // destroy_func_decl<br class="">
-    elements.push_back(buildDispos<wbr class="">eHelper(CGM, blockInfo));<br class="">
+    elements.add(buildDisposeHelpe<wbr class="">r(CGM, blockInfo));<br class="">
   }<br class="">
<br class="">
   // Signature.  Mandatory ObjC-style method descriptor @encode sequence.<br class="">
   std::string typeAtEncoding =<br class="">
     CGM.getContext().getObjCEncod<wbr class="">ingForBlock(blockInfo.getBlock<wbr class="">Expr());<br class="">
-  elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(<br class="">
+  elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(<br class="">
     CGM.GetAddrOfConstantCString(<wbr class="">typeAtEncoding).getPointer(), i8p));<br class="">
<br class="">
   // GC layout.<br class="">
   if (C.getLangOpts().ObjC1) {<br class="">
     if (CGM.getLangOpts().getGC() != LangOptions::NonGC)<br class="">
-      elements.push_back(CGM.getObjC<wbr class="">Runtime().BuildGCBlockLayout(C<wbr class="">GM, blockInfo));<br class="">
+      elements.add(CGM.getObjCRuntim<wbr class="">e().BuildGCBlockLayout(CGM, blockInfo));<br class="">
     else<br class="">
-      elements.push_back(CGM.getObjC<wbr class="">Runtime().BuildRCBlockLayout(C<wbr class="">GM, blockInfo));<br class="">
+      elements.add(CGM.getObjCRuntim<wbr class="">e().BuildRCBlockLayout(CGM, blockInfo));<br class="">
   }<br class="">
   else<br class="">
-    elements.push_back(llvm::Const<wbr class="">ant::getNullValue(i8p));<br class="">
-<br class="">
-  llvm::Constant *init = llvm::ConstantStruct::getAnon(<wbr class="">elements);<br class="">
+    elements.addNullPointer(i8p);<br class="">
<br class="">
   unsigned AddrSpace = 0;<br class="">
   if (C.getLangOpts().OpenCL)<br class="">
     AddrSpace = C.getTargetAddressSpace(LangAS<wbr class="">::opencl_constant);<br class="">
+<br class="">
   llvm::GlobalVariable *global =<br class="">
-    new llvm::GlobalVariable(CGM.getMo<wbr class="">dule(), init->getType(), true,<br class="">
-                             llvm::GlobalValue::InternalLi<wbr class="">nkage,<br class="">
-                             init, "__block_descriptor_tmp", nullptr,<br class="">
-                             llvm::GlobalValue::NotThreadL<wbr class="">ocal,<br class="">
-                             AddrSpace);<br class="">
+    elements.finishAndCreateGlobal<wbr class="">("__block_descriptor_tmp",<br class="">
+                                   CGM.getPointerAlign(),<br class="">
+                                   /*constant*/ true,<br class="">
+                                   llvm::GlobalValue::InternalLi<wbr class="">nkage,<br class="">
+                                   AddrSpace);<br class="">
<br class="">
   return llvm::ConstantExpr::getBitCast<wbr class="">(global, CGM.getBlockDescriptorType());<br class="">
 }<br class="">
@@ -1080,36 +1081,31 @@ static llvm::Constant *buildGlobalBlock(<br class="">
   assert(blockInfo.CanBeGlobal)<wbr class="">;<br class="">
<br class="">
   // Generate the constants for the block literal initializer.<br class="">
-  llvm::Constant *fields[BlockHeaderSize];<br class="">
+  ConstantBuilder builder(CGM);<br class="">
+  auto fields = builder.beginStruct();<br class="">
<br class="">
   // isa<br class="">
-  fields[0] = CGM.getNSConcreteGlobalBlock()<wbr class="">;<br class="">
+  fields.add(CGM.getNSConcreteGl<wbr class="">obalBlock());<br class="">
<br class="">
   // __flags<br class="">
   BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;<br class="">
   if (blockInfo.UsesStret) flags |= BLOCK_USE_STRET;<br class="">
<br class="">
-  fields[1] = llvm::ConstantInt::get(CGM.Int<wbr class="">Ty, flags.getBitMask());<br class="">
+  fields.addInt(CGM.IntTy, flags.getBitMask());<br class="">
<br class="">
   // Reserved<br class="">
-  fields[2] = llvm::Constant::getNullValue(C<wbr class="">GM.IntTy);<br class="">
+  fields.addInt(CGM.IntTy, 0);<br class="">
<br class="">
   // Function<br class="">
-  fields[3] = blockFn;<br class="">
+  fields.add(blockFn);<br class="">
<br class="">
   // Descriptor<br class="">
-  fields[4] = buildBlockDescriptor(CGM, blockInfo);<br class="">
-<br class="">
-  llvm::Constant *init = llvm::ConstantStruct::getAnon(<wbr class="">fields);<br class="">
+  fields.add(buildBlockDescripto<wbr class="">r(CGM, blockInfo));<br class="">
<br class="">
-  llvm::GlobalVariable *literal =<br class="">
-    new llvm::GlobalVariable(CGM.getMo<wbr class="">dule(),<br class="">
-                             init->getType(),<br class="">
-                             /*constant*/ true,<br class="">
-                             llvm::GlobalVariable::Interna<wbr class="">lLinkage,<br class="">
-                             init,<br class="">
-                             "__block_literal_global");<br class="">
-  literal->setAlignment(blockInf<wbr class="">o.BlockAlign.getQuantity());<br class="">
+  llvm::Constant *literal =<br class="">
+    fields.finishAndCreateGlobal("<wbr class="">__block_literal_global",<br class="">
+                                 blockInfo.BlockAlign,<br class="">
+                                 /*constant*/ true);<br class="">
<br class="">
   // Return a constant of the appropriately-casted type.<br class="">
   llvm::Type *requiredType =<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGCUDANV<wbr class="">.cpp<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/CG<wbr class="">CUDANV.cpp?rev=287437&r1=28743<wbr class="">6&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGCUDANV<wbr class="">.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGCUDANV<wbr class="">.cpp Sat Nov 19 02:17:24 2016<br class="">
@@ -15,6 +15,7 @@<br class="">
 #include "CGCUDARuntime.h"<br class="">
 #include "CodeGenFunction.h"<br class="">
 #include "CodeGenModule.h"<br class="">
+#include "ConstantBuilder.h"<br class="">
 #include "clang/AST/Decl.h"<br class="">
 #include "llvm/IR/BasicBlock.h"<br class="">
 #include "llvm/IR/CallSite.h"<br class="">
@@ -29,7 +30,8 @@ namespace {<br class="">
 class CGNVCUDARuntime : public CGCUDARuntime {<br class="">
<br class="">
 private:<br class="">
-  llvm::Type *IntTy, *SizeTy, *VoidTy;<br class="">
+  llvm::IntegerType *IntTy, *SizeTy;<br class="">
+  llvm::Type *VoidTy;<br class="">
   llvm::PointerType *CharPtrTy, *VoidPtrTy, *VoidPtrPtrTy;<br class="">
<br class="">
   /// Convenience reference to LLVM Context<br class="">
@@ -95,9 +97,9 @@ CGNVCUDARuntime::CGNVCUDARunti<wbr class="">me(CodeGen<br class="">
   CodeGen::CodeGenTypes &Types = CGM.getTypes();<br class="">
   ASTContext &Ctx = CGM.getContext();<br class="">
<br class="">
-  IntTy = Types.ConvertType(Ctx.IntTy);<br class="">
-  SizeTy = Types.ConvertType(Ctx.getSizeT<wbr class="">ype());<br class="">
-  VoidTy = llvm::Type::getVoidTy(Context)<wbr class="">;<br class="">
+  IntTy = CGM.IntTy;<br class="">
+  SizeTy = CGM.SizeTy;<br class="">
+  VoidTy = CGM.VoidTy;<br class="">
<br class="">
   CharPtrTy = llvm::PointerType::getUnqual(T<wbr class="">ypes.ConvertType(Ctx.CharTy));<br class="">
   VoidPtrTy = cast<llvm::PointerType>(Types.<wbr class="">ConvertType(Ctx.VoidPtrTy));<br class="">
@@ -296,16 +298,21 @@ llvm::Function *CGNVCUDARuntime::makeMod<br class="">
         CGM.getTriple().isMacOSX() ? "__NV_CUDA,__fatbin" : ".nvFatBinSegment";<br class="">
<br class="">
     // Create initialized wrapper structure that points to the loaded GPU binary<br class="">
-    llvm::Constant *Values[] = {<br class="">
-        llvm::ConstantInt::get(IntTy, 0x466243b1), // Fatbin wrapper magic.<br class="">
-        llvm::ConstantInt::get(IntTy, 1),          // Fatbin version.<br class="">
-        makeConstantString(GpuBinaryOr<wbr class="">Err.get()->getBuffer(), // Data.<br class="">
-                           "", FatbinConstantName, 8),<br class="">
-        llvm::ConstantPointerNull::get<wbr class="">(VoidPtrTy)}; // Unused in fatbin v1.<br class="">
-    llvm::GlobalVariable *FatbinWrapper = new llvm::GlobalVariable(<br class="">
-        TheModule, FatbinWrapperTy, true, llvm::GlobalValue::InternalLin<wbr class="">kage,<br class="">
-        llvm::ConstantStruct::get(Fatb<wbr class="">inWrapperTy, Values),<br class="">
-        "__cuda_fatbin_wrapper");<br class="">
+    ConstantBuilder Builder(CGM);<br class="">
+    auto Values = Builder.beginStruct(FatbinWrap<wbr class="">perTy);<br class="">
+    // Fatbin wrapper magic.<br class="">
+    Values.addInt(IntTy, 0x466243b1);<br class="">
+    // Fatbin version.<br class="">
+    Values.addInt(IntTy, 1);<br class="">
+    // Data.<br class="">
+    Values.add(makeConstantString(<wbr class="">GpuBinaryOrErr.get()->getBuffe<wbr class="">r(),<br class="">
+                                  "", FatbinConstantName, 8));<br class="">
+    // Unused in fatbin v1.<br class="">
+    Values.add(llvm::ConstantPoint<wbr class="">erNull::get(VoidPtrTy));<br class="">
+    llvm::GlobalVariable *FatbinWrapper =<br class="">
+      Values.finishAndCreateGlobal("<wbr class="">__cuda_fatbin_wrapper",<br class="">
+                                   CGM.getPointerAlign(),<br class="">
+                                   /*constant*/ true);<br class="">
     FatbinWrapper->setSection(Fat<wbr class="">binSectionName);<br class="">
<br class="">
     // GpuBinaryHandle = __cudaRegisterFatBinary(&Fatbi<wbr class="">nWrapper);<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGObjCGN<wbr class="">U.cpp<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/CG<wbr class="">ObjCGNU.cpp?rev=287437&r1=2874<wbr class="">36&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGObjCGN<wbr class="">U.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGObjCGN<wbr class="">U.cpp Sat Nov 19 02:17:24 2016<br class="">
@@ -18,6 +18,7 @@<br class="">
 #include "CGCleanup.h"<br class="">
 #include "CodeGenFunction.h"<br class="">
 #include "CodeGenModule.h"<br class="">
+#include "ConstantBuilder.h"<br class="">
 #include "clang/AST/ASTContext.h"<br class="">
 #include "clang/AST/Decl.h"<br class="">
 #include "clang/AST/DeclObjC.h"<br class="">
@@ -190,47 +191,17 @@ protected:<br class="">
   /// Generates a global structure, initialized by the elements in the vector.<br class="">
   /// The element types must match the types of the structure elements in the<br class="">
   /// first argument.<br class="">
-  llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,<br class="">
-                                   ArrayRef<llvm::Constant *> V,<br class="">
+  llvm::GlobalVariable *MakeGlobal(llvm::Constant *C,<br class="">
                                    CharUnits Align,<br class="">
                                    StringRef Name="",<br class="">
                                    llvm::GlobalValue::LinkageType<wbr class="">s linkage<br class="">
                                          =llvm::GlobalValue::InternalLi<wbr class="">nkage) {<br class="">
-    llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);<br class="">
-    auto GV = new llvm::GlobalVariable(TheModule<wbr class="">, Ty, false,<br class="">
+    auto GV = new llvm::GlobalVariable(TheModule<wbr class="">, C->getType(), false,<br class="">
                                        linkage, C, Name);<br class="">
     GV->setAlignment(Align.getQua<wbr class="">ntity());<br class="">
     return GV;<br class="">
   }<br class="">
<br class="">
-  /// Generates a global array.  The vector must contain the same number of<br class="">
-  /// elements that the array type declares, of the type specified as the array<br class="">
-  /// element type.<br class="">
-  llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,<br class="">
-                                   ArrayRef<llvm::Constant *> V,<br class="">
-                                   CharUnits Align,<br class="">
-                                   StringRef Name="",<br class="">
-                                   llvm::GlobalValue::LinkageTyp<wbr class="">es linkage<br class="">
-                                         =llvm::GlobalValue::InternalL<wbr class="">inkage) {<br class="">
-    llvm::Constant *C = llvm::ConstantArray::get(Ty, V);<br class="">
-    auto GV = new llvm::GlobalVariable(TheModule<wbr class="">, Ty, false,<br class="">
-                                       linkage, C, Name);<br class="">
-    GV->setAlignment(Align.getQuan<wbr class="">tity());<br class="">
-    return GV;<br class="">
-  }<br class="">
-<br class="">
-  /// Generates a global array, inferring the array type from the specified<br class="">
-  /// element type and the size of the initialiser.<br class="">
-  llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty,<br class="">
-                                        ArrayRef<llvm::Constant *> V,<br class="">
-                                        CharUnits Align,<br class="">
-                                        StringRef Name="",<br class="">
-                                        llvm::GlobalValue::LinkageType<wbr class="">s linkage<br class="">
-                                         =llvm::GlobalValue::InternalL<wbr class="">inkage) {<br class="">
-    llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());<br class="">
-    return MakeGlobal(ArrayTy, V, Align, Name, linkage);<br class="">
-  }<br class="">
-<br class="">
   /// Returns a property name and encoding string.<br class="">
   llvm::Constant *MakePropertyEncodingString(co<wbr class="">nst ObjCPropertyDecl *PD,<br class="">
                                              const Decl *Container) {<br class="">
@@ -251,7 +222,7 @@ protected:<br class="">
   }<br class="">
<br class="">
   /// Push the property attributes into two structure fields.<br class="">
-  void PushPropertyAttributes(std::ve<wbr class="">ctor<llvm::Constant*> &Fields,<br class="">
+  void PushPropertyAttributes(Constan<wbr class="">tBuilder::StructBuilder &Fields,<br class="">
       ObjCPropertyDecl *property, bool isSynthesized=true, bool<br class="">
       isDynamic=true) {<br class="">
     int attrs = property->getPropertyAttribute<wbr class="">s();<br class="">
@@ -263,7 +234,7 @@ protected:<br class="">
       attrs &= ~ObjCPropertyDecl::OBJC_PR_str<wbr class="">ong;<br class="">
     }<br class="">
     // The first flags field has the same attribute values as clang uses internally<br class="">
-    Fields.push_back(llvm::Constan<wbr class="">tInt::get(Int8Ty, attrs & 0xff));<br class="">
+    Fields.addInt(Int8Ty, attrs & 0xff);<br class="">
     attrs >>= 8;<br class="">
     attrs <<= 2;<br class="">
     // For protocol properties, synthesized and dynamic have no meaning, so we<br class="">
@@ -273,10 +244,10 @@ protected:<br class="">
     attrs |= isDynamic ? (1<<1) : 0;<br class="">
     // The second field is the next four fields left shifted by two, with the<br class="">
     // low bit set to indicate whether the field is synthesized or dynamic.<br class="">
-    Fields.push_back(llvm::Constan<wbr class="">tInt::get(Int8Ty, attrs & 0xff));<br class="">
+    Fields.addInt(Int8Ty, attrs & 0xff);<br class="">
     // Two padding fields<br class="">
-    Fields.push_back(llvm::Constan<wbr class="">tInt::get(Int8Ty, 0));<br class="">
-    Fields.push_back(llvm::Constan<wbr class="">tInt::get(Int8Ty, 0));<br class="">
+    Fields.addInt(Int8Ty, 0);<br class="">
+    Fields.addInt(Int8Ty, 0);<br class="">
   }<br class="">
<br class="">
   /// Ensures that the value has the required type, by inserting a bitcast if<br class="">
@@ -1233,14 +1204,15 @@ llvm::Constant *CGObjCGNUstep::GetEHType<br class="">
   llvm::Constant *typeName =<br class="">
     ExportUniqueString(className, "__objc_eh_typename_");<br class="">
<br class="">
-  std::vector<llvm::Constant*> fields;<br class="">
-  fields.push_back(BVtable);<br class="">
-  fields.push_back(typeName);<br class="">
-  llvm::Constant *TI =<br class="">
-      MakeGlobal(llvm::StructType::g<wbr class="">et(PtrToInt8Ty, PtrToInt8Ty, nullptr),<br class="">
-                 fields, CGM.getPointerAlign(),<br class="">
-                 "__objc_eh_typeinfo_" + className,<br class="">
-          llvm::GlobalValue::LinkOnceODR<wbr class="">Linkage);<br class="">
+  ConstantBuilder builder(CGM);<br class="">
+  auto fields = builder.beginStruct();<br class="">
+  fields.add(BVtable);<br class="">
+  fields.add(typeName);<br class="">
+  llvm::Constant *TI =<br class="">
+    fields.finishAndCreateGlobal("<wbr class="">__objc_eh_typeinfo_" + className,<br class="">
+                                 CGM.getPointerAlign(),<br class="">
+                                 /*constant*/ false,<br class="">
+                                 llvm::GlobalValue::LinkOnceOD<wbr class="">RLinkage);<br class="">
   return llvm::ConstantExpr::getBitCast<wbr class="">(TI, PtrToInt8Ty);<br class="">
 }<br class="">
<br class="">
@@ -1270,13 +1242,13 @@ ConstantAddress CGObjCGNU::GenerateConst<br class="">
   else if (isa->getType() != PtrToIdTy)<br class="">
     isa = llvm::ConstantExpr::getBitCast<wbr class="">(isa, PtrToIdTy);<br class="">
<br class="">
-  std::vector<llvm::Constant*> Ivars;<br class="">
-  Ivars.push_back(isa);<br class="">
-  Ivars.push_back(MakeConstantSt<wbr class="">ring(Str));<br class="">
-  Ivars.push_back(llvm::Constant<wbr class="">Int::get(IntTy, Str.size()));<br class="">
-  llvm::Constant *ObjCStr = MakeGlobal(<br class="">
-    llvm::StructType::get(PtrToIdT<wbr class="">y, PtrToInt8Ty, IntTy, nullptr),<br class="">
-    Ivars, Align, ".objc_str");<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Fields = Builder.beginStruct();<br class="">
+  Fields.add(isa);<br class="">
+  Fields.add(MakeConstantString(<wbr class="">Str));<br class="">
+  Fields.addInt(IntTy, Str.size());<br class="">
+  llvm::Constant *ObjCStr =<br class="">
+    Fields.finishAndCreateGlobal("<wbr class="">.objc_str", Align);<br class="">
   ObjCStr = llvm::ConstantExpr::getBitCast<wbr class="">(ObjCStr, PtrToInt8Ty);<br class="">
   ObjCStrings[Str] = ObjCStr;<br class="">
   ConstantStrings.push_back(Obj<wbr class="">CStr);<br class="">
@@ -1551,13 +1523,20 @@ GenerateMethodList(StringRef ClassName,<br class="">
                    bool isClassMethodList) {<br class="">
   if (MethodSels.empty())<br class="">
     return NULLPtr;<br class="">
+<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+<br class="">
+  auto MethodList = Builder.beginStruct();<br class="">
+  MethodList.addNullPointer(CGM.<wbr class="">Int8PtrTy);<br class="">
+  MethodList.addInt(Int32Ty, MethodTypes.size());<br class="">
+<br class="">
   // Get the method structure type.<br class="">
   llvm::StructType *ObjCMethodTy = llvm::StructType::get(<br class="">
     PtrToInt8Ty, // Really a selector, but the runtime creates it us.<br class="">
     PtrToInt8Ty, // Method types<br class="">
     IMPTy, //Method pointer<br class="">
     nullptr);<br class="">
-  std::vector<llvm::Constant*> Methods;<br class="">
+  auto Methods = MethodList.beginArray();<br class="">
   for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {<br class="">
     llvm::Constant *Method =<br class="">
       TheModule.getFunction(SymbolN<wbr class="">ameForMethod(ClassName, CategoryName,<br class="">
@@ -1567,34 +1546,14 @@ GenerateMethodList(StringRef ClassName,<br class="">
     llvm::Constant *C = MakeConstantString(MethodSels[<wbr class="">i].getAsString());<br class="">
     Method = llvm::ConstantExpr::getBitCast<wbr class="">(Method,<br class="">
         IMPTy);<br class="">
-    Methods.push_back(<br class="">
+    Methods.add(<br class="">
         llvm::ConstantStruct::get(Obj<wbr class="">CMethodTy, {C, MethodTypes[i], Method}));<br class="">
   }<br class="">
-<br class="">
-  // Array of method structures<br class="">
-  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMetho<wbr class="">dTy,<br class="">
-                                                            Methods.size());<br class="">
-  llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCM<wbr class="">ethodArrayTy,<br class="">
-                                                         Methods);<br class="">
-<br class="">
-  // Structure containing list pointer, array and array count<br class="">
-  llvm::StructType *ObjCMethodListTy = llvm::StructType::create(VMCon<wbr class="">text);<br class="">
-  llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(O<wbr class="">bjCMethodListTy);<br class="">
-  ObjCMethodListTy->setBody(<br class="">
-      NextPtrTy,<br class="">
-      IntTy,<br class="">
-      ObjCMethodArrayTy,<br class="">
-      nullptr);<br class="">
-<br class="">
-  Methods.clear();<br class="">
-  Methods.push_back(llvm::Consta<wbr class="">ntPointerNull::get(<br class="">
-        llvm::PointerType::getUnqual(O<wbr class="">bjCMethodListTy)));<br class="">
-  Methods.push_back(llvm::Consta<wbr class="">ntInt::get(Int32Ty, MethodTypes.size()));<br class="">
-  Methods.push_back(MethodArray)<wbr class="">;<br class="">
+  MethodList.add(Methods.finish(<wbr class="">));<br class="">
<br class="">
   // Create an instance of the structure<br class="">
-  return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),<br class="">
-                    ".objc_method_list");<br class="">
+  return MethodList.finishAndCreateGlob<wbr class="">al(".objc_method_list",<br class="">
+                                          CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 /// Generates an IvarList.  Used in construction of a objc_class.<br class="">
@@ -1602,35 +1561,36 @@ llvm::Constant *CGObjCGNU::<br class="">
 GenerateIvarList(ArrayRef<llv<wbr class="">m::Constant *> IvarNames,<br class="">
                  ArrayRef<llvm::Constant *> IvarTypes,<br class="">
                  ArrayRef<llvm::Constant *> IvarOffsets) {<br class="">
-  if (IvarNames.size() == 0)<br class="">
+  if (IvarNames.empty())<br class="">
     return NULLPtr;<br class="">
-  // Get the method structure type.<br class="">
+<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+<br class="">
+  // Structure containing array count followed by array.<br class="">
+  auto IvarList = Builder.beginStruct();<br class="">
+  IvarList.addInt(IntTy, (int)IvarNames.size());<br class="">
+<br class="">
+  // Get the ivar structure type.<br class="">
   llvm::StructType *ObjCIvarTy = llvm::StructType::get(<br class="">
     PtrToInt8Ty,<br class="">
     PtrToInt8Ty,<br class="">
     IntTy,<br class="">
     nullptr);<br class="">
-  std::vector<llvm::Constant*> Ivars;<br class="">
+<br class="">
+  // Array of ivar structures.<br class="">
+  auto Ivars = IvarList.beginArray(ObjCIvarTy<wbr class="">);<br class="">
   for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {<br class="">
-    Ivars.push_back(llvm::Constant<wbr class="">Struct::get(<br class="">
-        ObjCIvarTy, {IvarNames[i], IvarTypes[i], IvarOffsets[i]}));<br class="">
+    auto Ivar = Ivars.beginStruct(ObjCIvarTy);<br class="">
+    Ivar.add(IvarNames[i]);<br class="">
+    Ivar.add(IvarTypes[i]);<br class="">
+    Ivar.add(IvarOffsets[i]);<br class="">
+    Ivars.add(Ivar.finish());<br class="">
   }<br class="">
-<br class="">
-  // Array of method structures<br class="">
-  llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarT<wbr class="">y,<br class="">
-      IvarNames.size());<br class="">
-<br class="">
-  llvm::Constant *Elements[] = {<br class="">
-      llvm::ConstantInt::get(IntTy, (int)IvarNames.size()),<br class="">
-      llvm::ConstantArray::get(ObjCI<wbr class="">varArrayTy, Ivars)};<br class="">
-  // Structure containing array and array count<br class="">
-  llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,<br class="">
-    ObjCIvarArrayTy,<br class="">
-    nullptr);<br class="">
+  IvarList.add(Ivars.finish());<br class="">
<br class="">
   // Create an instance of the structure<br class="">
-  return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),<br class="">
-                    ".objc_ivar_list");<br class="">
+  return IvarList.finishAndCreateGlobal<wbr class="">(".objc_ivar_list",<br class="">
+                                        CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 /// Generate a class structure<br class="">
@@ -1678,34 +1638,55 @@ llvm::Constant *CGObjCGNU::GenerateClass<br class="">
       IntPtrTy,               // strong_pointers<br class="">
       IntPtrTy,               // weak_pointers<br class="">
       nullptr);<br class="">
-  llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);<br class="">
+<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Elements = Builder.beginStruct(ClassTy);<br class="">
+<br class="">
   // Fill in the structure<br class="">
-  std::vector<llvm::Constant*> Elements;<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(MetaClass, PtrToInt8Ty));<br class="">
-  Elements.push_back(SuperClass)<wbr class="">;<br class="">
-  Elements.push_back(MakeConstan<wbr class="">tString(Name, ".class_name"));<br class="">
-  Elements.push_back(Zero);<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antInt::get(LongTy, info));<br class="">
+<br class="">
+  // isa<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(MetaClass, PtrToInt8Ty));<br class="">
+  // super_class<br class="">
+  Elements.add(SuperClass);<br class="">
+  // name<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(Name, ".class_name"));<br class="">
+  // version<br class="">
+  Elements.addInt(LongTy, 0);<br class="">
+  // info<br class="">
+  Elements.addInt(LongTy, info);<br class="">
+  // instance_size<br class="">
   if (isMeta) {<br class="">
     llvm::DataLayout td(&TheModule);<br class="">
-    Elements.push_back(<br class="">
-        llvm::ConstantInt::get(LongTy,<br class="">
-                               td.getTypeSizeInBits(ClassTy) /<br class="">
-                                 CGM.getContext().getCharWidth<wbr class="">()));<br class="">
+    Elements.addInt(LongTy,<br class="">
+                    td.getTypeSizeInBits(ClassTy) /<br class="">
+                      CGM.getContext().getCharWidth(<wbr class="">));<br class="">
   } else<br class="">
-    Elements.push_back(InstanceSiz<wbr class="">e);<br class="">
-  Elements.push_back(IVars);<br class="">
-  Elements.push_back(Methods);<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(Protocols, PtrTy));<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antInt::get(LongTy, 1));<br class="">
-  Elements.push_back(IvarOffsets<wbr class="">);<br class="">
-  Elements.push_back(Properties)<wbr class="">;<br class="">
-  Elements.push_back(StrongIvarB<wbr class="">itmap);<br class="">
-  Elements.push_back(WeakIvarBit<wbr class="">map);<br class="">
+    Elements.add(InstanceSize);<br class="">
+  // ivars<br class="">
+  Elements.add(IVars);<br class="">
+  // methods<br class="">
+  Elements.add(Methods);<br class="">
+  // These are all filled in by the runtime, so we pretend<br class="">
+  // dtable<br class="">
+  Elements.add(NULLPtr);<br class="">
+  // subclass_list<br class="">
+  Elements.add(NULLPtr);<br class="">
+  // sibling_class<br class="">
+  Elements.add(NULLPtr);<br class="">
+  // protocols<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(Protocols, PtrTy));<br class="">
+  // gc_object_type<br class="">
+  Elements.add(NULLPtr);<br class="">
+  // abi_version<br class="">
+  Elements.addInt(LongTy, 1);<br class="">
+  // ivar_offsets<br class="">
+  Elements.add(IvarOffsets);<br class="">
+  // properties<br class="">
+  Elements.add(Properties);<br class="">
+  // strong_pointers<br class="">
+  Elements.add(StrongIvarBitmap)<wbr class="">;<br class="">
+  // weak_pointers<br class="">
+  Elements.add(WeakIvarBitmap);<br class="">
   // Create an instance of the structure<br class="">
   // This is now an externally visible symbol, so that we can speed up class<br class="">
   // messages in the next ABI.  We may already have some weak references to<br class="">
@@ -1714,13 +1695,13 @@ llvm::Constant *CGObjCGNU::GenerateClass<br class="">
           std::string(Name));<br class="">
   llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(Class<wbr class="">Sym);<br class="">
   llvm::Constant *Class =<br class="">
-    MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,<br class="">
-               llvm::GlobalValue::ExternalLi<wbr class="">nkage);<br class="">
+    Elements.finishAndCreateGlobal<wbr class="">(ClassSym, CGM.getPointerAlign(), false,<br class="">
+                                   llvm::GlobalValue::ExternalLi<wbr class="">nkage);<br class="">
   if (ClassRef) {<br class="">
-      ClassRef->replaceAllUsesWith(l<wbr class="">lvm::ConstantExpr::getBitCast(<wbr class="">Class,<br class="">
+    ClassRef->replaceAllUsesWith(l<wbr class="">lvm::ConstantExpr::getBitCast(<wbr class="">Class,<br class="">
                   ClassRef->getType()));<br class="">
-      ClassRef->removeFromParent();<br class="">
-      Class->setName(ClassSym);<br class="">
+    ClassRef->removeFromParent();<br class="">
+    Class->setName(ClassSym);<br class="">
   }<br class="">
   return Class;<br class="">
 }<br class="">
@@ -1729,38 +1710,33 @@ llvm::Constant *CGObjCGNU::<br class="">
 GenerateProtocolMethodList(Ar<wbr class="">rayRef<llvm::Constant *> MethodNames,<br class="">
                            ArrayRef<llvm::Constant *> MethodTypes) {<br class="">
   // Get the method structure type.<br class="">
-  llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(<br class="">
-    PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.<br class="">
-    PtrToInt8Ty,<br class="">
-    nullptr);<br class="">
-  std::vector<llvm::Constant*> Methods;<br class="">
+  llvm::StructType *ObjCMethodDescTy =<br class="">
+    llvm::StructType::get(CGM.getL<wbr class="">LVMContext(), { PtrToInt8Ty, PtrToInt8Ty });<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto MethodList = Builder.beginStruct();<br class="">
+  MethodList.addInt(IntTy, MethodNames.size());<br class="">
+  auto Methods = MethodList.beginArray(ObjCMeth<wbr class="">odDescTy);<br class="">
   for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {<br class="">
-    Methods.push_back(llvm::Consta<wbr class="">ntStruct::get(<br class="">
-        ObjCMethodDescTy, {MethodNames[i], MethodTypes[i]}));<br class="">
-  }<br class="">
-  llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMetho<wbr class="">dDescTy,<br class="">
-      MethodNames.size());<br class="">
-  llvm::Constant *Array = llvm::ConstantArray::get(ObjCM<wbr class="">ethodArrayTy,<br class="">
-                                                   Methods);<br class="">
-  llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(<br class="">
-      IntTy, ObjCMethodArrayTy, nullptr);<br class="">
-  Methods.clear();<br class="">
-  Methods.push_back(llvm::Consta<wbr class="">ntInt::get(IntTy, MethodNames.size()));<br class="">
-  Methods.push_back(Array);<br class="">
-  return MakeGlobal(ObjCMethodDescListT<wbr class="">y, Methods, CGM.getPointerAlign(),<br class="">
-                    ".objc_method_list");<br class="">
+    auto Method = Methods.beginStruct(ObjCMethod<wbr class="">DescTy);<br class="">
+    Method.add(MethodNames[i]);<br class="">
+    Method.add(MethodTypes[i]);<br class="">
+    Methods.add(Method.finish());<br class="">
+  }<br class="">
+  MethodList.add(Methods.finish(<wbr class="">));<br class="">
+  return MethodList.finishAndCreateGlob<wbr class="">al(".objc_method_list",<br class="">
+                                          CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 // Create the protocol list structure used in classes, categories and so on<br class="">
-llvm::Constant *CGObjCGNU::GenerateProtocolLi<wbr class="">st(ArrayRef<std::string>Protoc<wbr class="">ols){<br class="">
-  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8<wbr class="">Ty,<br class="">
-      Protocols.size());<br class="">
-  llvm::StructType *ProtocolListTy = llvm::StructType::get(<br class="">
-      PtrTy, //Should be a recurisve pointer, but it's always NULL here.<br class="">
-      SizeTy,<br class="">
-      ProtocolArrayTy,<br class="">
-      nullptr);<br class="">
-  std::vector<llvm::Constant*> Elements;<br class="">
+llvm::Constant *<br class="">
+CGObjCGNU::GenerateProtocolLi<wbr class="">st(ArrayRef<std::string> Protocols) {<br class="">
+<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto ProtocolList = Builder.beginStruct();<br class="">
+  ProtocolList.add(NULLPtr);<br class="">
+  ProtocolList.addInt(LongTy, Protocols.size());<br class="">
+<br class="">
+  auto Elements = ProtocolList.beginArray(PtrToI<wbr class="">nt8Ty);<br class="">
   for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();<br class="">
       iter != endIter ; iter++) {<br class="">
     llvm::Constant *protocol = nullptr;<br class="">
@@ -1773,16 +1749,11 @@ llvm::Constant *CGObjCGNU::GenerateProto<br class="">
     }<br class="">
     llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast<wbr class="">(protocol,<br class="">
                                                            PtrToInt8Ty);<br class="">
-    Elements.push_back(Ptr);<br class="">
+    Elements.add(Ptr);<br class="">
   }<br class="">
-  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(Proto<wbr class="">colArrayTy,<br class="">
-      Elements);<br class="">
-  Elements.clear();<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antInt::get(LongTy, Protocols.size()));<br class="">
-  Elements.push_back(ProtocolArr<wbr class="">ay);<br class="">
-  return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),<br class="">
-                    ".objc_protocol_list");<br class="">
+  ProtocolList.add(Elements.fini<wbr class="">sh());<br class="">
+  return ProtocolList.finishAndCreateGl<wbr class="">obal(".objc_protocol_list",<br class="">
+                                            CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 llvm::Value *CGObjCGNU::GenerateProtocolRe<wbr class="">f(CodeGenFunction &CGF,<br class="">
@@ -1793,33 +1764,28 @@ llvm::Value *CGObjCGNU::GenerateProtocol<br class="">
   return CGF.Builder.CreateBitCast(prot<wbr class="">ocol, llvm::PointerType::getUnqual(T<wbr class="">));<br class="">
 }<br class="">
<br class="">
-llvm::Constant *CGObjCGNU::GenerateEmptyProto<wbr class="">col(<br class="">
-  const std::string &ProtocolName) {<br class="">
-  SmallVector<std::string, 0> EmptyStringVector;<br class="">
-  SmallVector<llvm::Constant*, 0> EmptyConstantVector;<br class="">
-<br class="">
-  llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStri<wbr class="">ngVector);<br class="">
-  llvm::Constant *MethodList =<br class="">
-    GenerateProtocolMethodList(Emp<wbr class="">tyConstantVector, EmptyConstantVector);<br class="">
+llvm::Constant *<br class="">
+CGObjCGNU::GenerateEmptyProto<wbr class="">col(const std::string &ProtocolName) {<br class="">
+  llvm::Constant *ProtocolList = GenerateProtocolList({});<br class="">
+  llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});<br class="">
   // Protocols are objects containing lists of the methods implemented and<br class="">
   // protocols adopted.<br class="">
-  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,<br class="">
-      PtrToInt8Ty,<br class="">
-      ProtocolList->getType(),<br class="">
-      MethodList->getType(),<br class="">
-      MethodList->getType(),<br class="">
-      MethodList->getType(),<br class="">
-      MethodList->getType(),<br class="">
-      nullptr);<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Elements = Builder.beginStruct();<br class="">
+<br class="">
   // The isa pointer must be set to a magic number so the runtime knows it's<br class="">
   // the correct layout.<br class="">
-  llvm::Constant *Elements[] = {<br class="">
-      llvm::ConstantExpr::getIntToPt<wbr class="">r(<br class="">
-          llvm::ConstantInt::get(Int32Ty<wbr class="">, ProtocolVersion), IdTy),<br class="">
-      MakeConstantString(ProtocolNam<wbr class="">e, ".objc_protocol_name"), ProtocolList,<br class="">
-      MethodList, MethodList, MethodList, MethodList};<br class="">
-  return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),<br class="">
-                    ".objc_protocol");<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getIntToPtr(<br class="">
+          llvm::ConstantInt::get(Int32Ty<wbr class="">, ProtocolVersion), IdTy));<br class="">
+<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(ProtocolName, ".objc_protocol_name"));<br class="">
+  Elements.add(ProtocolList);<br class="">
+  Elements.add(MethodList);<br class="">
+  Elements.add(MethodList);<br class="">
+  Elements.add(MethodList);<br class="">
+  Elements.add(MethodList);<br class="">
+  return Elements.finishAndCreateGlobal<wbr class="">(".objc_protocol",<br class="">
+                                        CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 void CGObjCGNU::GenerateProtocol(co<wbr class="">nst ObjCProtocolDecl *PD) {<br class="">
@@ -1886,142 +1852,143 @@ void CGObjCGNU::GenerateProtocol(co<wbr class="">nst O<br class="">
   // The isSynthesized value is always set to 0 in a protocol.  It exists to<br class="">
   // simplify the runtime library by allowing it to use the same data<br class="">
   // structures for protocol metadata everywhere.<br class="">
-  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(<br class="">
-          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br class="">
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);<br class="">
-  std::vector<llvm::Constant*> Properties;<br class="">
-  std::vector<llvm::Constant*> OptionalProperties;<br class="">
<br class="">
-  // Add all of the property methods need adding to the method list and to the<br class="">
-  // property metadata list.<br class="">
-  for (auto *property : PD->instance_properties()) {<br class="">
-    std::vector<llvm::Constant*> Fields;<br class="">
-<br class="">
-    Fields.push_back(MakePropertyE<wbr class="">ncodingString(property, nullptr));<br class="">
-    PushPropertyAttributes(Fields, property);<br class="">
+  llvm::Constant *PropertyList;<br class="">
+  llvm::Constant *OptionalPropertyList;<br class="">
+  {<br class="">
+    llvm::StructType *propertyMetadataTy =<br class="">
+      llvm::StructType::get(CGM.getL<wbr class="">LVMContext(),<br class="">
+        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br class="">
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });<br class="">
+<br class="">
+    unsigned numReqProperties = 0, numOptProperties = 0;<br class="">
+    for (auto property : PD->instance_properties()) {<br class="">
+      if (property->isOptional())<br class="">
+        numOptProperties++;<br class="">
+      else<br class="">
+        numReqProperties++;<br class="">
+    }<br class="">
+<br class="">
+    ConstantBuilder reqPropertyListBuilder(CGM);<br class="">
+    auto reqPropertiesList = reqPropertyListBuilder.beginSt<wbr class="">ruct();<br class="">
+    reqPropertiesList.addInt(IntTy<wbr class="">, numReqProperties);<br class="">
+    reqPropertiesList.add(NULLPtr)<wbr class="">;<br class="">
+    auto reqPropertiesArray = reqPropertiesList.beginArray(p<wbr class="">ropertyMetadataTy);<br class="">
+<br class="">
+    ConstantBuilder optPropertyListBuilder(CGM);<br class="">
+    auto optPropertiesList = optPropertyListBuilder.beginSt<wbr class="">ruct();<br class="">
+    optPropertiesList.addInt(IntTy<wbr class="">, numOptProperties);<br class="">
+    optPropertiesList.add(NULLPtr)<wbr class="">;<br class="">
+    auto optPropertiesArray = optPropertiesList.beginArray(p<wbr class="">ropertyMetadataTy);<br class="">
+<br class="">
+    // Add all of the property methods need adding to the method list and to the<br class="">
+    // property metadata list.<br class="">
+    for (auto *property : PD->instance_properties()) {<br class="">
+      auto &propertiesArray =<br class="">
+        (property->isOptional() ? optPropertiesArray : reqPropertiesArray);<br class="">
+      auto fields = propertiesArray.beginStruct(pr<wbr class="">opertyMetadataTy);<br class="">
+<br class="">
+      fields.add(MakePropertyEncodin<wbr class="">gString(property, nullptr));<br class="">
+      PushPropertyAttributes(fields, property);<br class="">
+<br class="">
+      if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr class="">)) {<br class="">
+        std::string typeStr;<br class="">
+        Context.getObjCEncodingForMeth<wbr class="">odDecl(getter, typeStr);<br class="">
+        llvm::Constant *typeEncoding = MakeConstantString(typeStr);<br class="">
+        InstanceMethodTypes.push_back(<wbr class="">typeEncoding);<br class="">
+        fields.add(MakeConstantString(<wbr class="">getter->getSelector().getAsStr<wbr class="">ing()));<br class="">
+        fields.add(typeEncoding);<br class="">
+      } else {<br class="">
+        fields.add(NULLPtr);<br class="">
+        fields.add(NULLPtr);<br class="">
+      }<br class="">
+      if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr class="">)) {<br class="">
+        std::string typeStr;<br class="">
+        Context.getObjCEncodingForMeth<wbr class="">odDecl(setter, typeStr);<br class="">
+        llvm::Constant *typeEncoding = MakeConstantString(typeStr);<br class="">
+        InstanceMethodTypes.push_back(<wbr class="">typeEncoding);<br class="">
+        fields.add(MakeConstantString(<wbr class="">setter->getSelector().getAsStr<wbr class="">ing()));<br class="">
+        fields.add(typeEncoding);<br class="">
+      } else {<br class="">
+        fields.add(NULLPtr);<br class="">
+        fields.add(NULLPtr);<br class="">
+      }<br class="">
<br class="">
-    if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr class="">)) {<br class="">
-      std::string TypeStr;<br class="">
-      Context.getObjCEncodingForMeth<wbr class="">odDecl(getter,TypeStr);<br class="">
-      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);<br class="">
-      InstanceMethodTypes.push_back(<wbr class="">TypeEncoding);<br class="">
-      Fields.push_back(MakeConstantS<wbr class="">tring(getter->getSelector().ge<wbr class="">tAsString()));<br class="">
-      Fields.push_back(TypeEncoding)<wbr class="">;<br class="">
-    } else {<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-    }<br class="">
-    if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr class="">)) {<br class="">
-      std::string TypeStr;<br class="">
-      Context.getObjCEncodingForMeth<wbr class="">odDecl(setter,TypeStr);<br class="">
-      llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);<br class="">
-      InstanceMethodTypes.push_back(<wbr class="">TypeEncoding);<br class="">
-      Fields.push_back(MakeConstantS<wbr class="">tring(setter->getSelector().ge<wbr class="">tAsString()));<br class="">
-      Fields.push_back(TypeEncoding)<wbr class="">;<br class="">
-    } else {<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-    }<br class="">
-    if (property->getPropertyImplemen<wbr class="">tation() == ObjCPropertyDecl::Optional) {<br class="">
-      OptionalProperties.push_back(l<wbr class="">lvm::ConstantStruct::get(Prope<wbr class="">rtyMetadataTy, Fields));<br class="">
-    } else {<br class="">
-      Properties.push_back(llvm::Con<wbr class="">stantStruct::get(PropertyMetad<wbr class="">ataTy, Fields));<br class="">
+      propertiesArray.add(fields.fin<wbr class="">ish());<br class="">
     }<br class="">
+<br class="">
+    reqPropertiesList.add(reqPrope<wbr class="">rtiesArray.finish());<br class="">
+    PropertyList =<br class="">
+      reqPropertiesList.finishAndCre<wbr class="">ateGlobal(".objc_property_list<wbr class="">",<br class="">
+                                              CGM.getPointerAlign());<br class="">
+<br class="">
+    optPropertiesList.add(optPrope<wbr class="">rtiesArray.finish());<br class="">
+    OptionalPropertyList =<br class="">
+      optPropertiesList.finishAndCre<wbr class="">ateGlobal(".objc_property_list<wbr class="">",<br class="">
+                                              CGM.getPointerAlign());<br class="">
   }<br class="">
-  llvm::Constant *PropertyArray = llvm::ConstantArray::get(<br class="">
-      llvm::ArrayType::get(PropertyM<wbr class="">etadataTy, Properties.size()), Properties);<br class="">
-  llvm::Constant* PropertyListInitFields[] =<br class="">
-    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};<br class="">
-<br class="">
-  llvm::Constant *PropertyListInit =<br class="">
-      llvm::ConstantStruct::getAnon(<wbr class="">PropertyListInitFields);<br class="">
-  llvm::Constant *PropertyList = new llvm::GlobalVariable(TheModule<wbr class="">,<br class="">
-      PropertyListInit->getType(), false, llvm::GlobalValue::InternalLin<wbr class="">kage,<br class="">
-      PropertyListInit, ".objc_property_list");<br class="">
-<br class="">
-  llvm::Constant *OptionalPropertyArray =<br class="">
-      llvm::ConstantArray::get(llvm:<wbr class="">:ArrayType::get(PropertyMetada<wbr class="">taTy,<br class="">
-          OptionalProperties.size()) , OptionalProperties);<br class="">
-  llvm::Constant* OptionalPropertyListInitFields<wbr class="">[] = {<br class="">
-      llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,<br class="">
-      OptionalPropertyArray };<br class="">
-<br class="">
-  llvm::Constant *OptionalPropertyListInit =<br class="">
-      llvm::ConstantStruct::getAnon(<wbr class="">OptionalPropertyListInitFields<wbr class="">);<br class="">
-  llvm::Constant *OptionalPropertyList = new llvm::GlobalVariable(TheModule<wbr class="">,<br class="">
-          OptionalPropertyListInit->getT<wbr class="">ype(), false,<br class="">
-          llvm::GlobalValue::InternalLin<wbr class="">kage, OptionalPropertyListInit,<br class="">
-          ".objc_property_list");<br class="">
<br class="">
   // Protocols are objects containing lists of the methods implemented and<br class="">
   // protocols adopted.<br class="">
-  llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,<br class="">
-      PtrToInt8Ty,<br class="">
-      ProtocolList->getType(),<br class="">
-      InstanceMethodList->getType(),<br class="">
-      ClassMethodList->getType(),<br class="">
-      OptionalInstanceMethodList->ge<wbr class="">tType(),<br class="">
-      OptionalClassMethodList->getTy<wbr class="">pe(),<br class="">
-      PropertyList->getType(),<br class="">
-      OptionalPropertyList->getType(<wbr class="">),<br class="">
-      nullptr);<br class="">
   // The isa pointer must be set to a magic number so the runtime knows it's<br class="">
   // the correct layout.<br class="">
-  llvm::Constant *Elements[] = {<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Elements = Builder.beginStruct();<br class="">
+  Elements.add(<br class="">
       llvm::ConstantExpr::getIntToP<wbr class="">tr(<br class="">
-          llvm::ConstantInt::get(Int32Ty<wbr class="">, ProtocolVersion), IdTy),<br class="">
-      MakeConstantString(ProtocolNam<wbr class="">e, ".objc_protocol_name"), ProtocolList,<br class="">
-      InstanceMethodList, ClassMethodList, OptionalInstanceMethodList,<br class="">
-      OptionalClassMethodList, PropertyList, OptionalPropertyList};<br class="">
+          llvm::ConstantInt::get(Int32Ty<wbr class="">, ProtocolVersion), IdTy));<br class="">
+  Elements.add(<br class="">
+      MakeConstantString(ProtocolNam<wbr class="">e, ".objc_protocol_name"));<br class="">
+  Elements.add(ProtocolList);<br class="">
+  Elements.add(InstanceMethodLis<wbr class="">t);<br class="">
+  Elements.add(ClassMethodList);<br class="">
+  Elements.add(OptionalInstanceM<wbr class="">ethodList);<br class="">
+  Elements.add(OptionalClassMeth<wbr class="">odList);<br class="">
+  Elements.add(PropertyList);<br class="">
+  Elements.add(OptionalPropertyL<wbr class="">ist);<br class="">
   ExistingProtocols[ProtocolNam<wbr class="">e] =<br class="">
-    llvm::ConstantExpr::getBitCast<wbr class="">(MakeGlobal(ProtocolTy, Elements,<br class="">
-          CGM.getPointerAlign(), ".objc_protocol"), IdTy);<br class="">
+    llvm::ConstantExpr::getBitCast<wbr class="">(<br class="">
+      Elements.finishAndCreateGlobal<wbr class="">(".objc_protocol", CGM.getPointerAlign()),<br class="">
+      IdTy);<br class="">
 }<br class="">
 void CGObjCGNU::GenerateProtocolHol<wbr class="">derCategory() {<br class="">
   // Collect information about instance methods<br class="">
   SmallVector<Selector, 1> MethodSels;<br class="">
   SmallVector<llvm::Constant*, 1> MethodTypes;<br class="">
<br class="">
-  std::vector<llvm::Constant*> Elements;<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Elements = Builder.beginStruct();<br class="">
+<br class="">
   const std::string ClassName = "__ObjC_Protocol_Holder_Ugly_H<wbr class="">ack";<br class="">
   const std::string CategoryName = "AnotherHack";<br class="">
-  Elements.push_back(MakeConstan<wbr class="">tString(CategoryName));<br class="">
-  Elements.push_back(MakeConstan<wbr class="">tString(ClassName));<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(CategoryName));<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(ClassName));<br class="">
   // Instance method list<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(GenerateMe<wbr class="">thodList(<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(GenerateMethodLi<wbr class="">st(<br class="">
           ClassName, CategoryName, MethodSels, MethodTypes, false), PtrTy));<br class="">
   // Class method list<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(GenerateMe<wbr class="">thodList(<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(GenerateMethodLi<wbr class="">st(<br class="">
           ClassName, CategoryName, MethodSels, MethodTypes, true), PtrTy));<br class="">
+<br class="">
   // Protocol list<br class="">
-  llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,<br class="">
-      ExistingProtocols.size());<br class="">
-  llvm::StructType *ProtocolListTy = llvm::StructType::get(<br class="">
-      PtrTy, //Should be a recurisve pointer, but it's always NULL here.<br class="">
-      SizeTy,<br class="">
-      ProtocolArrayTy,<br class="">
-      nullptr);<br class="">
-  std::vector<llvm::Constant*> ProtocolElements;<br class="">
-  for (llvm::StringMapIterator<llvm:<wbr class="">:Constant*> iter =<br class="">
-       ExistingProtocols.begin(), endIter = ExistingProtocols.end();<br class="">
+  ConstantBuilder ProtocolListBuilder(CGM);<br class="">
+  auto ProtocolList = ProtocolListBuilder.beginStruc<wbr class="">t();<br class="">
+  ProtocolList.add(NULLPtr);<br class="">
+  ProtocolList.addInt(LongTy, ExistingProtocols.size());<br class="">
+  auto ProtocolElements = ProtocolList.beginArray(PtrTy)<wbr class="">;<br class="">
+  for (auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();<br class="">
        iter != endIter ; iter++) {<br class="">
     llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast<wbr class="">(iter->getValue(),<br class="">
             PtrTy);<br class="">
-    ProtocolElements.push_back(Ptr<wbr class="">);<br class="">
+    ProtocolElements.add(Ptr);<br class="">
   }<br class="">
-  llvm::Constant * ProtocolArray = llvm::ConstantArray::get(Proto<wbr class="">colArrayTy,<br class="">
-      ProtocolElements);<br class="">
-  ProtocolElements.clear();<br class="">
-  ProtocolElements.push_back(NUL<wbr class="">LPtr);<br class="">
-  ProtocolElements.push_back(llv<wbr class="">m::ConstantInt::get(LongTy,<br class="">
-              ExistingProtocols.size()));<br class="">
-  ProtocolElements.push_back(Pro<wbr class="">tocolArray);<br class="">
-  Elements.push_back(llvm::Const<wbr class="">antExpr::getBitCast(MakeGlobal<wbr class="">(ProtocolListTy,<br class="">
-                  ProtocolElements, CGM.getPointerAlign(),<br class="">
-                  ".objc_protocol_list"), PtrTy));<br class="">
+  ProtocolList.add(ProtocolEleme<wbr class="">nts.finish());<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(<br class="">
+                   ProtocolList.finishAndCreateG<wbr class="">lobal(".objc_protocol_list",<br class="">
+                                                      CGM.getPointerAlign()),<br class="">
+                   PtrTy));<br class="">
   Categories.push_back(llvm::Co<wbr class="">nstantExpr::getBitCast(<br class="">
-        MakeGlobal(llvm::StructType::g<wbr class="">et(PtrToInt8Ty, PtrToInt8Ty,<br class="">
-            PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),<br class="">
+        Elements.finishAndCreateGlobal<wbr class="">("", CGM.getPointerAlign()),<br class="">
         PtrTy));<br class="">
 }<br class="">
<br class="">
@@ -2056,13 +2023,16 @@ llvm::Constant *CGObjCGNU::MakeBitField(<br class="">
     }<br class="">
     values.push_back(llvm::Consta<wbr class="">ntInt::get(Int32Ty, word));<br class="">
   }<br class="">
-  llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());<br class="">
-  llvm::Constant *array = llvm::ConstantArray::get(array<wbr class="">Ty, values);<br class="">
-  llvm::Constant *fields[2] = {<br class="">
-      llvm::ConstantInt::get(Int32Ty<wbr class="">, values.size()),<br class="">
-      array };<br class="">
-  llvm::Constant *GS = MakeGlobal(llvm::StructType::g<wbr class="">et(Int32Ty, arrayTy,<br class="">
-        nullptr), fields, CharUnits::fromQuantity(4));<br class="">
+<br class="">
+  ConstantBuilder builder(CGM);<br class="">
+  auto fields = builder.beginStruct();<br class="">
+  fields.addInt(Int32Ty, values.size());<br class="">
+  auto array = fields.beginArray();<br class="">
+  for (auto v : values) array.add(v);<br class="">
+  fields.add(array.finish());<br class="">
+<br class="">
+  llvm::Constant *GS =<br class="">
+    fields.finishAndCreateGlobal("<wbr class="">", CharUnits::fromQuantity(4));<br class="">
   llvm::Constant *ptr = llvm::ConstantExpr::getPtrToIn<wbr class="">t(GS, IntPtrTy);<br class="">
   return ptr;<br class="">
 }<br class="">
@@ -2098,23 +2068,25 @@ void CGObjCGNU::GenerateCategory(co<wbr class="">nst O<br class="">
        E = Protos.end(); I != E; ++I)<br class="">
     Protocols.push_back((*I)->get<wbr class="">NameAsString());<br class="">
<br class="">
-  llvm::Constant *Elements[] = {<br class="">
-      MakeConstantString(CategoryNam<wbr class="">e), MakeConstantString(ClassName),<br class="">
-      // Instance method list<br class="">
-      llvm::ConstantExpr::getBitCast<wbr class="">(<br class="">
+  ConstantBuilder Builder(CGM);<br class="">
+  auto Elements = Builder.beginStruct();<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(CategoryName));<br class="">
+  Elements.add(MakeConstantStrin<wbr class="">g(ClassName));<br class="">
+  // Instance method list<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(<br class="">
           GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,<br class="">
                              InstanceMethodTypes, false),<br class="">
-          PtrTy),<br class="">
-      // Class method list<br class="">
-      llvm::ConstantExpr::getBitCast<wbr class="">(GenerateMethodList(ClassName, CategoryName,<br class="">
-                                                        ClassMethodSels,<br class="">
-                                                        ClassMethodTypes, true),<br class="">
-                                     PtrTy),<br class="">
-      // Protocol list<br class="">
-      llvm::ConstantExpr::getBitCast<wbr class="">(GenerateProtocolList(Protocol<wbr class="">s), PtrTy)};<br class="">
+          PtrTy));<br class="">
+  // Class method list<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(<br class="">
+                 GenerateMethodList(ClassName, CategoryName,<br class="">
+                                    ClassMethodSels, ClassMethodTypes, true),<br class="">
+                  PtrTy));<br class="">
+  // Protocol list<br class="">
+  Elements.add(llvm::ConstantExp<wbr class="">r::getBitCast(<br class="">
+                 GenerateProtocolList(Protocol<wbr class="">s), PtrTy));<br class="">
   Categories.push_back(llvm::Co<wbr class="">nstantExpr::getBitCast(<br class="">
-        MakeGlobal(llvm::StructType::g<wbr class="">et(PtrToInt8Ty, PtrToInt8Ty,<br class="">
-            PtrTy, PtrTy, PtrTy, nullptr), Elements, CGM.getPointerAlign()),<br class="">
+        Elements.finishAndCreateGlobal<wbr class="">("", CGM.getPointerAlign()),<br class="">
         PtrTy));<br class="">
 }<br class="">
<br class="">
@@ -2124,23 +2096,35 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br class="">
   ASTContext &Context = CGM.getContext();<br class="">
   // Property metadata: name, attributes, attributes2, padding1, padding2,<br class="">
   // setter name, setter types, getter name, getter types.<br class="">
-  llvm::StructType *PropertyMetadataTy = llvm::StructType::get(<br class="">
-          PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br class="">
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);<br class="">
-  std::vector<llvm::Constant*> Properties;<br class="">
+  llvm::StructType *propertyMetadataTy =<br class="">
+    llvm::StructType::get(CGM.getL<wbr class="">LVMContext(),<br class="">
+        { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,<br class="">
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });<br class="">
+<br class="">
+  unsigned numProperties = 0;<br class="">
+  for (auto *propertyImpl : OID->property_impls()) {<br class="">
+    (void) propertyImpl;<br class="">
+    numProperties++;<br class="">
+  }<br class="">
+<br class="">
+  ConstantBuilder builder(CGM);<br class="">
+  auto propertyList = builder.beginStruct();<br class="">
+  propertyList.addInt(IntTy, numProperties);<br class="">
+  propertyList.add(NULLPtr);<br class="">
+  auto properties = propertyList.beginArray(proper<wbr class="">tyMetadataTy);<br class="">
<br class="">
   // Add all of the property methods need adding to the method list and to the<br class="">
   // property metadata list.<br class="">
   for (auto *propertyImpl : OID->property_impls()) {<br class="">
-    std::vector<llvm::Constant*> Fields;<br class="">
+    auto fields = properties.beginStruct(propert<wbr class="">yMetadataTy);<br class="">
     ObjCPropertyDecl *property = propertyImpl->getPropertyDecl(<wbr class="">);<br class="">
     bool isSynthesized = (propertyImpl->getPropertyImpl<wbr class="">ementation() ==<br class="">
         ObjCPropertyImplDecl::Synthes<wbr class="">ize);<br class="">
     bool isDynamic = (propertyImpl->getPropertyImpl<wbr class="">ementation() ==<br class="">
         ObjCPropertyImplDecl::Dynamic<wbr class="">);<br class="">
<br class="">
-    Fields.push_back(MakePropertyE<wbr class="">ncodingString(property, OID));<br class="">
-    PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);<br class="">
+    fields.add(MakePropertyEncodin<wbr class="">gString(property, OID));<br class="">
+    PushPropertyAttributes(fields, property, isSynthesized, isDynamic);<br class="">
     if (ObjCMethodDecl *getter = property->getGetterMethodDecl(<wbr class="">)) {<br class="">
       std::string TypeStr;<br class="">
       Context.getObjCEncodingForMet<wbr class="">hodDecl(getter,TypeStr);<br class="">
@@ -2149,11 +2133,11 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br class="">
         InstanceMethodTypes.push_back<wbr class="">(TypeEncoding);<br class="">
         InstanceMethodSels.push_back(<wbr class="">getter->getSelector());<br class="">
       }<br class="">
-      Fields.push_back(MakeConstantS<wbr class="">tring(getter->getSelector().ge<wbr class="">tAsString()));<br class="">
-      Fields.push_back(TypeEncoding)<wbr class="">;<br class="">
+      fields.add(MakeConstantString(<wbr class="">getter->getSelector().getAsStr<wbr class="">ing()));<br class="">
+      fields.add(TypeEncoding);<br class="">
     } else {<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-      Fields.push_back(NULLPtr);<br class="">
+      fields.add(NULLPtr);<br class="">
+      fields.add(NULLPtr);<br class="">
     }<br class="">
     if (ObjCMethodDecl *setter = property->getSetterMethodDecl(<wbr class="">)) {<br class="">
       std::string TypeStr;<br class="">
@@ -2163,26 +2147,18 @@ llvm::Constant *CGObjCGNU::GeneratePrope<br class="">
         InstanceMethodTypes.push_back<wbr class="">(TypeEncoding);<br class="">
         InstanceMethodSels.push_back(<wbr class="">setter->getSelector());<br class="">
       }<br class="">
-      Fields.push_back(MakeConstantS<wbr class="">tring(setter->getSelector().ge<wbr class="">tAsString()));<br class="">
-      Fields.push_back(TypeEncoding)<wbr class="">;<br class="">
+      fields.add(MakeConstantString(<wbr class="">setter->getSelector().getAsStr<wbr class="">ing()));<br class="">
+      fields.add(TypeEncoding);<br class="">
     } else {<br class="">
-      Fields.push_back(NULLPtr);<br class="">
-      Fields.push_back(NULLPtr);<br class="">
+      fields.add(NULLPtr);<br class="">
+      fields.add(NULLPtr);<br class="">
     }<br class="">
-    Properties.push_back(llvm::Con<wbr class="">stantStruct::get(PropertyMetad<wbr class="">ataTy, Fields));<br class="">
+    properties.add(fields.finish()<wbr class="">);<br class="">
   }<br class="">
-  llvm::ArrayType *PropertyArrayTy =<br class="">
-      llvm::ArrayType::get(PropertyM<wbr class="">etadataTy, Properties.size());<br class="">
-  llvm::Constant *PropertyArray = llvm::ConstantArray::get(Prope<wbr class="">rtyArrayTy,<br class="">
-          Properties);<br class="">
-  llvm::Constant* PropertyListInitFields[] =<br class="">
-    {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};<br class="">
-<br class="">
-  llvm::Constant *PropertyListInit =<br class="">
-      llvm::ConstantStruct::getAnon(<wbr class="">PropertyListInitFields);<br class="">
-  return new llvm::GlobalVariable(TheModule<wbr class="">, PropertyListInit->getType(), false,<br class="">
-          llvm::GlobalValue::InternalLin<wbr class="">kage, PropertyListInit,<br class="">
-          ".objc_property_list");<br class="">
+  propertyList.add(<a href="http://properties.fi/" target="_blank" class="">properties.fi</a><wbr class="">nish());<br class="">
+<br class="">
+  return propertyList.finishAndCreateGl<wbr class="">obal(".objc_property_list",<br class="">
+                                            CGM.getPointerAlign());<br class="">
 }<br class="">
<br class="">
 void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {<br class="">
@@ -2231,7 +2207,8 @@ void CGObjCGNU::GenerateClass(const ObjC<br class="">
   SmallVector<llvm::Constant*, 16> IvarTypes;<br class="">
   SmallVector<llvm::Constant*, 16> IvarOffsets;<br class="">
<br class="">
-  std::vector<llvm::Constant*> IvarOffsetValues;<br class="">
+  ConstantBuilder IvarOffsetBuilder(CGM);<br class="">
+  auto IvarOffsetValues = IvarOffsetBuilder.beginArray(P<wbr class="">trToIntTy);<br class="">
   SmallVector<bool, 16> WeakIvars;<br class="">
   SmallVector<bool, 16> StrongIvars;<br class="">
<br class="">
@@ -2275,7 +2252,7 @@ void CGObjCGNU::GenerateClass(const ObjC<br class="">
           "__objc_ivar_offset_value_" + ClassName +"." +<br class="">
           IVD->getNameAsString());<br class="">
       IvarOffsets.push_back(OffsetV<wbr class="">alue);<br class="">
-      IvarOffsetValues.push_back(Off<wbr class="">setVar);<br class="">
+      IvarOffsetValues.add(OffsetVar<wbr class="">);<br class="">
       Qualifiers::ObjCLifetime lt = IVD->getType().getQualifiers()<wbr class="">.getObjCLifetime();<br class="">
       switch (lt) {<br class="">
         case Qualifiers::OCL_Strong:<br class="">
@@ -2294,8 +2271,8 @@ void CGObjCGNU::GenerateClass(const ObjC<br class="">
   llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);<br class="">
   llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);<br class="">
   llvm::GlobalVariable *IvarOffsetArray =<br class="">
-    MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),<br class="">
-                    ".ivar.offsets");<br class="">
+    IvarOffsetValues.finishAndCrea<wbr class="">teGlobal(".ivar.offsets",<br class="">
+                                           CGM.getPointerAlign());<br class="">
<br class="">
   // Collect information about instance methods<br class="">
   SmallVector<Selector, 16> InstanceMethodSels;<br class="">
@@ -2461,21 +2438,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
     if (StringClass.empty()) StringClass = "NXConstantString";<br class="">
<br class="">
     Elements.push_back(MakeConsta<wbr class="">ntString(StringClass,<br class="">
-                ".objc_static_class_name"));<br class="">
+                                          ".objc_static_class_name"));<br class="">
     Elements.push_back(llvm::Cons<wbr class="">tantArray::get(StaticsArrayTy,<br class="">
-       ConstantStrings));<br class="">
-    llvm::StructType *StaticsListTy =<br class="">
-      llvm::StructType::get(PtrToInt<wbr class="">8Ty, StaticsArrayTy, nullptr);<br class="">
-    llvm::Type *StaticsListPtrTy =<br class="">
-      llvm::PointerType::getUnqual(S<wbr class="">taticsListTy);<br class="">
-    Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),<br class="">
-                         ".objc_statics");<br class="">
+                                                ConstantStrings));<br class="">
+    Statics = MakeGlobal(llvm::ConstantStruc<wbr class="">t::getAnon(Elements),<br class="">
+                         CGM.getPointerAlign(), ".objc_statics");<br class="">
+    llvm::Type *StaticsListPtrTy = Statics->getType();<br class="">
     llvm::ArrayType *StaticsListArrayTy =<br class="">
       llvm::ArrayType::get(StaticsL<wbr class="">istPtrTy, 2);<br class="">
     Elements.clear();<br class="">
     Elements.push_back(Statics);<br class="">
     Elements.push_back(llvm::Cons<wbr class="">tant::getNullValue(StaticsList<wbr class="">PtrTy));<br class="">
-    Statics = MakeGlobal(StaticsListArrayTy, Elements,<br class="">
+    Statics = MakeGlobal(llvm::ConstantArray<wbr class="">::get(StaticsListArrayTy, Elements),<br class="">
                          CGM.getPointerAlign(), ".objc_statics_ptr");<br class="">
     Statics = llvm::ConstantExpr::getBitCast<wbr class="">(Statics, PtrTy);<br class="">
   }<br class="">
@@ -2489,7 +2463,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
<br class="">
   Elements.clear();<br class="">
   // Pointer to an array of selectors used in this module.<br class="">
-  std::vector<llvm::Constant*> Selectors;<br class="">
+  ConstantBuilder SelectorBuilder(CGM);<br class="">
+  auto Selectors = SelectorBuilder.beginArray(Sel<wbr class="">StructTy);<br class="">
   std::vector<llvm::GlobalAlias<wbr class="">*> SelectorAliases;<br class="">
   for (SelectorMap::iterator iter = SelectorTable.begin(),<br class="">
       iterEnd = SelectorTable.end(); iter != iterEnd ; ++iter) {<br class="">
@@ -2505,10 +2480,10 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
       if (!i->first.empty())<br class="">
         SelectorTypeEncoding = MakeConstantString(i->first, ".objc_sel_types");<br class="">
<br class="">
-      Elements.push_back(SelName);<br class="">
-      Elements.push_back(SelectorTyp<wbr class="">eEncoding);<br class="">
-      Selectors.push_back(llvm::Cons<wbr class="">tantStruct::get(SelStructTy, Elements));<br class="">
-      Elements.clear();<br class="">
+      auto SelStruct = Selectors.beginStruct(SelStruc<wbr class="">tTy);<br class="">
+      SelStruct.add(SelName);<br class="">
+      SelStruct.add(SelectorTypeEnco<wbr class="">ding);<br class="">
+      Selectors.add(SelStruct.finish<wbr class="">());<br class="">
<br class="">
       // Store the selector alias for later replacement<br class="">
       SelectorAliases.push_back(i-><wbr class="">second);<br class="">
@@ -2519,16 +2494,18 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
   // because the selector list has a length field.  Unfortunately, the GCC<br class="">
   // runtime decides to ignore the length field and expects a NULL terminator,<br class="">
   // and GCC cooperates with this by always setting the length to 0.<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Elements.push_back(NULLPtr);<br class="">
-  Selectors.push_back(llvm::Cons<wbr class="">tantStruct::get(SelStructTy, Elements));<br class="">
-  Elements.clear();<br class="">
+  {<br class="">
+    auto SelStruct = Selectors.beginStruct(SelStruc<wbr class="">tTy);<br class="">
+    SelStruct.add(NULLPtr);<br class="">
+    SelStruct.add(NULLPtr);<br class="">
+    Selectors.add(SelStruct.finish<wbr class="">());<br class="">
+  }<br class="">
<br class="">
   // Number of static selectors<br class="">
   Elements.push_back(llvm::Cons<wbr class="">tantInt::get(LongTy, SelectorCount));<br class="">
   llvm::GlobalVariable *SelectorList =<br class="">
-      MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),<br class="">
-                      ".objc_selector_list");<br class="">
+      Selectors.finishAndCreateGloba<wbr class="">l(".objc_selector_list",<br class="">
+                                      CGM.getPointerAlign());<br class="">
   Elements.push_back(llvm::Cons<wbr class="">tantExpr::getBitCast(SelectorL<wbr class="">ist,<br class="">
     SelStructPtrTy));<br class="">
<br class="">
@@ -2562,7 +2539,8 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
   Elements.push_back(ClassList)<wbr class="">;<br class="">
   // Construct the symbol table<br class="">
   llvm::Constant *SymTab =<br class="">
-    MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());<br class="">
+    MakeGlobal(llvm::ConstantStruc<wbr class="">t::get(SymTabTy, Elements),<br class="">
+               CGM.getPointerAlign());<br class="">
<br class="">
   // The symbol table is contained in a module which has some version-checking<br class="">
   // constants<br class="">
@@ -2603,7 +2581,9 @@ llvm::Function *CGObjCGNU::ModuleInitFun<br class="">
         break;<br class="">
     }<br class="">
<br class="">
-  llvm::Value *Module = MakeGlobal(ModuleTy, Elements, CGM.getPointerAlign());<br class="">
+  llvm::Value *Module =<br class="">
+    MakeGlobal(llvm::ConstantStruc<wbr class="">t::get(ModuleTy, Elements),<br class="">
+               CGM.getPointerAlign());<br class="">
<br class="">
   // Create the load function calling the runtime entry point with the module<br class="">
   // structure<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CGOpenMP<wbr class="">Runtime.cpp<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/CG<wbr class="">OpenMPRuntime.cpp?rev=287437&r<wbr class="">1=287436&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CGOpenMP<wbr class="">Runtime.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CGOpenMP<wbr class="">Runtime.cpp Sat Nov 19 02:17:24 2016<br class="">
@@ -15,6 +15,7 @@<br class="">
 #include "CGCleanup.h"<br class="">
 #include "CGOpenMPRuntime.h"<br class="">
 #include "CodeGenFunction.h"<br class="">
+#include "ConstantBuilder.h"<br class=""></div></div><span class="">
 #include "clang/AST/Decl.h"<br class="">
 #include "clang/AST/StmtOpenMP.h"<br class="">
 #include "llvm/ADT/ArrayRef.h"<br class="">
@@ -906,18 +907,19 @@ Address CGOpenMPRuntime::getOrCreateDe<wbr class="">fa<br class="">
       DefaultOpenMPPSource =<br class="">
           llvm::ConstantExpr::getBitCas<wbr class="">t(DefaultOpenMPPSource, CGM.Int8PtrTy);<br class="">
     }<br class="">
-    auto DefaultOpenMPLocation = new llvm::GlobalVariable(<br class="">
-        CGM.getModule(), IdentTy, /*isConstant*/ true,<br class="">
-        llvm::GlobalValue::PrivateLink<wbr class="">age, /*Initializer*/ nullptr);<br class=""></span>
+<br class="">
+    ConstantBuilder builder(CGM);<div class=""><div class="h5"><br class="">
+    auto fields = builder.beginStruct(IdentTy);<br class="">
+    fields.addInt(CGM.Int32Ty, 0);<br class="">
+    fields.addInt(CGM.Int32Ty, Flags);<br class="">
+    fields.addInt(CGM.Int32Ty, 0);<br class="">
+    fields.addInt(CGM.Int32Ty, 0);<br class="">
+    fields.add(DefaultOpenMPPSourc<wbr class="">e);<br class="">
+    auto DefaultOpenMPLocation =<br class="">
+      fields.finishAndCreateGlobal("<wbr class="">", Align, /*isConstant*/ true,<br class="">
+                                   llvm::GlobalValue::PrivateLin<wbr class="">kage);<br class="">
     DefaultOpenMPLocation->setUnn<wbr class="">amedAddr(llvm::GlobalValue::Un<wbr class="">namedAddr::Global);<br class="">
-    DefaultOpenMPLocation->setAlig<wbr class="">nment(Align.getQuantity());<br class="">
<br class="">
-    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int<wbr class="">32Ty, 0, true);<br class="">
-    llvm::Constant *Values[] = {Zero,<br class="">
-                                llvm::ConstantInt::get(CGM.Int<wbr class="">32Ty, Flags),<br class="">
-                                Zero, Zero, DefaultOpenMPPSource};<br class="">
-    llvm::Constant *Init = llvm::ConstantStruct::get(Iden<wbr class="">tTy, Values);<br class="">
-    DefaultOpenMPLocation->setInit<wbr class="">ializer(Init);<br class="">
     OpenMPDefaultLocMap[Flags] = Entry = DefaultOpenMPLocation;<br class="">
   }<br class="">
   return Address(Entry, Align);<br class="">
@@ -2810,9 +2812,10 @@ CGOpenMPRuntime::createOffload<wbr class="">ingBinaryD<br class="">
       ".omp_offloading.entries_end"<wbr class="">);<br class="">
<br class="">
   // Create all device images<br class="">
-  llvm::SmallVector<llvm::Consta<wbr class="">nt *, 4> DeviceImagesEntires;<br class="">
   auto *DeviceImageTy = cast<llvm::StructType>(<br class="">
       CGM.getTypes().ConvertTypeFor<wbr class="">Mem(getTgtDeviceImageQTy()));<br class="">
+  ConstantBuilder DeviceImagesBuilder(CGM);<br class="">
+  auto DeviceImagesEntries = DeviceImagesBuilder.beginArray<wbr class="">(DeviceImageTy);<br class="">
<br class="">
   for (unsigned i = 0; i < Devices.size(); ++i) {<br class="">
     StringRef T = Devices[i].getTriple();<br class="">
@@ -2824,22 +2827,19 @@ CGOpenMPRuntime::createOffload<wbr class="">ingBinaryD<br class="">
         M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLin<wbr class="">kage,<br class="">
         /*Initializer=*/nullptr, Twine(".omp_offloading.img_end<wbr class="">.") + Twine(T));<br class="">
<br class="">
-    llvm::Constant *Dev =<br class="">
-        llvm::ConstantStruct::get(Devi<wbr class="">ceImageTy, ImgBegin, ImgEnd,<br class="">
-                                  HostEntriesBegin, HostEntriesEnd, nullptr);<br class="">
-    DeviceImagesEntires.push_back(<wbr class="">Dev);<br class="">
+    auto Dev = DeviceImagesEntries.beginStruc<wbr class="">t(DeviceImageTy);<br class="">
+    Dev.add(ImgBegin);<br class="">
+    Dev.add(ImgEnd);<br class="">
+    Dev.add(HostEntriesBegin);<br class="">
+    Dev.add(HostEntriesEnd);<br class="">
+    DeviceImagesEntries.add(<a href="http://Dev.fi" class="">Dev.fi</a><wbr class="">nish());<br class="">
   }<br class="">
<br class="">
   // Create device images global array.<br class="">
-  llvm::ArrayType *DeviceImagesInitTy =<br class="">
-      llvm::ArrayType::get(DeviceIma<wbr class="">geTy, DeviceImagesEntires.size());<br class="">
-  llvm::Constant *DeviceImagesInit =<br class="">
-      llvm::ConstantArray::get(Devic<wbr class="">eImagesInitTy, DeviceImagesEntires);<br class="">
-<br class="">
-  llvm::GlobalVariable *DeviceImages = new llvm::GlobalVariable(<br class="">
-      M, DeviceImagesInitTy, /*isConstant=*/true,<br class="">
-      llvm::GlobalValue::InternalLin<wbr class="">kage, DeviceImagesInit,<br class="">
-      ".omp_offloading.device_images<wbr class="">");<br class="">
+  llvm::GlobalVariable *DeviceImages =<br class="">
+    DeviceImagesEntries.finishAndC<wbr class="">reateGlobal(".omp_offloading.d<wbr class="">evice_images",<br class="">
+                                              CGM.getPointerAlign(),<br class="">
+                                              /*isConstant=*/true);<br class="">
   DeviceImages->setUnnamedAddr(<wbr class="">llvm::GlobalValue::UnnamedAddr<wbr class="">::Global);<br class="">
<br class="">
   // This is a Zero array to be used in the creation of the constant expressions<br class="">
@@ -2849,16 +2849,18 @@ CGOpenMPRuntime::createOffload<wbr class="">ingBinaryD<br class="">
   // Create the target region descriptor.<br class="">
   auto *BinaryDescriptorTy = cast<llvm::StructType>(<br class="">
       CGM.getTypes().ConvertTypeFor<wbr class="">Mem(getTgtBinaryDescriptorQTy(<wbr class="">)));<br class="">
-  llvm::Constant *TargetRegionsDescriptorInit = llvm::ConstantStruct::get(<br class="">
-      BinaryDescriptorTy, llvm::ConstantInt::get(CGM.Int<wbr class="">32Ty, Devices.size()),<br class="">
-      llvm::ConstantExpr::getGetElem<wbr class="">entPtr(DeviceImagesInitTy, DeviceImages,<br class="">
-                                           Index),<br class="">
-      HostEntriesBegin, HostEntriesEnd, nullptr);<br class="">
-<br class="">
-  auto *Desc = new llvm::GlobalVariable(<br class="">
-      M, BinaryDescriptorTy, /*isConstant=*/true,<br class="">
-      llvm::GlobalValue::InternalLin<wbr class="">kage, TargetRegionsDescriptorInit,<br class="">
-      ".omp_offloading.descriptor");<br class="">
+  ConstantBuilder DescBuilder(CGM);<br class="">
+  auto DescInit = DescBuilder.beginStruct(Binary<wbr class="">DescriptorTy);<br class="">
+  DescInit.addInt(CGM.Int32Ty, Devices.size());<br class="">
+  DescInit.add(llvm::ConstantExp<wbr class="">r::getGetElementPtr(DeviceImag<wbr class="">es->getValueType(),<br class="">
+                                                    DeviceImages,<br class="">
+                                                    Index));<br class="">
+  DescInit.add(HostEntriesBegin)<wbr class="">;<br class="">
+  DescInit.add(HostEntriesEnd);<br class="">
+<br class="">
+  auto *Desc = DescInit.finishAndCreateGlobal<wbr class="">(".omp_offloading.descriptor",<br class="">
+                                              CGM.getPointerAlign(),<br class="">
+                                              /*isConstant=*/true);<br class="">
<br class="">
   // Emit code to register or unregister the descriptor at execution<br class="">
   // startup or closing, respectively.<br class="">
@@ -2906,19 +2908,24 @@ void CGOpenMPRuntime::createOffload<wbr class="">Entry<br class="">
   Str->setUnnamedAddr(llvm::Glo<wbr class="">balValue::UnnamedAddr::Global)<wbr class="">;<br class="">
   llvm::Constant *StrPtr = llvm::ConstantExpr::getBitCast<wbr class="">(Str, CGM.Int8PtrTy);<br class="">
<br class="">
+  // We can't have any padding between symbols, so we need to have 1-byte<br class="">
+  // alignment.<br class="">
+  auto Align = CharUnits::fromQuantity(1);<br class="">
+<br class="">
   // Create the entry struct.<br class="">
-  llvm::Constant *EntryInit = llvm::ConstantStruct::get(<br class="">
-      TgtOffloadEntryType, AddrPtr, StrPtr,<br class="">
-      llvm::ConstantInt::get(CGM.Siz<wbr class="">eTy, Size), nullptr);<br class="">
-  llvm::GlobalVariable *Entry = new llvm::GlobalVariable(<br class="">
-      M, TgtOffloadEntryType, true, llvm::GlobalValue::ExternalLin<wbr class="">kage,<br class="">
-      EntryInit, ".omp_offloading.entry");<br class="">
+  ConstantBuilder EntryBuilder(CGM);<br class="">
+  auto EntryInit = EntryBuilder.beginStruct(TgtOf<wbr class="">floadEntryType);<br class="">
+  EntryInit.add(AddrPtr);<br class="">
+  EntryInit.add(StrPtr);<br class="">
+  EntryInit.addInt(CGM.SizeTy, Size);<br class="">
+  llvm::GlobalVariable *Entry =<br class="">
+    EntryInit.finishAndCreateGloba<wbr class="">l(".omp_offloading.entry",<br class="">
+                                    Align,<br class=""></div></div>
+                                    /*constant*/ true,<div class=""><div class="h5"><br class="">
+                                    llvm::GlobalValue::ExternalLin<wbr class="">kage);<br class="">
<br class="">
   // The entry has to be created in the section the linker expects it to be.<br class="">
   Entry->setSection(".omp_offlo<wbr class="">ading.entries");<br class="">
-  // We can't have any padding between symbols, so we need to have 1-byte<br class="">
-  // alignment.<br class="">
-  Entry->setAlignment(1);<br class="">
 }<br class="">
<br class="">
 void CGOpenMPRuntime::createOffload<wbr class="">EntriesAndInfoMetadata() {<br class="">
<br class="">
Modified: cfe/trunk/lib/CodeGen/CodeGenM<wbr class="">odule.cpp<br class="">
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" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/Co<wbr class="">deGenModule.cpp?rev=287437&r1=<wbr class="">287436&r2=287437&view=diff</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/CodeGenM<wbr class="">odule.cpp (original)<br class="">
+++ cfe/trunk/lib/CodeGen/CodeGenM<wbr class="">odule.cpp Sat Nov 19 02:17:24 2016<br class="">
@@ -24,6 +24,7 @@<br class="">
 #include "CodeGenFunction.h"<br class="">
 #include "CodeGenPGO.h"<br class="">
 #include "CodeGenTBAA.h"<br class="">
+#include "ConstantBuilder.h"<br class="">
 #include "CoverageMappingGen.h"<br class="">
 #include "TargetInfo.h"<br class="">
 #include "clang/AST/ASTContext.h"<br class="">
@@ -731,6 +732,8 @@ void CodeGenModule::AddGlobalDtor(l<wbr class="">lvm::<br class="">
 }<br class="">
<br class="">
 void CodeGenModule::EmitCtorList(Ct<wbr class="">orList &Fns, const char *GlobalName) {<br class="">
+  if (Fns.empty()) return;<br class="">
+<br class="">
   // Ctor function type is void()*.<br class="">
   llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy<wbr class="">, false);<br class="">
   llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(C<wbr class="">torFTy);<br class="">
@@ -740,24 +743,22 @@ void CodeGenModule::EmitCtorList(Ct<wbr class="">orLis<br class="">
       Int32Ty, llvm::PointerType::getUnqual(C<wbr class="">torFTy), VoidPtrTy, nullptr);<br class="">
<br class="">
   // Construct the constructor and destructor arrays.<br class="">
-  SmallVector<llvm::Constant *, 8> Ctors;<br class="">
+  ConstantBuilder builder(*this);<br class="">
+  auto ctors = builder.beginArray(CtorStructT<wbr class="">y);<br class="">
   for (const auto &I : Fns) {<br class="">
-    llvm::Constant *S[] = {<br class="">
-        llvm::ConstantInt::get(Int32Ty<wbr class="">, I.Priority, false),<br class="">
-        llvm::ConstantExpr::getBitCast<wbr class="">(I.Initializer, CtorPFTy),<br class="">
-        (I.AssociatedData<br class="">
-             ? llvm::ConstantExpr::getBitCast<wbr class="">(I.AssociatedData, VoidPtrTy)<br class="">
-             : llvm::Constant::getNullValue(V<wbr class="">oidPtrTy))};<br class="">
-    Ctors.push_back(llvm::Constant<wbr class="">Struct::get(CtorStructTy, S));<br class="">
+    auto ctor = ctors.beginStruct(CtorStructTy<wbr class="">);<br class="">
+    ctor.addInt(Int32Ty, I.Priority);<br class="">
+    ctor.add(llvm::ConstantExpr::g<wbr class="">etBitCast(I.Initializer, CtorPFTy));<br class="">
+    if (I.AssociatedData)<br class="">
+      ctor.add(llvm::ConstantExpr::g<wbr class="">etBitCast(I.AssociatedData, VoidPtrTy));<br class="">
+    else<br class="">
+      ctor.addNullPointer(VoidPtrTy)<wbr class="">;<br class="">
+    ctors.add(ctor.finish());<br class="">
   }<br class="">
<br class="">
-  if (!Ctors.empty()) {<br class="">
-    llvm::ArrayType *AT = llvm::ArrayType::get(CtorStruc<wbr class="">tTy, Ctors.size());<br class="">
-    new llvm::GlobalVariable(TheModule<wbr class="">, AT, false,<br class="">
-                             llvm::GlobalValue::AppendingL<wbr class="">inkage,<br class="">
-                             llvm::ConstantArray::get(AT, Ctors),<br class="">
-                             GlobalName);<br class="">
-  }<br class="">
+  (void) ctors.finishAndCreateGlobal(Gl<wbr class="">obalName, getPointerAlign(),<br class=""></div></div>
+                                     /*constant*/ false,<div class=""><div class="h5"><br class="">
+                                     llvm::GlobalValue::AppendingL<wbr class="">inkage);<br class="">
   Fns.clear();<br class="">
 }<br class="">
<br class="">
@@ -3190,15 +3191,14 @@ CodeGenModule::GetAddrOfConsta<wbr class="">ntCFString<br class="">
<br class="">
   auto *STy = cast<llvm::StructType>(getType<wbr class="">s().ConvertType(CFTy));<br class="">
<br class="">
-  llvm::Constant *Fields[4];<br class="">
+  ConstantBuilder Builder(*this);<br class="">
+  auto Fields = Builder.beginStruct(STy);<br class="">
<br class="">
   // Class pointer.<br class="">
-  Fields[0] = cast<llvm::ConstantExpr>(CFCon<wbr class="">stantStringClassRef);<br class="">
+  Fields.add(cast<llvm::Constant<wbr class="">Expr>(CFConstantStringClassRef<wbr class="">));<br class="">
<br class="">
   // Flags.<br class="">
-  llvm::Type *Ty = getTypes().ConvertType(getCont<wbr class="">ext().UnsignedIntTy);<br class="">
-  Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0)<br class="">
-                      : llvm::ConstantInt::get(Ty, 0x07C8);<br class="">
+  Fields.addInt(IntTy, isUTF16 ? 0x07d0 : 0x07C8);<br class="">
<br class="">
   // String pointer.<br class="">
   llvm::Constant *C = nullptr;<br class="">
@@ -3232,25 +3232,24 @@ CodeGenModule::GetAddrOfConsta<wbr class="">ntCFString<br class="">
                            : "__TEXT,__cstring,cstring_lite<wbr class="">rals");<br class="">
<br class="">
   // String.<br class="">
-  Fields[2] =<br class="">
+  llvm::Constant *Str =<br class="">
       llvm::ConstantExpr::getGetEle<wbr class="">mentPtr(GV->getValueType(), GV, Zeros);<br class="">
<br class="">
   if (isUTF16)<br class="">
     // Cast the UTF16 string to the correct type.<br class="">
-    Fields[2] = llvm::ConstantExpr::getBitCast<wbr class="">(Fields[2], Int8PtrTy);<br class="">
+    Str = llvm::ConstantExpr::getBitCast<wbr class="">(Str, Int8PtrTy);<br class="">
+  Fields.add(Str);<br class="">
<br class="">
   // String length.<br class="">
-  Ty = getTypes().ConvertType(getCont<wbr class="">ext().LongTy);<br class="">
-  Fields[3] = llvm::ConstantInt::get(Ty, StringLength);<br class="">
+  auto Ty = getTypes().ConvertType(getCont<wbr class="">ext().LongTy);<br class="">
+  Fields.addInt(cast<llvm::Integ<wbr class="">erType>(Ty), StringLength);<br class="">
<br class="">
   CharUnits Alignment = getPointerAlign();<br class="">
<br class="">
   // The struct.<br class="">
-  C = llvm::ConstantStruct::get(STy, Fields);<br class="">
-  GV = new llvm::GlobalVariable(getModule<wbr class="">(), C->getType(), /*isConstant=*/false,<br class="">
-                                llvm::GlobalVariable::PrivateL<wbr class="">inkage, C,<br class="">
-                                "_unnamed_cfstring_");<br class="">
-  GV->setAlignment(Alignment.get<wbr class="">Quantity());<br class="">
+  GV = Fields.finishAndCreateGlobal("<wbr class="">_unnamed_cfstring_", Alignment,<br class="">
+                                    /*isConstant=*/false,<br class="">
+                                    llvm::GlobalVariable::PrivateL<wbr class="">inkage);<br class="">
   switch (getTriple().getObjectFormat()<wbr class="">) {<br class="">
   case llvm::Triple::UnknownObjectFor<wbr class="">mat:<br class="">
     llvm_unreachable("unknown file format");<br class="">
@@ -3338,19 +3337,18 @@ CodeGenModule::GetAddrOfConsta<wbr class="">ntString(c<br class="">
     NSConstantStringType = cast<llvm::StructType>(getType<wbr class="">s().ConvertType(NSTy));<br class="">
   }<br class="">
<br class="">
-  llvm::Constant *Fields[3];<br class="">
+  ConstantBuilder Builder(*this);<br class="">
+  auto Fields = Builder.beginStruct(NSConstant<wbr class="">StringType);<br class="">
<br class="">
   // Class pointer.<br class="">
-  Fields[0] = cast<llvm::ConstantExpr>(V);<br class="">
+  Fields.add(cast<llvm::Constant<wbr class="">Expr>(V));<br class="">
<br class="">
   // String pointer.<br class=""></div></div>
   llvm::Constant *C =<div class=""><div class="h5"><br class="">
       llvm::ConstantDataArray::getS<wbr class="">tring(VMContext, Entry.first());<br class="">
<br class="">
-  llvm::GlobalValue::LinkageType<wbr class="">s Linkage;<br class="">
-  bool isConstant;<br class="">
-  Linkage = llvm::GlobalValue::PrivateLink<wbr class="">age;<br class="">
-  isConstant = !LangOpts.WritableStrings;<br class="">
+  llvm::GlobalValue::LinkageType<wbr class="">s Linkage = llvm::GlobalValue::PrivateLink<wbr class="">age;<br class="">
+  bool isConstant = !LangOpts.WritableStrings;<br class="">
<br class="">
   auto *GV = new llvm::GlobalVariable(getModule<wbr class="">(), C->getType(), isConstant,<br class="">
                                       Linkage, C, ".str");<br class="">
@@ -3359,20 +3357,17 @@ CodeGenModule::GetAddrOfConsta<wbr class="">ntString(c<br class="">
   // of the string is via this class initializer.<br class="">
   CharUnits Align = getContext().getTypeAlignInCha<wbr class="">rs(getContext().CharTy);<br class="">
   GV->setAlignment(Align.getQua<wbr class="">ntity());<br class="">
-  Fields[1] =<br class="">
-      llvm::ConstantExpr::getGetElem<wbr class="">entPtr(GV->getValueType(), GV, Zeros);<br class="">
+  Fields.add(<br class="">
+      llvm::ConstantExpr::getGetElem<wbr class="">entPtr(GV->getValueType(), GV, Zeros));<br class="">
<br class="">
   // String length.<br class="">
-  llvm::Type *Ty = getTypes().ConvertType(getCont<wbr class="">ext().UnsignedIntTy);<br class="">
-  Fields[2] = llvm::ConstantInt::get(Ty, StringLength);<br class="">
+  Fields.addInt(IntTy, StringLength);<br class="">
<br class="">
   // The struct.<br class="">
   CharUnits Alignment = getPointerAlign();<br class="">
-  C = llvm::ConstantStruct::get(NSCo<wbr class="">nstantStringType, Fields);<br class="">
-  GV = new llvm::GlobalVariable(getModule<wbr class="">(), C->getType(), true,<br class="">
-                                llvm::GlobalVariable::PrivateL<wbr class="">inkage, C,<br class="">
-                                "_unnamed_nsstring_");<br class="">
-  GV->setAlignment(Alignment.get<wbr class="">Quantity());<br class="">
+  GV = Fields.finishAndCreateGlobal("<wbr class="">_unnamed_nsstring_", Alignment,<br class=""></div></div>
+                                    /*constant*/ true,<div class=""><div class="h5"><br class="">
+                                    llvm::GlobalVariable::PrivateL<wbr class="">inkage);<br class="">
   const char *NSStringSection = "__OBJC,__cstring_object,regul<wbr class="">ar,no_dead_strip";<br class="">
   const char *NSStringNonFragileABISection =<br class="">
       "__DATA,__objc_stringobj,regu<wbr class="">lar,no_dead_strip";<br class="">
<br class="">
Added: cfe/trunk/lib/CodeGen/Constant<wbr class="">Builder.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.h?rev=287437&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-pr<wbr class="">oject/cfe/trunk/lib/CodeGen/Co<wbr class="">nstantBuilder.h?rev=287437&vie<wbr class="">w=auto</a><br class="">
==============================<wbr class="">==============================<wbr class="">==================<br class="">
--- cfe/trunk/lib/CodeGen/Constant<wbr class="">Builder.h (added)<br class="">
+++ cfe/trunk/lib/CodeGen/Constant<wbr class="">Builder.h Sat Nov 19 02:17:24 2016<br class="">
@@ -0,0 +1,274 @@<br class="">
+//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//<br class="">
+//<br class="">
+//                     The LLVM Compiler Infrastructure<br class="">
+//<br class="">
+// This file is distributed under the University of Illinois Open Source<br class="">
+// License. See LICENSE.TXT for details.<br class="">
+//<br class="">
+//===------------------------<wbr class="">------------------------------<wbr class="">----------------===//<br class="">
+//<br class="">
+// This class provides a convenient interface for building complex<br class="">
+// global initializers.<br class="">
+//<br class="">
+//===------------------------<wbr class="">------------------------------<wbr class="">----------------===//<br class="">
+<br class="">
+#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTAN<wbr class="">TBUILDER_H<br class="">
+#define LLVM_CLANG_LIB_CODEGEN_CONSTAN<wbr class="">TBUILDER_H<br class="">
+<br class="">
+#include "llvm/ADT/ArrayRef.h"<br class="">
+#include "llvm/ADT/SmallVector.h"<br class="">
+#include "llvm/IR/Constants.h"<br class="">
+<br class="">
+#include "CodeGenModule.h"<br class="">
+<br class="">
+namespace clang {<br class="">
+namespace CodeGen {<br class="">
+<br class="">
+class ConstantBuilder;<br class="">
+<br class="">
+/// A convenience builder class for complex constant initializers,<br class="">
+/// especially for anonymous global structures used by various language<br class="">
+/// runtimes.<br class="">
+///<br class="">
+/// The basic usage pattern is expected to be something like:<br class="">
+///    ConstantBuilder builder(CGM);<br class="">
+///    auto toplevel = builder.beginStruct();<br class="">
+///    toplevel.addInt(CGM.SizeTy, widgets.size());<br class="">
+///    auto widgetArray = builder.beginArray();<br class="">
+///    for (auto &widget : widgets) {<br class="">
+///      auto widgetDesc = widgetArray.beginStruct();<br class="">
+///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());<br class="">
+///      widgetDesc.add(CGM.GetAddrOfCo<wbr class="">nstantString(widget.getName())<wbr class="">);<br class="">
+///      widgetDesc.add(CGM.GetAddrOfGl<wbr class="">obal(widget.getInitializerDecl<wbr class="">()));<br class="">
+///      widgetArray.add(widgetDesc.fin<wbr class="">ish());<br class="">
+///    }<br class="">
+///    toplevel.add(widgetArray.finis<wbr class="">h());<br class="">
+///    auto global = toplevel.finishAndCreateGlobal<wbr class="">("WIDGET_LIST", Align,<br class="">
+///                                                 /*constant*/ true);<br class="">
+class ConstantBuilder {<br class="">
+  CodeGenModule &CGM;<br class="">
+  llvm::SmallVector<llvm::Consta<wbr class="">nt*, 16> Buffer;<br class="">
+  bool Frozen = false;<br class="">
+<br class="">
+public:<br class="">
+  explicit ConstantBuilder(CodeGenModule &CGM) : CGM(CGM) {}<br class="">
+<br class="">
+  ~ConstantBuilder() {<br class="">
+    assert(Buffer.empty() && "didn't claim all values out of buffer");<br class="">
+  }<br class="">
+<br class="">
+  class ArrayBuilder;<br class="">
+  class StructBuilder;<br class="">
+<br class="">
+  class AggregateBuilder {<br class="">
+  protected:<br class="">
+    ConstantBuilder &Builder;<br class="">
+    AggregateBuilder *Parent;<br class="">
+    size_t Begin;<br class="">
+    bool Finished = false;<br class="">
+    bool Frozen = false;<br class="">
+<br class="">
+    AggregateBuilder(ConstantBuild<wbr class="">er &builder, AggregateBuilder *parent)<br class="">
+        : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {<br class="">
+      if (parent) {<br class="">
+        assert(!parent->Frozen && "parent already has child builder active");<br class="">
+        parent->Frozen = true;<br class="">
+      } else {<br class="">
+        assert(!builder.Frozen && "builder already has child builder active");<br class="">
+        builder.Frozen = true;<br class="">
+      }<br class="">
+    }<br class="">
+<br class="">
+    ~AggregateBuilder() {<br class="">
+      assert(Finished && "didn't claim value from aggregate builder");<br class="">
+    }<br class="">
+<br class="">
+    void markFinished() {<br class="">
+      assert(!Frozen && "child builder still active");<br class="">
+      assert(!Finished && "builder already finished");<br class="">
+      Finished = true;<br class="">
+      if (Parent) {<br class="">
+        assert(Parent->Frozen &&<br class="">
+               "parent not frozen while child builder active");<br class="">
+        Parent->Frozen = false;<br class="">
+      } else {<br class="">
+        assert(Builder.Frozen &&<br class="">
+               "builder not frozen while child builder active");<br class="">
+        Builder.Frozen = false;<br class="">
+      }<br class="">
+    }<br class="">
+<br class="">
+  public:<br class="">
+    // Not copyable.<br class="">
+    AggregateBuilder(const AggregateBuilder &) = delete;<br class="">
+    AggregateBuilder &operator=(const AggregateBuilder &) = delete;<br class="">
+<br class="">
+    // Movable, mostly to allow returning.  But we have to write this out<br class="">
+    // properly to satisfy the assert in the destructor.<br class="">
+    AggregateBuilder(AggregateBuil<wbr class="">der &&other)<br class="">
+      : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),<br class="">
+        Finished(other.Finished), Frozen(other.Frozen) {<br class="">
+      other.Finished = false;<br class="">
+    }<br class="">
+    AggregateBuilder &operator=(AggregateBuilder &&other) = delete;<br class="">
+<br class="">
+    void add(llvm::Constant *value) {<br class="">
+      assert(!Finished && "cannot add more values after finishing builder");<br class="">
+      Builder.Buffer.push_back(value<wbr class="">);<br class="">
+    }<br class="">
+<br class="">
+    void addSize(CharUnits size) {<br class="">
+      add(Builder.CGM.getSize(size))<wbr class="">;<br class="">
+    }<br class="">
+<br class="">
+    void addInt(llvm::IntegerType *intTy, uint64_t value,<br class="">
+                bool isSigned = false) {<br class="">
+      add(llvm::ConstantInt::get(int<wbr class="">Ty, value, isSigned));<br class="">
+    }<br class="">
+<br class="">
+    void addNullPointer(llvm::PointerTy<wbr class="">pe *ptrTy) {<br class="">
+      add(llvm::ConstantPointerNull:<wbr class="">:get(ptrTy));<br class="">
+    }<br class="">
+<br class="">
+    ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition<wbr class="">(<br class="">
+                             llvm::SmallVectorImpl<llvm::C<wbr class="">onstant*> &indices) {<br class="">
+      getGEPIndicesTo(indices, Builder.Buffer.size());<br class="">
+      return indices;<br class="">
+    }<br class="">
+<br class="">
+    ArrayBuilder beginArray(llvm::Type *eltTy = nullptr);<br class="">
+    StructBuilder beginStruct(llvm::StructType *structTy = nullptr);<br class="">
+<br class="">
+  private:<br class="">
+    void getGEPIndicesTo(llvm::SmallVec<wbr class="">torImpl<llvm::Constant*> &indices,<br class="">
+                         size_t position) const {<br class="">
+      // Recurse on the parent builder if present.<br class="">
+      if (Parent) {<br class="">
+        Parent->getGEPIndicesTo(indice<wbr class="">s, Begin);<br class="">
+<br class="">
+      // Otherwise, add an index to drill into the first level of pointer.<br class="">
+      } else {<br class="">
+        assert(indices.empty());<br class="">
+        indices.push_back(llvm::Consta<wbr class="">ntInt::get(Builder.CGM.SizeTy, 0));<br class="">
+      }<br class="">
+<br class="">
+      assert(position >= Begin);<br class="">
+      indices.push_back(llvm::Consta<wbr class="">ntInt::get(Builder.CGM.SizeTy,<br class="">
+                                               position - Begin));<br class="">
+    }<br class="">
+  };<br class="">
+<br class="">
+  class ArrayBuilder : public AggregateBuilder {<br class="">
+    llvm::Type *EltTy;<br class="">
+    friend class ConstantBuilder;<br class="">
+    ArrayBuilder(ConstantBuilder &builder, AggregateBuilder *parent,<br class="">
+                 llvm::Type *eltTy)<br class="">
+      : AggregateBuilder(builder, parent), EltTy(eltTy) {}<br class="">
+  public:<br class="">
+    size_t size() const {<br class="">
+      assert(!Finished);<br class="">
+      assert(!Frozen);<br class="">
+      assert(Begin <= Builder.Buffer.size());<br class="">
+      return Builder.Buffer.size() - Begin;<br class="">
+    }<br class="">
+<br class="">
+    /// Form an array constant from the values that have been added to this<br class="">
+    /// builder.<br class="">
+    llvm::Constant *finish() {<br class="">
+      markFinished();<br class="">
+<br class="">
+      auto &buffer = Builder.Buffer;<br class="">
+      assert((Begin < buffer.size() ||<br class="">
+              (Begin == buffer.size() && EltTy))<br class="">
+             && "didn't add any array elements without element type");<br class="">
+      auto elts = llvm::makeArrayRef(buffer).sli<wbr class="">ce(Begin);<br class="">
+      auto eltTy = EltTy ? EltTy : elts[0]->getType();<br class="">
+      auto type = llvm::ArrayType::get(eltTy, elts.size());<br class="">
+      auto constant = llvm::ConstantArray::get(type, elts);<br class="">
+      buffer.erase(buffer.begin() + Begin, buffer.end());<br class="">
+      return constant;<br class="">
+    }<br class="">
+<br class="">
+    template <class... As><br class="">
+    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {<br class="">
+      assert(!Parent && "finishing non-root builder");<br class="">
+      return Builder.createGlobal(finish(), std::forward<As>(args)...);<br class="">
+    }<br class="">
+  };<br class="">
+<br class="">
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {<br class="">
+    return ArrayBuilder(*this, nullptr, eltTy);<br class="">
+  }<br class="">
+<br class="">
+  class StructBuilder : public AggregateBuilder {<br class="">
+    llvm::StructType *Ty;<br class="">
+    friend class ConstantBuilder;<br class="">
+    StructBuilder(ConstantBuilder &builder, AggregateBuilder *parent,<br class="">
+                  llvm::StructType *ty)<br class="">
+      : AggregateBuilder(builder, parent), Ty(ty) {}<br class="">
+  public:<br class="">
+    /// Finish the struct.<br class="">
+    llvm::Constant *finish(bool packed = false) {<br class="">
+      markFinished();<br class="">
+<br class="">
+      auto &buffer = Builder.Buffer;<br class="">
+      assert(Begin < buffer.size() && "didn't add any struct elements?");<br class="">
+      auto elts = llvm::makeArrayRef(buffer).sli<wbr class="">ce(Begin);<br class="">
+<br class="">
+      llvm::Constant *constant;<br class="">
+      if (Ty) {<br class="">
+        constant = llvm::ConstantStruct::get(Ty, elts);<br class="">
+      } else {<br class="">
+        constant = llvm::ConstantStruct::getAnon(<wbr class="">elts, packed);<br class="">
+      }<br class="">
+<br class="">
+      buffer.erase(buffer.begin() + Begin, buffer.end());<br class="">
+      return constant;<br class="">
+    }<br class="">
+<br class="">
+    template <class... As><br class="">
+    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {<br class="">
+      assert(!Parent && "finishing non-root builder");<br class="">
+      return Builder.createGlobal(finish(), std::forward<As>(args)...);<br class="">
+    }<br class="">
+  };<br class="">
+<br class="">
+  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {<br class="">
+    return StructBuilder(*this, nullptr, structTy);<br class="">
+  }<br class="">
+<br class="">
+  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,<br class="">
+                                     StringRef name,<br class="">
+                                     CharUnits alignment,<br class="">
+                                     bool constant = false,<br class="">
+                                     llvm::GlobalValue::LinkageTyp<wbr class="">es linkage<br class="">
+                                       = llvm::GlobalValue::InternalLin<wbr class="">kage,<br class="">
+                                     unsigned addressSpace = 0) {<br class="">
+    auto GV = new llvm::GlobalVariable(CGM.getMo<wbr class="">dule(),<br class="">
+                                       initializer->getType(),<br class="">
+                                       constant,<br class="">
+                                       linkage,<br class="">
+                                       initializer,<br class="">
+                                       name,<br class="">
+                                       /*insert before*/ nullptr,<br class="">
+                                       llvm::GlobalValue::NotThreadL<wbr class="">ocal,<br class="">
+                                       addressSpace);<br class="">
+    GV->setAlignment(alignment.get<wbr class="">Quantity());<br class="">
+    return GV;<br class="">
+  }<br class="">
+};<br class="">
+<br class="">
+inline ConstantBuilder::ArrayBuilder<br class="">
+ConstantBuilder::AggregateBui<wbr class="">lder::beginArray(llvm::Type *eltTy) {<br class="">
+  return ArrayBuilder(Builder, this, eltTy);<br class="">
+}<br class="">
+<br class="">
+inline ConstantBuilder::StructBuilder<br class="">
+ConstantBuilder::AggregateBui<wbr class="">lder::beginStruct(llvm::Struct<wbr class="">Type *structTy) {<br class="">
+  return StructBuilder(Builder, this, structTy);<br class="">
+}<br class="">
+<br class="">
+}  // end namespace CodeGen<br class="">
+}  // end namespace clang<br class="">
+<br class="">
+#endif<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a><br class="">
</div></div></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></div></blockquote></div><br class=""></div>
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>