diff options
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 28 | ||||
| -rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 38 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenAction.cpp | 1 | 
3 files changed, 31 insertions, 36 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 = diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 3e994edc976b..915738b8b301 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -3812,40 +3812,10 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(    // is.  This allows code compiled with non-fragile ivars to work correctly    // when linked against code which isn't (most of the time).    llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name); -  if (!IvarOffsetPointer) { -    // This will cause a run-time crash if we accidentally use it.  A value of -    // 0 would seem more sensible, but will silently overwrite the isa pointer -    // causing a great deal of confusion. -    uint64_t Offset = -1; -    // We can't call ComputeIvarBaseOffset() here if we have the -    // implementation, because it will create an invalid ASTRecordLayout object -    // that we are then stuck with forever, so we only initialize the ivar -    // offset variable with a guess if we only have the interface.  The -    // initializer will be reset later anyway, when we are generating the class -    // description. -    if (!CGM.getContext().getObjCImplementation( -              const_cast<ObjCInterfaceDecl *>(ID))) -      Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); - -    llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset, -                             /*isSigned*/true); -    // Don't emit the guess in non-PIC code because the linker will not be able -    // to replace it with the real version for a library.  In non-PIC code you -    // must compile with the fragile ABI if you want to use ivars from a -    // GCC-compiled class. -    if (CGM.getLangOpts().PICLevel) { -      llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule, -            Int32Ty, false, -            llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess"); -      IvarOffsetPointer = new llvm::GlobalVariable(TheModule, -            IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage, -            IvarOffsetGV, Name); -    } else { -      IvarOffsetPointer = new llvm::GlobalVariable(TheModule, -              llvm::Type::getInt32PtrTy(VMContext), false, -              llvm::GlobalValue::ExternalLinkage, nullptr, Name); -    } -  } +  if (!IvarOffsetPointer) +    IvarOffsetPointer = new llvm::GlobalVariable(TheModule, +            llvm::Type::getInt32PtrTy(VMContext), false, +            llvm::GlobalValue::ExternalLinkage, nullptr, Name);    return IvarOffsetPointer;  } diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index d499364002f0..1a2b0616dc77 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -127,6 +127,7 @@ namespace clang {                                  CodeGenOpts, C, CoverageInfo)),            LinkModules(std::move(LinkModules)) {        FrontendTimesIsEnabled = TimePasses; +      llvm::TimePassesIsEnabled = TimePasses;      }      llvm::Module *getModule() const { return Gen->GetModule(); }      std::unique_ptr<llvm::Module> takeModule() {  | 
