r287437 - Introduce a helper class for building complex constant initializers. NFC.
Galina Kistanova via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 21 15:01:44 PST 2016
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?
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.getBlockExpr());
>>> - 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::InternalLin
>>> kage,
>>> - 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::ExternalLinkage);
>>> 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::InternalLin
>>> kage,
>>> - PropertyListInit, ".objc_property_list");
>>> -
>>> - llvm::Constant *OptionalPropertyArray =
>>> - llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
>>> - 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(GenerateMethodList(
>>> + Elements.add(llvm::ConstantExpr::getBitCast(GenerateMethodList(
>>> ClassName, CategoryName, MethodSels, MethodTypes, false),
>>> PtrTy));
>>> // Class method list
>>> - Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
>>> + 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(StaticsListPtrTy));
>>> - 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::ExternalLinkage,
>>> - 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/20161121/a8caf075/attachment-0001.html>
More information about the cfe-commits
mailing list