diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index f5098f06a9f6..a445042aecc1 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -2320,11 +2320,9 @@ class ObjCImplDecl : public ObjCContainerDecl { protected: ObjCImplDecl(Kind DK, DeclContext *DC, ObjCInterfaceDecl *classInterface, + IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc) - : ObjCContainerDecl(DK, DC, - classInterface? classInterface->getIdentifier() - : nullptr, - nameLoc, atStartLoc), + : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc), ClassInterface(classInterface) {} public: @@ -2386,9 +2384,6 @@ public: class ObjCCategoryImplDecl : public ObjCImplDecl { void anchor() override; - // Category name - IdentifierInfo *Id; - // Category name location SourceLocation CategoryNameLoc; @@ -2396,8 +2391,9 @@ class ObjCCategoryImplDecl : public ObjCImplDecl { ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc) - : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), - Id(Id), CategoryNameLoc(CategoryNameLoc) {} + : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, + nameLoc, atStartLoc), + CategoryNameLoc(CategoryNameLoc) {} public: static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, @@ -2407,37 +2403,10 @@ public: SourceLocation CategoryNameLoc); static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// 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; - } - void setIdentifier(IdentifierInfo *II) { Id = II; } - ObjCCategoryDecl *getCategoryDecl() const; SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } - /// getName - Get the name of identifier for the class interface associated - /// with this implementation as a StringRef. - // - // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different - // meaning. - StringRef getName() const { return Id ? Id->getName() : StringRef(); } - - /// @brief Get the name of the class associated with this interface. - // - // FIXME: Deprecated, move clients to getName(). - std::string getNameAsString() const { - return getName(); - } - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} @@ -2493,7 +2462,10 @@ class ObjCImplementationDecl : public ObjCImplDecl { SourceLocation superLoc = SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) - : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), + : ObjCImplDecl(ObjCImplementation, DC, classInterface, + classInterface ? classInterface->getIdentifier() + : nullptr, + nameLoc, atStartLoc), SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), IvarInitializers(nullptr), NumIvarInitializers(0), diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 4ba609b56269..cc6f2fa70541 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1414,6 +1414,11 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, const PrintingPolicy &P) const { const DeclContext *Ctx = getDeclContext(); + // For ObjC methods, look through categories and use the interface as context. + if (auto *MD = dyn_cast(this)) + if (auto *ID = MD->getClassInterface()) + Ctx = ID; + if (Ctx->isFunctionOrMethod()) { printName(OS); return; diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index 05dd886adcef..00d50c0e3bdf 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -262,9 +262,13 @@ void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD = dyn_cast(MD->getDeclContext()); assert (CD && "Missing container decl in GetNameForMethod"); - OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName(); - if (const ObjCCategoryImplDecl *CID = dyn_cast(CD)) + OS << (MD->isInstanceMethod() ? '-' : '+') << '['; + if (const ObjCCategoryImplDecl *CID = dyn_cast(CD)) { + OS << CID->getClassInterface()->getName(); OS << '(' << *CID << ')'; + } else { + OS << CD->getName(); + } OS << ' '; MD->getSelector().print(OS); OS << ']'; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 703498755c2d..3e3e50b85c74 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -273,8 +273,8 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) { << OC->getIdentifier()->getNameStart() << ')'; } } else if (const auto *OCD = dyn_cast(DC)) { - OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' - << OCD->getIdentifier()->getNameStart() << ')'; + OS << OCD->getClassInterface()->getName() << '(' + << OCD->getName() << ')'; } else if (isa(DC)) { // We can extract the type of the class from the self pointer. if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 93d0f9384fff..719b6ad3414a 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1138,7 +1138,6 @@ void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) { void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { VisitObjCImplDecl(D); - D->setIdentifier(Record.getIdentifierInfo()); D->CategoryNameLoc = ReadSourceLocation(); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 200be6688b07..190d3975b701 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -814,7 +814,6 @@ void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) { void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { VisitObjCImplDecl(D); - Record.AddIdentifierRef(D->getIdentifier()); Record.AddSourceLocation(D->getCategoryNameLoc()); Code = serialization::DECL_OBJC_CATEGORY_IMPL; } diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index b3e287ebf815..0fe0f3a6ed58 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -615,8 +615,8 @@ std::string AnalysisConsumer::getFunctionName(const Decl *D) { << OC->getIdentifier()->getNameStart() << ')'; } } else if (const auto *OCD = dyn_cast(DC)) { - OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' - << OCD->getIdentifier()->getNameStart() << ')'; + OS << OCD->getClassInterface()->getName() << '(' + << OCD->getName() << ')'; } else if (isa(DC)) { // We can extract the type of the class from the self pointer. if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) { diff --git a/clang/test/Index/Core/index-source.m b/clang/test/Index/Core/index-source.m index e54198ab8617..2675edd02678 100644 --- a/clang/test/Index/Core/index-source.m +++ b/clang/test/Index/Core/index-source.m @@ -188,7 +188,7 @@ extern int setjmp(jmp_buf); @end // CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelCont | rel: 1 -// CHECK: [[@LINE+1]]:20 | extension/ObjC | I3 | c:objc(cy)I3@bar | | Def | rel: 0 +// CHECK: [[@LINE+1]]:20 | extension/ObjC | bar | c:objc(cy)I3@bar | | Def | rel: 0 @implementation I3(bar) @end diff --git a/clang/test/Index/Core/index-subkinds.m b/clang/test/Index/Core/index-subkinds.m index bb3a37c95105..71959d4ce05f 100644 --- a/clang/test/Index/Core/index-subkinds.m +++ b/clang/test/Index/Core/index-subkinds.m @@ -32,7 +32,7 @@ @interface MyTestCase(cat) @end // CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelCont | rel: 1 -// CHECK: [[@LINE+1]]:28 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | | Def | rel: 0 +// CHECK: [[@LINE+1]]:28 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | | Def | rel: 0 @implementation MyTestCase(cat) // CHECK: [[@LINE+1]]:9 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1 - (void)testInCat {} diff --git a/clang/test/Misc/ast-dump-decl.m b/clang/test/Misc/ast-dump-decl.m index 539923b2e36a..4cfb8aa0c41d 100644 --- a/clang/test/Misc/ast-dump-decl.m +++ b/clang/test/Misc/ast-dump-decl.m @@ -77,7 +77,7 @@ @end // CHECK: ObjCCategoryDecl{{.*}} TestObjCCategoryDecl // CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' -// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCCategoryDecl' // CHECK-NEXT: ObjCProtocol{{.*}} 'P' // CHECK-NEXT: ObjCMethodDecl{{.*}} bar @@ -85,7 +85,7 @@ - (void) bar { } @end -// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCClass +// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCCategoryDecl // CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' // CHECK-NEXT: ObjCCategory{{.*}} 'TestObjCCategoryDecl' // CHECK-NEXT: ObjCMethodDecl{{.*}} bar