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