зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
102ff97bc5
Коммит
4c73307c74
|
@ -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
|
Загрузка…
Ссылка в новой задаче