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