Unique ObjC strings (GNU Runtime); fix for PR6142.  Note: Doing this in the runtime-specific code is a bit ugly.  It would be a good idea to hoist all of the string / protocol uniqueing code up into CGObjCRuntime or CodeGenModule and only handle emitting the original versions in the runtime-specific code.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94676 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 77be9fb..3a0ac99 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -65,6 +65,7 @@
   std::vector<llvm::Constant*> Classes;
   std::vector<llvm::Constant*> Categories;
   std::vector<llvm::Constant*> ConstantStrings;
+  llvm::StringMap<llvm::Constant*> ObjCStrings;
   llvm::Function *LoadFunction;
   llvm::StringMap<llvm::Constant*> ExistingProtocols;
   typedef std::pair<std::string, std::string> TypedSelector;
@@ -357,8 +358,14 @@
 
 /// Generate an NSConstantString object.
 llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) {
+
   std::string Str(SL->getStrData(), SL->getByteLength());
 
+  // Look for an existing one
+  llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
+  if (old != ObjCStrings.end())
+    return old->getValue();
+
   std::vector<llvm::Constant*> Ivars;
   Ivars.push_back(NULLPtr);
   Ivars.push_back(MakeConstantString(Str));
@@ -366,8 +373,9 @@
   llvm::Constant *ObjCStr = MakeGlobal(
     llvm::StructType::get(VMContext, PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
     Ivars, ".objc_str");
-  ConstantStrings.push_back(
-      llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty));
+  ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
+  ObjCStrings[Str] = ObjCStr;
+  ConstantStrings.push_back(ObjCStr);
   return ObjCStr;
 }