/// getFirstClassExtension - Find first class extension of the given class. ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const { for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl; CDecl = CDecl->getNextClassCategory()) if (CDecl->IsClassExtension()) return CDecl; return 0; }
/// FindPropertyDeclaration - Finds declaration of the property given its name /// in 'PropertyId' and returns it. It returns 0, if not found. ObjCPropertyDecl * ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId)) return PD; switch (getKind()) { default: break; case Decl::ObjCProtocol: { const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this); for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), E = PID->protocol_end(); I != E; ++I) if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) return P; break; } case Decl::ObjCInterface: { const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this); // Look through categories. for (ObjCCategoryDecl *Cat = OID->getCategoryList(); Cat; Cat = Cat->getNextClassCategory()) if (!Cat->IsClassExtension()) if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId)) return P; // Look through protocols. for (ObjCInterfaceDecl::all_protocol_iterator I = OID->all_referenced_protocol_begin(), E = OID->all_referenced_protocol_end(); I != E; ++I) if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) return P; // Finally, check the super class. if (const ObjCInterfaceDecl *superClass = OID->getSuperClass()) return superClass->FindPropertyDeclaration(PropertyId); break; } case Decl::ObjCCategory: { const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this); // Look through protocols. if (!OCD->IsClassExtension()) for (ObjCCategoryDecl::protocol_iterator I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I) if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) return P; break; } } return 0; }
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { switch (D->getKind()) { default: llvm_unreachable("Invalid ObjC container."); case Decl::ObjCInterface: case Decl::ObjCImplementation: GenObjCClass(D->getName()); break; case Decl::ObjCCategory: { ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); ObjCInterfaceDecl *ID = CD->getClassInterface(); if (!ID) { // Handle invalid code where the @interface might not // have been specified. // FIXME: We should be able to generate this USR even if the // @interface isn't available. IgnoreResults = true; return; } // Specially handle class extensions, which are anonymous categories. // We want to mangle in the location to uniquely distinguish them. if (CD->IsClassExtension()) { Out << "objc(ext)" << ID->getName() << '@'; GenLoc(CD); } else GenObjCCategory(ID->getName(), CD->getName()); break; } case Decl::ObjCCategoryImpl: { ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); ObjCInterfaceDecl *ID = CD->getClassInterface(); if (!ID) { // Handle invalid code where the @interface might not // have been specified. // FIXME: We should be able to generate this USR even if the // @interface isn't available. IgnoreResults = true; return; } GenObjCCategory(ID->getName(), CD->getName()); break; } case Decl::ObjCProtocol: GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName()); break; } }