[cfe-commits] r147493 - /cfe/trunk/lib/CodeGen/CGObjCGNU.cpp

David Chisnall csdavec at swan.ac.uk
Tue Jan 3 15:18:17 PST 2012


Author: theraven
Date: Tue Jan  3 17:18:17 2012
New Revision: 147493

URL: http://llvm.org/viewvc/llvm-project?rev=147493&view=rev
Log:
Initialise constant Objective-C string isa pointers with a weak reference to the class, so that they are usable in +load methods if the string class has been compiled with clang - if it's been compiled with GCC, the ABI makes this impossible.  (GNU runtimes)


Modified:
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=147493&r1=147492&r2=147493&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Tue Jan  3 17:18:17 2012
@@ -970,12 +970,27 @@
   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 @@
   // 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 @@
   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(





More information about the cfe-commits mailing list