diff options
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.h | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 35 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/constant-string-class-1.m | 23 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/constant-string-class.m | 2 |
6 files changed, 59 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index c4dc4c41da6..7cf4f0bbc9e 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -484,6 +484,10 @@ public: const CGBlockInfo &blockInfo) { return NULLPtr; } + + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { + return 0; + } }; /// Class representing the legacy GCC Objective-C ABI. This is the default when /// -fobjc-nonfragile-abi is not specified. diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 50f2c78b524..99d464f8846 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1048,6 +1048,13 @@ public: virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); + + /// GetClassGlobal - Return the global variable for the Objective-C + /// class of the given name. + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) { + assert(false && "CGObjCMac::GetClassGlobal"); + return 0; + } }; class CGObjCNonFragileABIMac : public CGObjCCommonMac { @@ -1142,11 +1149,11 @@ private: bool IsSuper, const CallArgList &CallArgs, const ObjCMethodDecl *Method); - + /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. llvm::GlobalVariable *GetClassGlobal(const std::string &Name); - + /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, /// for the given class reference. llvm::Value *EmitClassRef(CGBuilderTy &Builder, diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 0cc2d824d40..fdb58d91e99 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -243,6 +243,7 @@ public: llvm::Value *Size) = 0; virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo) = 0; + virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0; }; /// Creates an instance of an Objective-C runtime class. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 84fa4af669e..7f2e3f593ef 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1768,24 +1768,31 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { if (!ConstantStringClassRef) { std::string StringClass(getLangOptions().ObjCConstantStringClass); const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); - Ty = llvm::ArrayType::get(Ty, 0); llvm::Constant *GV; - if (StringClass.empty()) - GV = CreateRuntimeVariable(Ty, - Features.ObjCNonFragileABI ? - "OBJC_CLASS_$_NSConstantString" : - "_NSConstantStringClassReference"); - else { + if (Features.ObjCNonFragileABI) { std::string str; - if (Features.ObjCNonFragileABI) + if (StringClass.empty()) + str = "OBJC_CLASS_$_NSConstantString"; + else { str = "OBJC_CLASS_$_" + StringClass; - else - str = "_" + StringClass + "ClassReference"; - GV = CreateRuntimeVariable(Ty, str); + } + GV = getObjCRuntime().GetClassGlobal(str); + // Make sure the result is of the correct type. + const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); + ConstantStringClassRef = + llvm::ConstantExpr::getBitCast(GV, PTy); + } else { + Ty = llvm::ArrayType::get(Ty, 0); + if (StringClass.empty()) + GV = CreateRuntimeVariable(Ty, "_NSConstantStringClassReference"); + else { + std::string str = "_" + StringClass + "ClassReference"; + GV = CreateRuntimeVariable(Ty, str); + } + // Decay array -> ptr + ConstantStringClassRef = + llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); } - // Decay array -> ptr - ConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); } QualType NSTy = getContext().getNSConstantStringType(); diff --git a/clang/test/CodeGenObjC/constant-string-class-1.m b/clang/test/CodeGenObjC/constant-string-class-1.m new file mode 100644 index 00000000000..8ff605ec693 --- /dev/null +++ b/clang/test/CodeGenObjC/constant-string-class-1.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fno-constant-cfstrings -fconstant-string-class OFConstantString -emit-llvm -o %t %s +// pr9914 + +@interface OFConstantString ++ class; +@end + +@interface OFString +- (void)XMLElementBySerializing; +@end + +@implementation OFString + +- (void)XMLElementBySerializing +{ + id str = @"object"; + + [OFConstantString class]; +} + +@end + +// CHECK: @"OBJC_CLASS_$_OFConstantString" = external global diff --git a/clang/test/CodeGenObjC/constant-string-class.m b/clang/test/CodeGenObjC/constant-string-class.m index 12253d6c70f..489f511e781 100644 --- a/clang/test/CodeGenObjC/constant-string-class.m +++ b/clang/test/CodeGenObjC/constant-string-class.m @@ -32,4 +32,4 @@ int main () { // CHECK-FRAGILE: @_FooClassReference = common global // CHECK-NONFRAGILE: @"OBJC_CLASS_$_Object" = external global -// CHECK-NONFRAGILE: "OBJC_CLASS_$_Foo" = unnamed_addr global +// CHECK-NONFRAGILE: "OBJC_CLASS_$_Foo" = global |