diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1571,13 +1571,16 @@ // For ObjC methods and properties, look through categories and use the // interface as context. - if (auto *MD = dyn_cast(this)) + if (auto *MD = dyn_cast(this)) { if (auto *ID = MD->getClassInterface()) Ctx = ID; - if (auto *PD = dyn_cast(this)) { + } else if (auto *PD = dyn_cast(this)) { if (auto *MD = PD->getGetterMethodDecl()) if (auto *ID = MD->getClassInterface()) Ctx = ID; + } else if (auto *ID = dyn_cast(this)) { + if (auto *CI = ID->getContainingInterface()) + Ctx = CI; } if (Ctx->isFunctionOrMethod()) diff --git a/clang/unittests/AST/NamedDeclPrinterTest.cpp b/clang/unittests/AST/NamedDeclPrinterTest.cpp --- a/clang/unittests/AST/NamedDeclPrinterTest.cpp +++ b/clang/unittests/AST/NamedDeclPrinterTest.cpp @@ -230,6 +230,27 @@ "Obj::property")); } +TEST(NamedDeclPrinter, TestInstanceObjCClassExtension) { + const char *Code = +R"( +@interface ObjC +@end +@interface ObjC () { + char data; // legal with non-fragile ABI. +} +@end +)"; + + std::vector Args{ + "-std=c++11", "-xobjective-c++", + "-fobjc-runtime=macosx" /*force to use non-fragile ABI*/}; + ASSERT_TRUE(PrintedNamedDeclMatches(Code, Args, + /*SuppressUnwrittenScope*/ true, + namedDecl(hasName("data")).bind("id"), + // not "::data" + "ObjC::data", "input.mm")); +} + TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) { const char *Code = R"(