зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
a59077d3ac
Коммит
1e64a9531b
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
Загрузка…
Ссылка в новой задаче