This patch corrects several errors that result in incorrect Objective-C method declaration enumeration that occurs when an AST is deserialized from an .ast file.
There were two issues:
- In lib/AST/DeclObjC.cpp, in ObjCImplDecl::setClassInterface(), the base class version (ObjCImplDecl) of (non-virtual) getIdentifier() was being called, but the derived class version (ObjCCategoryImplDecl) is what is required. See this comment in include/clang/AST/DeclObjC.h: class ObjCCategoryImplDecl : public ObjCImplDecl { ... / getIdentifier - Get the identifier that names the category / interface associated with this implementation. / FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier() / with a different meaning. For example: / ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() / returns the class interface name, whereas / ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier() / returns the category name. IdentifierInfo *getIdentifier() const { return Id; } I did not change the interface, but clearly, it would be a good idea to do so. The patch uses the existing downcasted pointer to call the correct version.
- With the above change, when deserializing a ObjCCategoryImplDecl instance, ObjCImplDecl::setClassInterface() was being called by ASTDeclReader::VisitObjCImplDecl() before the category name was deserialized in ASTDeclReader::VisitObjCCategoryImplDecl(). The patch delays the call to ObjCImplDecl::setClassInterface() until after the category name is deserialized and set.
The subtle fix. Calling ImplD->getIdentifier() is required to get the category name. this->getIdentifier() returns the class name.