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),
}
llvm::Constant *
-CodeGenModule::GetAddrOfConstantNSString(const StringLiteral *Literal) {
+CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
unsigned StringLength = 0;
bool isUTF16 = false;
llvm::StringMapEntry<llvm::Constant*> &Entry =
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();
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());
/// 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();
/// 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.
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)) {
--- /dev/null
+// 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