From 13df6f6e2e6adfb9933ba1a16802d35942e26a5c Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 4 Jan 2012 12:02:13 +0000 Subject: [PATCH] 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 --- lib/CodeGen/CGObjCGNU.cpp | 38 ++++++++++++++++++++++++----- test/CodeGenObjC/constant-strings.m | 2 -- 2 files changed, 32 insertions(+), 8 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 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( diff --git a/test/CodeGenObjC/constant-strings.m b/test/CodeGenObjC/constant-strings.m index 398981362e..c308d7a475 100644 --- a/test/CodeGenObjC/constant-strings.m +++ b/test/CodeGenObjC/constant-strings.m @@ -8,11 +8,9 @@ // RUN: %clang_cc1 -fgnu-runtime -emit-llvm -o %t %s // RUN: FileCheck --check-prefix=CHECK-GNU < %t %s // CHECK-GNU: NXConstantString -// CHECK-GNU-NOT: NXConstantString // RUN: %clang_cc1 -fgnu-runtime -fconstant-string-class NSConstantString -emit-llvm -o %t %s // RUN: FileCheck --check-prefix=CHECK-GNU-WITH-CLASS < %t %s // CHECK-GNU-WITH-CLASS: NSConstantString -// CHECK-GNU-WITH-CLASS-NOT: NSConstantString id a = @"Hello World!"; -- 2.50.1