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