aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-05-17 16:49:27 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-05-17 16:49:27 +0000
commit1e64a9531bf6e9d99ad3271b3a735ef702689b06 (patch)
tree6a23fa1e21360f6fb99cb862582bff564263a25d
parenta59077d3ac38d734b4188ac91ef40a7142093ac7 (diff)
This patch fixes two bugs in the GNU Objective-C runtime implementation. One is a case in rethrowing exceptions where the C types don't match correctly (I already sent this patch to Daniel Dunbar, who found the bug, so it may have already been committed). The other fixes the case properties so that the methods generated as property accessors are added to the class structure correctly.
Patch by David Chisnall. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71980 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp48
-rw-r--r--test/Coverage/codegen-gnu.m3
2 files changed, 35 insertions, 16 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 489b673587..1617e0b163 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -454,24 +454,25 @@ llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
std::vector<llvm::Constant*> Elements;
for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
Elements.clear();
- llvm::Constant *C =
- CGM.GetAddrOfConstantCString(MethodSels[i].getAsString());
- Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
- Elements.push_back(
- llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
- llvm::Constant *Method =
+ if (llvm::Constant *Method =
TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
MethodSels[i].getAsString(),
- isClassMethodList));
- Method = llvm::ConstantExpr::getBitCast(Method,
- llvm::PointerType::getUnqual(IMPTy));
- Elements.push_back(Method);
- Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
+ isClassMethodList))) {
+ llvm::Constant *C =
+ CGM.GetAddrOfConstantCString(MethodSels[i].getAsString());
+ Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
+ Elements.push_back(
+ llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
+ Method = llvm::ConstantExpr::getBitCast(Method,
+ llvm::PointerType::getUnqual(IMPTy));
+ Elements.push_back(Method);
+ Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
+ }
}
// Array of method structures
llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
- MethodSels.size());
+ Methods.size());
llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
Methods);
@@ -848,6 +849,24 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
}
+ for (ObjCImplDecl::propimpl_iterator
+ iter = OID->propimpl_begin(CGM.getContext()),
+ endIter = OID->propimpl_end(CGM.getContext());
+ iter != endIter ; iter++) {
+ ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
+ if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
+ InstanceMethodSels.push_back(getter->getSelector());
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(getter,TypeStr);
+ InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+ }
+ if (ObjCMethodDecl *setter = property->getSetterMethodDecl()) {
+ InstanceMethodSels.push_back(setter->getSelector());
+ std::string TypeStr;
+ Context.getObjCEncodingForMethodDecl(setter,TypeStr);
+ InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
+ }
+ }
// Collect information about class methods
llvm::SmallVector<Selector, 16> ClassMethodSels;
@@ -1363,13 +1382,14 @@ void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
if (const Expr *ThrowExpr = S.getThrowExpr()) {
llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
- ExceptionAsObject =
- CGF.Builder.CreateBitCast(Exception, IdTy, "tmp");
+ ExceptionAsObject = Exception;
} else {
assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
"Unexpected rethrow outside @catch block.");
ExceptionAsObject = CGF.ObjCEHValueStack.back();
}
+ ExceptionAsObject =
+ CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy, "tmp");
// Note: This may have to be an invoke, if we want to support constructs like:
// @try {
diff --git a/test/Coverage/codegen-gnu.m b/test/Coverage/codegen-gnu.m
index 417f5ef99e..f042c442b1 100644
--- a/test/Coverage/codegen-gnu.m
+++ b/test/Coverage/codegen-gnu.m
@@ -1,7 +1,6 @@
// RUN: clang-cc -triple i386-unknown-unknown -DIRGENABLE_GNU -DIRGENABLE -fgnu-runtime -emit-llvm -o %t %s &&
// RUN: clang-cc -triple i386-unknown-unknown -DIRGENABLE_GNU -DIRGENABLE -g -fgnu-runtime -emit-llvm -o %t %s &&
-// FIXME: Remove once GNU can IRgen everything.
-// RUN: not clang-cc -triple i386-unknown-unknown -fgnu-runtime -emit-llvm -o %t %s
+// RUN: clang-cc -triple i386-unknown-unknown -fgnu-runtime -emit-llvm -o %t %s
#include "objc-language-features.inc"