summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp4
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp11
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.h1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp35
-rw-r--r--clang/test/CodeGenObjC/constant-string-class-1.m23
-rw-r--r--clang/test/CodeGenObjC/constant-string-class.m2
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
OpenPOWER on IntegriCloud