diff options
author | David Chisnall <csdavec@swan.ac.uk> | 2012-01-04 12:02:13 +0000 |
---|---|---|
committer | David Chisnall <csdavec@swan.ac.uk> | 2012-01-04 12:02:13 +0000 |
commit | 13df6f6e2e6adfb9933ba1a16802d35942e26a5c (patch) | |
tree | 557d4935d4e343fc02b49fb6f7eeb29a02c56d31 /lib/CodeGen | |
parent | d1247c5002ee511e6f6c3c26214221c391d437cd (diff) |
Restore r147493 and remove the part of the test that was checking the wrong thing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147530 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 3a591e88dd..49323c58b1 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -970,12 +970,27 @@ llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { if (old != ObjCStrings.end()) return old->getValue(); + StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass; + + if (StringClass.empty()) StringClass = "NXConstantString"; + + std::string Sym = "_OBJC_CLASS_"; + Sym += StringClass; + + llvm::Constant *isa = TheModule.getNamedGlobal(Sym); + + if (!isa) + isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, + llvm::GlobalValue::ExternalWeakLinkage, 0, Sym); + else if (isa->getType() != PtrToIdTy) + isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); + std::vector<llvm::Constant*> Ivars; - Ivars.push_back(NULLPtr); + 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(PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL), + llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy, NULL), Ivars, ".objc_str"); ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty); ObjCStrings[Str] = ObjCStr; @@ -1368,7 +1383,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure( // anyway; the classes will still work with the GNU runtime, they will just // be ignored. llvm::StructType *ClassTy = llvm::StructType::get( - PtrToInt8Ty, // class_pointer + PtrToInt8Ty, // isa PtrToInt8Ty, // super_class PtrToInt8Ty, // name LongTy, // version @@ -1419,9 +1434,20 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure( Elements.push_back(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. - return MakeGlobal(ClassTy, Elements, (isMeta ? "_OBJC_METACLASS_": - "_OBJC_CLASS_") + std::string(Name), llvm::GlobalValue::ExternalLinkage); + // messages in the next ABI. We may already have some weak references to + // this, so check and fix them properly. + std::string ClassSym((isMeta ? "_OBJC_METACLASS_": "_OBJC_CLASS_") + + std::string(Name)); + llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym); + llvm::Constant *Class = MakeGlobal(ClassTy, Elements, ClassSym, + llvm::GlobalValue::ExternalLinkage); + if (ClassRef) { + ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class, + ClassRef->getType())); + ClassRef->removeFromParent(); + Class->setName(ClassSym); + } + return Class; } llvm::Constant *CGObjCGNU::GenerateProtocolMethodList( |