Index: lib/CodeGen/CGObjCGNU.cpp =================================================================== --- lib/CodeGen/CGObjCGNU.cpp +++ lib/CodeGen/CGObjCGNU.cpp @@ -560,8 +560,9 @@ return NULLPtr; } - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override { + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override { return nullptr; } }; Index: lib/CodeGen/CGObjCMac.cpp =================================================================== --- lib/CodeGen/CGObjCMac.cpp +++ lib/CodeGen/CGObjCMac.cpp @@ -1260,8 +1260,9 @@ /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override { + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override { llvm_unreachable("CGObjCMac::GetClassGlobal"); } }; @@ -1362,8 +1363,9 @@ /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. - llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) override; + llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) override; /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class reference. @@ -5686,7 +5688,12 @@ llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy)); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, Values); - llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak); + llvm::GlobalVariable *GV = cast( + GetClassGlobal(ClassName, + /*ForDefinition=*/true, + Weak)); + if (Init->getType() != GV->getValueType()) + Init = llvm::ConstantExpr::getBitCast(Init, GV->getValueType()); GV->setInitializer(Init); GV->setSection("__DATA, __objc_data"); GV->setAlignment( @@ -5755,7 +5762,7 @@ llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix()); llvm::SmallString<64> TClassName; - llvm::GlobalVariable *SuperClassGV, *IsAGV; + llvm::Constant *SuperClassGV, *IsAGV; // Build the flags for the metaclass. bool classIsHidden = @@ -5777,10 +5784,12 @@ TClassName = ObjCClassName; TClassName += ClassName; SuperClassGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->isWeakImported()); TClassName = ObjCMetaClassName; TClassName += ClassName; IsAGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->isWeakImported()); } else { // Has a root. Current class is not a root. @@ -5790,6 +5799,7 @@ TClassName = ObjCMetaClassName ; TClassName += Root->getObjCRuntimeNameAsString(); IsAGV = GetClassGlobal(TClassName.str(), + /*ForDefinition=*/false, Root->isWeakImported()); // work on super class metadata symbol. @@ -5797,6 +5807,7 @@ TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); SuperClassGV = GetClassGlobal( TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->getSuperClass()->isWeakImported()); } llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, @@ -5839,6 +5850,7 @@ TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString(); SuperClassGV = GetClassGlobal( TClassName.str(), + /*ForDefinition=*/false, ID->getClassInterface()->getSuperClass()->isWeakImported()); } GetClassSizeInfo(ID, InstanceStart, InstanceSize); @@ -5928,8 +5940,9 @@ llvm::Constant *Values[6]; Values[0] = GetClassName(OCD->getIdentifier()->getName()); // meta-class entry symbol - llvm::GlobalVariable *ClassGV = - GetClassGlobal(ExtClassName.str(), Interface->isWeakImported()); + llvm::Constant *ClassGV = GetClassGlobal(ExtClassName.str(), + /*ForDefinition=*/false, + Interface->isWeakImported()); Values[1] = ClassGV; std::vector Methods; @@ -6598,8 +6611,10 @@ false, CallArgs, Method, ObjCTypes); } -llvm::GlobalVariable * -CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) { +llvm::Constant * +CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) { llvm::GlobalValue::LinkageTypes L = Weak ? llvm::GlobalValue::ExternalWeakLinkage : llvm::GlobalValue::ExternalLinkage; @@ -6611,7 +6626,12 @@ false, L, nullptr, Name); assert(GV->getLinkage() == L); - return GV; + + if (ForDefinition || + GV->getValueType() == ObjCTypes.ClassnfABITy) + return GV; + + return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ClassnfABIPtrTy); } llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, @@ -6624,7 +6644,9 @@ std::string ClassName( getClassSymbolPrefix() + (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str()); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak); + llvm::Constant *ClassGV = GetClassGlobal(ClassName, + /*ForDefinition=*/false, + Weak); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, ClassGV, "OBJC_CLASSLIST_REFERENCES_$_"); @@ -6656,8 +6678,9 @@ if (!Entry) { llvm::SmallString<64> ClassName(getClassSymbolPrefix()); ClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), - ID->isWeakImported()); + llvm::Constant *ClassGV = GetClassGlobal(ClassName.str(), + /*ForDefinition=*/false, + ID->isWeakImported()); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_"); @@ -6680,8 +6703,9 @@ if (!Entry) { llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix()); MetaClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *MetaClassGV = - GetClassGlobal(MetaClassName.str(), Weak); + llvm::Constant *MetaClassGV = GetClassGlobal(MetaClassName.str(), + /*ForDefinition=*/false, + Weak); Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, llvm::GlobalValue::PrivateLinkage, @@ -6703,7 +6727,10 @@ if (ID->isWeakImported()) { llvm::SmallString<64> ClassName(getClassSymbolPrefix()); ClassName += ID->getObjCRuntimeNameAsString(); - llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true); + llvm::GlobalVariable *ClassGV = cast( + GetClassGlobal(ClassName.str(), + /*ForDefinition=*/true, + /*Weak=*/true)); (void)ClassGV; assert(ClassGV->hasExternalWeakLinkage()); } @@ -6998,11 +7025,15 @@ llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); + llvm::Constant *ClassGV = GetClassGlobal(ClassName.str(), + /*ForDefinition=*/false, + /*Weak=*/false); + llvm::Constant *Values[] = { llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV, VTableIdx), GetClassName(ID->getObjCRuntimeNameAsString()), - GetClassGlobal(ClassName.str())}; + ClassGV}; llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); Index: lib/CodeGen/CGObjCRuntime.h =================================================================== --- lib/CodeGen/CGObjCRuntime.h +++ lib/CodeGen/CGObjCRuntime.h @@ -268,8 +268,9 @@ const CodeGen::CGBlockInfo &blockInfo) = 0; virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T) = 0; - virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name, - bool Weak = false) = 0; + virtual llvm::Constant *GetClassGlobal(const std::string &Name, + bool ForDefinition, + bool Weak) = 0; struct MessageSendInfo { const CGFunctionInfo &CallInfo; Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2739,7 +2739,9 @@ std::string str = StringClass.empty() ? "OBJC_CLASS_$_NSConstantString" : "OBJC_CLASS_$_" + StringClass; - GV = getObjCRuntime().GetClassGlobal(str); + GV = getObjCRuntime().GetClassGlobal(str, + /*ForDefinition=*/false, + /*Weak=*/false); // Make sure the result is of the correct type. llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); V = llvm::ConstantExpr::getBitCast(GV, PTy);