diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-11 16:29:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-11 16:29:35 +0000 |
commit | 46faa67da1d7e9450e8fa363f6633e2c68e33ff1 (patch) | |
tree | ba7f8dbcd8358d07c15d1da6c2c2cc38f0febeb6 /lib/CodeGen/CGBlocks.cpp | |
parent | 874094833caedbee43fd17cca164dec53d500bdc (diff) | |
download | src-46faa67da1d7e9450e8fa363f6633e2c68e33ff1.tar.gz src-46faa67da1d7e9450e8fa363f6633e2c68e33ff1.zip |
Vendor import of clang release_70 branch r339355:vendor/clang/clang-release_70-r339355
Notes
Notes:
svn path=/vendor/clang/dist-release_70/; revision=337633
svn path=/vendor/clang/clang-release_70-r339355/; revision=337634; tag=vendor/clang/clang-release_70-r339355
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 8269b5b229a2..906b98bfbafe 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1213,9 +1213,13 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, auto fields = builder.beginStruct(); bool IsOpenCL = CGM.getLangOpts().OpenCL; + bool IsWindows = CGM.getTarget().getTriple().isOSWindows(); if (!IsOpenCL) { // isa - fields.add(CGM.getNSConcreteGlobalBlock()); + if (IsWindows) + fields.addNullPointer(CGM.Int8PtrPtrTy); + else + fields.add(CGM.getNSConcreteGlobalBlock()); // __flags BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE; @@ -1250,7 +1254,27 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM, llvm::Constant *literal = fields.finishAndCreateGlobal( "__block_literal_global", blockInfo.BlockAlign, - /*constant*/ true, llvm::GlobalVariable::InternalLinkage, AddrSpace); + /*constant*/ !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace); + + // Windows does not allow globals to be initialised to point to globals in + // different DLLs. Any such variables must run code to initialise them. + if (IsWindows) { + auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, + {}), llvm::GlobalValue::InternalLinkage, ".block_isa_init", + &CGM.getModule()); + llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry", + Init)); + b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(), + b.CreateStructGEP(literal, 0), CGM.getPointerAlign().getQuantity()); + b.CreateRetVoid(); + // We can't use the normal LLVM global initialisation array, because we + // need to specify that this runs early in library initialisation. + auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), + /*isConstant*/true, llvm::GlobalValue::InternalLinkage, + Init, ".block_isa_init_ptr"); + InitVar->setSection(".CRT$XCLa"); + CGM.addUsedGlobal(InitVar); + } // Return a constant of the appropriately-casted type. llvm::Type *RequiredType = |