r287437 - Introduce a helper class for building complex constant initializers. NFC.
John McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 22 12:22:39 PST 2016
> 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 <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 <mailto: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 <mailto:rjmccall at apple.com>> wrote:
>
>> On Nov 19, 2016, at 1:06 PM, Galina Kistanova <gkistanova at gmail.com <mailto: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-3stage-ubuntu/builds/355>
>> http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/308 <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 <mailto: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 <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 <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/CGBlocks.cpp?rev=287437&r1=287436&r2=287437&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.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.UnsignedLongTy));
>> + 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/CGCUDANV.cpp?rev=287437&r1=287436&r2=287437&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCUDANV.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(Types.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/CGObjCGNU.cpp?rev=287437&r1=287436&r2=287437&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.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::LinkOnceODRLinkage);
>> 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(ObjCMethodTy,
>> - Methods.size());
>> - llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
>> - Methods);
>> -
>> - // Structure containing list pointer, array and array count
>> - llvm::StructType *ObjCMethodListTy = llvm::StructType::create(VMContext);
>> - llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
>> - 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(ObjCMethodDescTy,
>> - 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::GenerateProtocolList(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(ProtocolArrayTy,
>> - 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(EmptyStringVector);
>> - 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(propertyMetadataTy);
>> +
>> + ConstantBuilder optPropertyListBuilder(CGM);
>> + auto optPropertiesList = optPropertyListBuilder.beginStruct();
>> + optPropertiesList.addInt(IntTy, numOptProperties);
>> + optPropertiesList.add(NULLPtr);
>> + auto optPropertiesArray = optPropertiesList.beginArray(propertyMetadataTy);
>> +
>> + // 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().getAsString()));
>> + 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().getAsString()));
>> + 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().getAsString()));
>> - 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().getAsString()));
>> - 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(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(ProtocolArrayTy,
>> - 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.finishAndCreateGlobal(".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().getAsString()));
>> - Fields.push_back(TypeEncoding);
>> + fields.add(MakeConstantString(getter->getSelector().getAsString()));
>> + 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().getAsString()));
>> - Fields.push_back(TypeEncoding);
>> + fields.add(MakeConstantString(setter->getSelector().getAsString()));
>> + 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(PropertyArrayTy,
>> - 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.fi <http://properties.fi/>nish());
>> +
>> + 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/CGOpenMPRuntime.cpp?rev=287437&r1=287436&r2=287437&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.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::UnnamedAddr::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.device_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(DeviceImages->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::ExternalLinkage);
>>
>> // 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/CodeGenModule.cpp?rev=287437&r1=287436&r2=287437&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.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::AppendingLinkage);
>> 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::PrivateLinkage);
>> switch (getTriple().getObjectFormat()) {
>> case llvm::Triple::UnknownObjectFormat:
>> llvm_unreachable("unknown file format");
>> @@ -3338,19 +3337,18 @@ CodeGenModule::GetAddrOfConstantString(c
>> NSConstantStringType = cast<llvm::StructType>(getTypes().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().getTypeAlignInChars(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::PrivateLinkage);
>> const char *NSStringSection = "__OBJC,__cstring_object,regular,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/ConstantBuilder.h?rev=287437&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantBuilder.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::InternalLinkage,
>> + unsigned addressSpace = 0) {
>> + auto GV = new llvm::GlobalVariable(CGM.getModule(),
>> + initializer->getType(),
>> + constant,
>> + linkage,
>> + initializer,
>> + name,
>> + /*insert before*/ nullptr,
>> + llvm::GlobalValue::NotThreadLocal,
>> + 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 <mailto:cfe-commits at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <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/d3cbd215/attachment-0001.html>
More information about the cfe-commits
mailing list