"This fixes message sends to super in a way that both works with real code and passes the test in the test suite. It also fixes a crash when using recent versions of GNU libobjc and compiling modules that do not contain any constant strings but do contain a declaration of the constant string class and possible some other corner cases (thanks to Pete French for providing me with a test case for that one)."

Patch by David Chisnall!

llvm-svn: 70093
This commit is contained in:
Chris Lattner 2009-04-25 23:19:45 +00:00
parent 003af24927
commit c06ce0f710
1 changed files with 28 additions and 20 deletions

View File

@ -298,8 +298,13 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *SuperClass = Class->getSuperClass();
// TODO: This should be cached, not looked up every time.
llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass);
if (IsClassMessage)
{
ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
llvm::PointerType::getUnqual(IdTy));
ReceiverClass = CGF.Builder.CreateBitCast(CGF.Builder.CreateLoad(
ReceiverClass), IdTy);
}
// Construct the structure used to look up the IMP
llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(),
IdTy, NULL);
@ -850,25 +855,28 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
TheModule.addTypeName(".objc_imp", IMPTy);
std::vector<llvm::Constant*> Elements;
llvm::Constant *Statics = NULLPtr;
// Generate statics list:
llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
ConstantStrings.size() + 1);
ConstantStrings.push_back(NULLPtr);
Elements.push_back(MakeConstantString("NSConstantString",
".objc_static_class_name"));
Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy, ConstantStrings));
llvm::StructType *StaticsListTy =
llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL);
llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy);
llvm::Constant *Statics =
MakeGlobal(StaticsListTy, Elements, ".objc_statics");
llvm::ArrayType *StaticsListArrayTy =
llvm::ArrayType::get(StaticsListPtrTy, 2);
Elements.clear();
Elements.push_back(Statics);
Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
if (ConstantStrings.size()) {
llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
ConstantStrings.size() + 1);
ConstantStrings.push_back(NULLPtr);
Elements.push_back(MakeConstantString("NSConstantString",
".objc_static_class_name"));
Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
ConstantStrings));
llvm::StructType *StaticsListTy =
llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL);
llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy);
Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
llvm::ArrayType *StaticsListArrayTy =
llvm::ArrayType::get(StaticsListPtrTy, 2);
Elements.clear();
Elements.push_back(Statics);
Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
}
// Array of classes, categories, and constant objects
llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
Classes.size() + Categories.size() + 2);