]> granicus.if.org Git - clang/commitdiff
Add Target hooks for IRgen of [cf]string literals.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 31 Mar 2009 23:42:16 +0000 (23:42 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 31 Mar 2009 23:42:16 +0000 (23:42 +0000)
 - Notably, set section on cfstring literal string data (for now, this
   is done everywhere because it matches what we were already doing
   for the CFString data itself)

 - <rdar://problem/6599098> [irgen] linker requires objc string data
   to go into cstring

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68160 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/TargetInfo.h
lib/Basic/Targets.cpp
lib/CodeGen/CodeGenModule.cpp
test/CodeGen/darwin-string-literals.c [new file with mode: 0644]

index f3ec2fe638e0ac4b77c2082b1b9edddc448f6cde..d9a8bc1f500d24eea883d4dce94db09d230babed 100644 (file)
@@ -245,6 +245,31 @@ public:
 
   virtual bool useGlobalsForAutomaticVariables() const { return false; }
 
+  /// getStringSymbolPrefix - Get the default symbol prefix to
+  /// use for string literals.
+  virtual const char *getStringSymbolPrefix(bool IsConstant) const { 
+    return ".str";
+  }
+
+  /// getCFStringSymbolPrefix - Get the default symbol prefix
+  /// to use for CFString literals.
+  virtual const char *getCFStringSymbolPrefix() const { 
+    return "";
+  }
+
+  /// getCFStringSection - Return the section to use for the CFString
+  /// literals, or 0 if no special section is used.
+  virtual const char *getCFStringSection() const { 
+    return "__DATA,__cfstring";
+  }
+
+  /// getCFStringDataSection - Return the section to use for the
+  /// constant string data associated with a CFString literal, or 0 if
+  /// no special section is used.
+  virtual const char *getCFStringDataSection() const { 
+    return "__TEXT,__cstring,cstring_literals";
+  }
+
   /// getDefaultLangOptions - Allow the target to specify default settings for
   /// various language options.  These may be overridden by command line
   /// options. 
index b3224fe1d2c84dfa5eb5b45d0576b1d46b00e444..ce55ec8046535a12c466abdd498f064efdb13c48 100644 (file)
@@ -653,11 +653,21 @@ public:
                         "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
                         "a0:0:64-f80:128:128";
   }
+
+  virtual const char *getStringSymbolPrefix(bool IsConstant) const { 
+    return IsConstant ? "\01LC" : "\01lC";
+  }
+
+  virtual const char *getCFStringSymbolPrefix() const { 
+    return "\01LC";
+  }
+
   virtual void getTargetDefines(const LangOptions &Opts,
                                 std::vector<char> &Defines) const {
     X86_32TargetInfo::getTargetDefines(Opts, Defines);
     getDarwinDefines(Defines, getTargetTriple());
   }
+
   /// getDefaultLangOptions - Allow the target to specify default settings for
   /// various language options.  These may be overridden by command line
   /// options. 
@@ -796,6 +806,14 @@ public:
   DarwinX86_64TargetInfo(const std::string& triple) :
     X86_64TargetInfo(triple) {}
 
+  virtual const char *getStringSymbolPrefix(bool IsConstant) const { 
+    return IsConstant ? "\01LC" : "\01lC";
+  }
+
+  virtual const char *getCFStringSymbolPrefix() const { 
+    return "\01L_unnamed_cfstring_";
+  }
+
   virtual void getTargetDefines(const LangOptions &Opts,
                                 std::vector<char> &Defines) const {
     X86_64TargetInfo::getTargetDefines(Opts, Defines);
index 6c0cc7ef2bbdf6379f4f570f07e9ca07c0849fa2..6419e27e63e9e2552d32af398445717821b780f4 100644 (file)
@@ -396,14 +396,16 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
 
   // Get the two global values corresponding to the ConstantArrays we just
   // created to hold the bytes of the strings.
+  const char *StringPrefix = getContext().Target.getStringSymbolPrefix(true);
   llvm::GlobalValue *annoGV = 
   new llvm::GlobalVariable(anno->getType(), false,
                            llvm::GlobalValue::InternalLinkage, anno,
-                           GV->getName() + ".str", M);
+                           GV->getName() + StringPrefix, M);
   // translation unit name string, emitted into the llvm.metadata section.
   llvm::GlobalValue *unitGV =
   new llvm::GlobalVariable(unit->getType(), false,
-                           llvm::GlobalValue::InternalLinkage, unit, ".str", M);
+                           llvm::GlobalValue::InternalLinkage, unit, 
+                           StringPrefix, M);
 
   // Create the ConstantStruct that is the global annotion.
   llvm::Constant *Fields[4] = {
@@ -1010,8 +1012,8 @@ GetAddrOfConstantCFString(const std::string &str) {
   llvm::StringMapEntry<llvm::Constant *> &Entry = 
     CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
   
-  if (Entry.getValue())
-    return Entry.getValue();
+  if (llvm::Constant *C = Entry.getValue())
+    return C;
   
   llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
   llvm::Constant *Zeros[] = { Zero, Zero };
@@ -1062,11 +1064,15 @@ GetAddrOfConstantCFString(const std::string &str) {
   CurField = NextField;
   NextField = *Field++;
   llvm::Constant *C = llvm::ConstantArray::get(str);
-  C = new llvm::GlobalVariable(C->getType(), true, 
-                               llvm::GlobalValue::InternalLinkage,
-                               C, ".str", &getModule());
+  llvm::GlobalVariable *GV = 
+    new llvm::GlobalVariable(C->getType(), true, 
+                             llvm::GlobalValue::InternalLinkage,
+                             C, getContext().Target.getStringSymbolPrefix(true),
+                             &getModule());
+  if (const char *Sect = getContext().Target.getCFStringDataSection())
+    GV->setSection(Sect);
   appendFieldAndPadding(*this, Fields, CurField, NextField,
-                        llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2),
+                        llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2),
                         CFRD, STy);
   
   // String length.
@@ -1078,12 +1084,12 @@ GetAddrOfConstantCFString(const std::string &str) {
   
   // The struct.
   C = llvm::ConstantStruct::get(STy, Fields);
-  llvm::GlobalVariable *GV = 
-    new llvm::GlobalVariable(C->getType(), true
-                             llvm::GlobalVariable::InternalLinkage
-                             C, "", &getModule());
-  
-  GV->setSection("__DATA,__cfstring");
+  GV = new llvm::GlobalVariable(C->getType(), true, 
+                                llvm::GlobalVariable::InternalLinkage, C
+                                getContext().Target.getCFStringSymbolPrefix()
+                                &getModule());
+  if (const char *Sect = getContext().Target.getCFStringSection())
+    GV->setSection(Sect);
   Entry.setValue(GV);
   
   return GV;
@@ -1141,8 +1147,7 @@ static llvm::Constant *GenerateStringLiteral(const std::string &str,
   // Create a global variable for this string
   return new llvm::GlobalVariable(C->getType(), constant, 
                                   llvm::GlobalValue::InternalLinkage,
-                                  C, GlobalName ? GlobalName : ".str", 
-                                  &CGM.getModule());
+                                  C, GlobalName, &CGM.getModule());
 }
 
 /// GetAddrOfConstantString - Returns a pointer to a character array
@@ -1155,8 +1160,14 @@ static llvm::Constant *GenerateStringLiteral(const std::string &str,
 /// The result has pointer to array type.
 llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str,
                                                        const char *GlobalName) {
-  // Don't share any string literals if writable-strings is turned on.
-  if (Features.WritableStrings)
+  bool IsConstant = !Features.WritableStrings;
+
+  // Get the default prefix if a name wasn't specified.
+  if (!GlobalName)
+    GlobalName = getContext().Target.getStringSymbolPrefix(IsConstant);
+
+  // Don't share any string literals if strings aren't constant.
+  if (!IsConstant)
     return GenerateStringLiteral(str, false, *this, GlobalName);
   
   llvm::StringMapEntry<llvm::Constant *> &Entry = 
diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c
new file mode 100644 (file)
index 0000000..5bfb84e
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm %s -o %t &&
+
+// RUN: grep -F '@"\01LC" = internal constant [8 x i8] c"string0\00"' %t &&
+// RUN: grep -F '@"\01LC1" = internal constant [8 x i8] c"string1\00", section "__TEXT,__cstring,cstring_literals"' %t &&
+
+// RUN: true
+
+const char *g0 = "string0";
+const void *g1 = __builtin___CFStringMakeConstantString("string1");