summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGObjCGNU.cpp
diff options
context:
space:
mode:
authorDavid Chisnall <csdavec@swan.ac.uk>2018-12-28 17:44:54 +0000
committerDavid Chisnall <csdavec@swan.ac.uk>2018-12-28 17:44:54 +0000
commit386477a54137833a4ecd713b950346e3fb605315 (patch)
tree05d16f3df866ab433f8ebca61d26c9196e006cf9 /clang/lib/CodeGen/CGObjCGNU.cpp
parent28eccf5ba0d10f319f8c0c506c9c544c67d2a09a (diff)
downloadbcm5719-llvm-386477a54137833a4ecd713b950346e3fb605315.tar.gz
bcm5719-llvm-386477a54137833a4ecd713b950346e3fb605315.zip
[objc-gnustep2] Fix a bug in category generation.
We were not emitting a protocol definition while generating the category method list. This was fine in most cases, because something else in the library typically referenced any given protocol, but it caused linker failures if the category was the only reference to a given protocol. llvm-svn: 350130
Diffstat (limited to 'clang/lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 534650b1108..548bd6b3fd7 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -277,6 +277,8 @@ protected:
Fields.addInt(Int8Ty, 0);
}
+ virtual llvm::Constant *GenerateCategoryProtocolList(const
+ ObjCCategoryDecl *OCD);
virtual ConstantArrayBuilder PushPropertyListHeader(ConstantStructBuilder &Fields,
int count) {
// int count;
@@ -1164,6 +1166,15 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
return MethodList.finishAndCreateGlobal(".objc_protocol_method_list",
CGM.getPointerAlign());
}
+ llvm::Constant *GenerateCategoryProtocolList(const ObjCCategoryDecl *OCD)
+ override {
+ SmallVector<llvm::Constant*, 16> Protocols;
+ for (const auto *PI : OCD->getReferencedProtocols())
+ Protocols.push_back(
+ llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
+ ProtocolPtrTy));
+ return GenerateProtocolList(Protocols);
+ }
llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
llvm::Value *cmd, MessageSendInfo &MSI) override {
@@ -3099,18 +3110,21 @@ llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) {
return ptr;
}
+llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(const
+ ObjCCategoryDecl *OCD) {
+ SmallVector<std::string, 16> Protocols;
+ for (const auto *PD : OCD->getReferencedProtocols())
+ Protocols.push_back(PD->getNameAsString());
+ return GenerateProtocolList(Protocols);
+}
+
void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
const ObjCInterfaceDecl *Class = OCD->getClassInterface();
std::string ClassName = Class->getNameAsString();
std::string CategoryName = OCD->getNameAsString();
// Collect the names of referenced protocols
- SmallVector<std::string, 16> Protocols;
const ObjCCategoryDecl *CatDecl = OCD->getCategoryDecl();
- const ObjCList<ObjCProtocolDecl> &Protos = CatDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
- E = Protos.end(); I != E; ++I)
- Protocols.push_back((*I)->getNameAsString());
ConstantInitBuilder Builder(CGM);
auto Elements = Builder.beginStruct();
@@ -3132,7 +3146,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
GenerateMethodList(ClassName, CategoryName, ClassMethods, true),
PtrTy);
// Protocol list
- Elements.addBitCast(GenerateProtocolList(Protocols), PtrTy);
+ Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
if (isRuntime(ObjCRuntime::GNUstep, 2)) {
const ObjCCategoryDecl *Category =
Class->FindCategoryDeclaration(OCD->getIdentifier());
OpenPOWER on IntegriCloud