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
This commit is contained in:
Fariborz Jahanian 2010-10-19 17:19:29 +00:00
Родитель 102ff97bc5
Коммит 4c73307c74
5 изменённых файлов: 70 добавлений и 17 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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());

Просмотреть файл

@ -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.

Просмотреть файл

@ -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)) {

Просмотреть файл

@ -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