Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -1604,6 +1604,11 @@ OS << *ED; else continue; + } else if (const auto *CD = dyn_cast(DC)) { + if (CD->IsClassExtension()) + OS << "(class extension)"; + else + OS << *CD; } else { OS << *cast(DC); } Index: unittests/AST/NamedDeclPrinterTest.cpp =================================================================== --- unittests/AST/NamedDeclPrinterTest.cpp +++ unittests/AST/NamedDeclPrinterTest.cpp @@ -115,6 +115,18 @@ "input.cc"); } +::testing::AssertionResult +PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName, + StringRef ExpectedPrinted) { + std::vector Args{"-std=c++11", "-xobjective-c++"}; + return PrintedNamedDeclMatches(Code, + Args, + /*SuppressUnwrittenScope*/ true, + objcPropertyDecl(hasName(DeclName)).bind("id"), + ExpectedPrinted, + "input.m"); +} + } // unnamed namespace TEST(NamedDeclPrinter, TestNamespace1) { @@ -179,3 +191,17 @@ "A", "X::A")); } + +TEST(NamedDeclPrinter, TestObjCClassExtension) { + ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches( + R"( + @interface Obj + @end + + @interface Obj () + @property(nonatomic) int property; + @end + )", + "property", + "(class extension)::property")); +}