From: Fariborz Jahanian Date: Tue, 19 Oct 2010 17:19:29 +0000 (+0000) Subject: This patch implements Next's IRGen for -fconstant-string-class=class-name. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4c73307c74764ba99e1379677fe92af72f676531;p=clang This patch implements Next's IRGen for -fconstant-string-class=class-name. PR6056, //rdar: //8564463 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116819 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 &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 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(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