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