aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGObjCMac.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp31
-rw-r--r--lib/CodeGen/CodeGenModule.h11
-rw-r--r--lib/Sema/SemaExprObjC.cpp9
-rw-r--r--test/CodeGenObjC/constant-string-class.m34
5 files changed, 70 insertions, 17 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 72953ce924..9ed3733a66 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1520,7 +1520,7 @@ llvm::Constant *CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
CGM.GetAddrOfConstantCFString(SL) :
- CGM.GetAddrOfConstantNSString(SL));
+ CGM.GetAddrOfConstantString(SL));
}
/// Generates a message send where the super is the receiver. This is
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 175c27b4c6..9199f6cfbd 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -65,7 +65,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI),
TBAA(0),
VTables(*this), Runtime(0),
- CFConstantStringClassRef(0), NSConstantStringClassRef(0),
+ CFConstantStringClassRef(0), ConstantStringClassRef(0),
VMContext(M.getContext()),
NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0),
NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
@@ -1635,7 +1635,7 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
}
llvm::Constant *
-CodeGenModule::GetAddrOfConstantNSString(const StringLiteral *Literal) {
+CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
unsigned StringLength = 0;
bool isUTF16 = false;
llvm::StringMapEntry<llvm::Constant*> &Entry =
@@ -1651,16 +1651,27 @@ CodeGenModule::GetAddrOfConstantNSString(const StringLiteral *Literal) {
llvm::Constant *Zeros[] = { Zero, Zero };
// If we don't already have it, get _NSConstantStringClassReference.
- if (!NSConstantStringClassRef) {
+ if (!ConstantStringClassRef) {
+ std::string StringClass(getLangOptions().ObjCConstantStringClass);
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
Ty = llvm::ArrayType::get(Ty, 0);
- llvm::Constant *GV = CreateRuntimeVariable(Ty,
- Features.ObjCNonFragileABI ?
- "OBJC_CLASS_$_NSConstantString" :
- "_NSConstantStringClassReference");
+ llvm::Constant *GV;
+ if (StringClass.empty())
+ GV = CreateRuntimeVariable(Ty,
+ Features.ObjCNonFragileABI ?
+ "OBJC_CLASS_$_NSConstantString" :
+ "_NSConstantStringClassReference");
+ else {
+ std::string str;
+ if (Features.ObjCNonFragileABI)
+ str = "OBJC_CLASS_$_" + StringClass;
+ else
+ str = "_" + StringClass + "ClassReference";
+ GV = CreateRuntimeVariable(Ty, str);
+ }
// Decay array -> ptr
- NSConstantStringClassRef =
- llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+ ConstantStringClassRef =
+ llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
}
QualType NSTy = getContext().getNSConstantStringType();
@@ -1671,7 +1682,7 @@ CodeGenModule::GetAddrOfConstantNSString(const StringLiteral *Literal) {
std::vector<llvm::Constant*> Fields(3);
// Class pointer.
- Fields[0] = NSConstantStringClassRef;
+ Fields[0] = ConstantStringClassRef;
// String pointer.
llvm::Constant *C = llvm::ConstantArray::get(VMContext, Entry.getKey().str());
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 236b5b73e6..d050eea3f5 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -185,9 +185,9 @@ class CodeGenModule : public BlockModule {
/// strings. This value has type int * but is actually an Obj-C class pointer.
llvm::Constant *CFConstantStringClassRef;
- /// NSConstantStringClassRef - Cached reference to the class for constant
+ /// ConstantStringClassRef - Cached reference to the class for constant
/// strings. This value has type int * but is actually an Obj-C class pointer.
- llvm::Constant *NSConstantStringClassRef;
+ llvm::Constant *ConstantStringClassRef;
/// Lazily create the Objective-C runtime
void createObjCRuntime();
@@ -321,9 +321,10 @@ public:
/// for the given string.
llvm::Constant *GetAddrOfConstantCFString(const StringLiteral *Literal);
- /// GetAddrOfConstantNSString - Return a pointer to a constant NSString object
- /// for the given string.
- llvm::Constant *GetAddrOfConstantNSString(const StringLiteral *Literal);
+ /// GetAddrOfConstantString - Return a pointer to a constant NSString object
+ /// for the given string. Or a user defined String object as defined via
+ /// -fconstant-string-class=class_name option.
+ llvm::Constant *GetAddrOfConstantString(const StringLiteral *Literal);
/// GetAddrOfConstantStringFromLiteral - Return a pointer to a constant array
/// for the given string literal.
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 1a90a2aaff..cd4c364898 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -77,7 +77,14 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
if (!Ty.isNull()) {
Ty = Context.getObjCObjectPointerType(Ty);
} else if (getLangOptions().NoConstantCFStrings) {
- IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
+ IdentifierInfo *NSIdent=0;
+ std::string StringClass(getLangOptions().ObjCConstantStringClass);
+
+ if (StringClass.empty())
+ NSIdent = &Context.Idents.get("NSConstantString");
+ else
+ NSIdent = &Context.Idents.get(StringClass);
+
NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
LookupOrdinaryName);
if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
diff --git a/test/CodeGenObjC/constant-string-class.m b/test/CodeGenObjC/constant-string-class.m
new file mode 100644
index 0000000000..3d182384a2
--- /dev/null
+++ b/test/CodeGenObjC/constant-string-class.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fno-constant-cfstrings -fconstant-string-class Foo -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-FRAGILE < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fno-constant-cfstrings -fconstant-string-class Foo -emit-llvm -o %t %s
+// RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
+
+// rdar: // 8564463
+// PR6056
+
+@interface Object {
+ id isa;
+}
+@end
+
+@interface Foo : Object{
+ char *cString;
+ unsigned int len;
+}
+- (char *)customString;
+@end
+
+id _FooClassReference[20];
+
+@implementation Foo
+- (char *)customString { return cString ; }
+@end
+
+int main () {
+ Foo *string = @"bla";
+ return 0;
+}
+
+// CHECK-FRAGILE: @_FooClassReference = common global
+// CHECK-NONFRAGILE: @"OBJC_CLASS_$_Object" = external global