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 llvm-svn: 68160
This commit is contained in:
parent
a9d1032f9c
commit
08b216abf1
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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");
|
Loading…
Reference in New Issue