void setImplementation(ObjCImplementationDecl *ImplD);
ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
+
+ // Get the local instance/class method declared in a category.
+ ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
+ ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
+ ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
+ return isInstance ? getInstanceMethod(Sel)
+ : getClassMethod(Sel);
+ }
typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
/// \brief Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 18,
- /// \brief Record code for the set of Objective-C category
- /// implementations.
- OBJC_CATEGORY_IMPLEMENTATIONS = 19,
-
/// \brief Record code for the original file that was used to
/// generate the precompiled header.
- ORIGINAL_FILE_NAME = 20,
+ ORIGINAL_FILE_NAME = 19,
/// \brief Record code for the sorted array of source ranges where
/// comments were encountered in the source code.
- COMMENT_RANGES = 21
+ COMMENT_RANGES = 20
};
/// \brief Record types used within a source manager block.
return 0;
}
+ObjCMethodDecl *
+ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
+ for (ObjCCategoryDecl *Category = getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+ if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
+ return MD;
+ return 0;
+}
+
+ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
+ for (ObjCCategoryDecl *Category = getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
+ if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
+ return MD;
+ return 0;
+}
+
//===----------------------------------------------------------------------===//
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
ExtVectorDecls.swap(Record);
break;
- case pch::OBJC_CATEGORY_IMPLEMENTATIONS:
- if (!ObjCCategoryImpls.empty()) {
- Error("duplicate OBJC_CATEGORY_IMPLEMENTATIONS record in PCH file");
- return Failure;
- }
- ObjCCategoryImpls.swap(Record);
- break;
-
case pch::ORIGINAL_FILE_NAME:
OriginalFileName.assign(BlobStart, BlobLen);
MaybeAddSystemRootToFilename(OriginalFileName);
for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
SemaObj->ExtVectorDecls.push_back(
cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
-
- // If there were any Objective-C category implementations,
- // deserialize them and add them to Sema's vector of such
- // definitions.
- for (unsigned I = 0, N = ObjCCategoryImpls.size(); I != N; ++I)
- SemaObj->ObjCCategoryImpls.push_back(
- cast<ObjCCategoryImplDecl>(GetDecl(ObjCCategoryImpls[I])));
}
IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
RECORD(SOURCE_LOCATION_PRELOADS);
RECORD(STAT_CACHE);
RECORD(EXT_VECTOR_DECLS);
- RECORD(OBJC_CATEGORY_IMPLEMENTATIONS);
RECORD(COMMENT_RANGES);
// SourceManager Block.
for (unsigned I = 0, N = SemaRef.ExtVectorDecls.size(); I != N; ++I)
AddDeclRef(SemaRef.ExtVectorDecls[I], ExtVectorDecls);
- // Build a record containing all of the Objective-C category
- // implementations.
- RecordData ObjCCategoryImpls;
- for (unsigned I = 0, N = SemaRef.ObjCCategoryImpls.size(); I != N; ++I)
- AddDeclRef(SemaRef.ObjCCategoryImpls[I], ObjCCategoryImpls);
-
// Write the remaining PCH contents.
RecordData Record;
Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
// Write the record containing ext_vector type names.
if (!ExtVectorDecls.empty())
Stream.EmitRecord(pch::EXT_VECTOR_DECLS, ExtVectorDecls);
-
- // Write the record containing Objective-C category implementations.
- if (!ObjCCategoryImpls.empty())
- Stream.EmitRecord(pch::OBJC_CATEGORY_IMPLEMENTATIONS, ObjCCategoryImpls);
// Some simple statistics
Record.clear();
/// us to associate a raw vector type with one of the ext_vector type names.
/// This is only necessary for issuing pretty diagnostics.
llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
-
- /// ObjCCategoryImpls - Maintain a list of category implementations so
- /// we can check for duplicates and find local method declarations.
- llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
llvm::OwningPtr<CXXFieldCollector> FieldCollector;
} else
CatIDecl->setImplementation(CDecl);
}
-
- ObjCCategoryImpls.push_back(CDecl);
CheckObjCDeclScope(CDecl);
return DeclPtrTy::make(CDecl);
Setter = FindMethodInNestedImplementations(IFace, SetterSel);
}
// Look through local category implementations associated with the class.
- if (!Setter) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
- }
- }
+ if (!Setter)
+ Setter = IFace->getCategoryClassMethod(SetterSel);
if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
Getter = FindMethodInNestedImplementations(IFace, Sel);
// Look through local category implementations associated with the class.
- if (!Getter) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
- }
- }
+ if (!Getter)
+ Getter = IFace->getCategoryInstanceMethod(Sel);
if (Getter) {
// Check if we can reference this property.
if (DiagnoseUseOfDecl(Getter, MemberLoc))
Setter = FindMethodInNestedImplementations(IFace, SetterSel);
}
// Look through local category implementations associated with the class.
- if (!Setter) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
- }
- }
+ if (!Setter)
+ Setter = IFace->getCategoryInstanceMethod(SetterSel);
if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
Method = ImpDecl->getClassMethod(Sel);
// Look through local category implementations associated with the class.
- if (!Method) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
- }
- }
+ if (!Method)
+ Method = ClassDecl->getCategoryClassMethod(Sel);
// Before we give up, check if the selector is an instance method.
// But only in the root. This matches gcc's behaviour and what the
Method = ImpDecl->getInstanceMethod(Sel);
// Look through local category implementations associated with the class.
- if (!Method) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
- }
- }
+ if (!Method)
+ Method = ClassDecl->getCategoryInstanceMethod(Sel);
ClassDecl = ClassDecl->getSuperClass();
}
return Method;
Setter = ImpDecl->getClassMethod(SetterSel);
}
// Look through local category implementations associated with the class.
- if (!Setter) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
- }
- }
+ if (!Setter)
+ Setter = IFace->getCategoryClassMethod(SetterSel);
if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
return ExprError();