summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-03-31 23:42:16 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-03-31 23:42:16 +0000
commit8e5c2b8072f4409c7c0004331d1db9652d5209c0 (patch)
treea0f47dbd90b7d5e4bcd465fee087c508de35ee0c
parent3106198188ac6eb2753f1764d5c28376b0b76351 (diff)
downloadclang-8e5c2b8072f4409c7c0004331d1db9652d5209c0.tar.gz
Add Target hooks for IRgen of [cf]string literals.
- 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
-rw-r--r--include/clang/Basic/TargetInfo.h25
-rw-r--r--lib/Basic/Targets.cpp18
-rw-r--r--lib/CodeGen/CodeGenModule.cpp47
-rw-r--r--test/CodeGen/darwin-string-literals.c9
4 files changed, 81 insertions, 18 deletions
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index f3ec2fe638..d9a8bc1f50 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -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.
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index b3224fe1d2..ce55ec8046 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -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);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 6c0cc7ef2b..6419e27e63 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -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
index 0000000000..5bfb84e91d
--- /dev/null
+++ b/test/CodeGen/darwin-string-literals.c
@@ -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");