diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 28 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenAction.cpp | 1 | ||||
-rw-r--r-- | lib/Headers/unwind.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 10 |
5 files changed, 43 insertions, 38 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() { diff --git a/lib/Headers/unwind.h b/lib/Headers/unwind.h index 345fa4d0c193..0e8317e5b9d9 100644 --- a/lib/Headers/unwind.h +++ b/lib/Headers/unwind.h @@ -154,8 +154,12 @@ struct _Unwind_Control_Block { struct _Unwind_Exception { _Unwind_Exception_Class exception_class; _Unwind_Exception_Cleanup_Fn exception_cleanup; +#if !defined (__USING_SJLJ_EXCEPTIONS__) && defined (__SEH__) + _Unwind_Word private_[6]; +#else _Unwind_Word private_1; _Unwind_Word private_2; +#endif /* The Itanium ABI requires that _Unwind_Exception objects are "double-word * aligned". GCC has interpreted this to mean "use the maximum useful * alignment for the target"; so do we. */ diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index a1168fa34d56..7a8f2d3f4702 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -113,9 +113,15 @@ ParsedType Sema::getConstructorName(IdentifierInfo &II, break; } } - if (!InjectedClassName && CurClass->isInvalidDecl()) + if (!InjectedClassName) { + if (!CurClass->isInvalidDecl()) { + // FIXME: RequireCompleteDeclContext doesn't check dependent contexts + // properly. Work around it here for now. + Diag(SS.getLastQualifierNameLoc(), + diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange(); + } return ParsedType(); - assert(InjectedClassName && "couldn't find injected class name"); + } QualType T = Context.getTypeDeclType(InjectedClassName); DiagnoseUseOfDecl(InjectedClassName, NameLoc); |