diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-03-31 23:42:16 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-03-31 23:42:16 +0000 |
commit | 8e5c2b8072f4409c7c0004331d1db9652d5209c0 (patch) | |
tree | a0f47dbd90b7d5e4bcd465fee087c508de35ee0c | |
parent | 3106198188ac6eb2753f1764d5c28376b0b76351 (diff) | |
download | clang-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.h | 25 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 47 | ||||
-rw-r--r-- | test/CodeGen/darwin-string-literals.c | 9 |
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"); |