[cfe-commits] r68125 - /cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Mar 31 11:27:22 PDT 2009
Author: fjahanian
Date: Tue Mar 31 13:27:22 2009
New Revision: 68125
URL: http://llvm.org/viewvc/llvm-project?rev=68125&view=rev
Log:
Patch to fix proptocol reference ir-gen for GNU runtime.
Patch by David Chisnal.
Modified:
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=68125&r1=68124&r2=68125&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Tue Mar 31 13:27:22 2009
@@ -71,6 +71,7 @@
const llvm::SmallVectorImpl<Selector> &MethodSels,
const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
bool isClassMethodList);
+ llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
llvm::Constant *GenerateProtocolList(
const llvm::SmallVectorImpl<std::string> &Protocols);
llvm::Constant *GenerateClassStructure(
@@ -554,8 +555,11 @@
std::vector<llvm::Constant*> Elements;
for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
iter != endIter ; iter++) {
+ llvm::Constant *protocol = ExistingProtocols[*iter];
+ if (!protocol)
+ protocol = GenerateEmptyProtocol(*iter);
llvm::Constant *Ptr =
- llvm::ConstantExpr::getBitCast(ExistingProtocols[*iter], PtrToInt8Ty);
+ llvm::ConstantExpr::getBitCast(protocol, PtrToInt8Ty);
Elements.push_back(Ptr);
}
llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
@@ -569,7 +573,40 @@
llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *PD) {
- return ExistingProtocols[PD->getNameAsString()];
+ llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
+ const llvm::Type *T =
+ CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
+ return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
+}
+
+llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
+ const std::string &ProtocolName) {
+ llvm::SmallVector<std::string, 0> EmptyStringVector;
+ llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
+
+ llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
+ llvm::Constant *InstanceMethodList =
+ GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
+ llvm::Constant *ClassMethodList =
+ GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
+ // Protocols are objects containing lists of the methods implemented and
+ // protocols adopted.
+ llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
+ PtrToInt8Ty,
+ ProtocolList->getType(),
+ InstanceMethodList->getType(),
+ ClassMethodList->getType(),
+ NULL);
+ std::vector<llvm::Constant*> Elements;
+ // The isa pointer must be set to a magic number so the runtime knows it's
+ // the correct layout.
+ Elements.push_back(llvm::ConstantExpr::getIntToPtr(
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy));
+ Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
+ Elements.push_back(ProtocolList);
+ Elements.push_back(InstanceMethodList);
+ Elements.push_back(ClassMethodList);
+ return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
}
void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
More information about the cfe-commits
mailing list