diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index bfd090ae20d5..c0f3e17693dc 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -954,11 +954,12 @@ void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { if (OMD->isVariadic()) Out << ", ..."; + + prettyPrintAttributes(OMD); if (OMD->getBody() && !Policy.TerseOutput) { Out << ' '; OMD->getBody()->printPretty(Out, nullptr, Policy); - Out << '\n'; } else if (Policy.PolishForDeclaration) Out << ';'; @@ -968,6 +969,7 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { std::string I = OID->getNameAsString(); ObjCInterfaceDecl *SID = OID->getSuperClass(); + bool eolnOut = false; if (SID) Out << "@implementation " << I << " : " << *SID; else @@ -975,6 +977,7 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { if (OID->ivar_size() > 0) { Out << "{\n"; + eolnOut = true; Indentation += Policy.Indentation; for (const auto *I : OID->ivars()) { Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()). @@ -983,7 +986,13 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { Indentation -= Policy.Indentation; Out << "}\n"; } + else if (SID || (OID->decls_begin() != OID->decls_end())) { + Out << "\n"; + eolnOut = true; + } VisitDeclContext(OID, false); + if (!eolnOut) + Out << "\n"; Out << "@end"; } @@ -1022,14 +1031,14 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { Indentation -= Policy.Indentation; Out << "}\n"; } - else if (SID) { + else if (SID || (OID->decls_begin() != OID->decls_end())) { Out << "\n"; eolnOut = true; } VisitDeclContext(OID, false); if (!eolnOut) - Out << ' '; + Out << "\n"; Out << "@end"; // FIXME: implement the rest... } diff --git a/clang/test/Misc/ast-print-objectivec.m b/clang/test/Misc/ast-print-objectivec.m new file mode 100644 index 000000000000..5e7acd37b873 --- /dev/null +++ b/clang/test/Misc/ast-print-objectivec.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s + +@interface NSObject @end + +@protocol P +- (void)MethP __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +@end + +@interface I : NSObject

+- (void)MethI __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +@end + +@interface I(CAT) +- (void)MethCAT __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))); +@end + +@implementation I +- (void)MethP __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {} +- (void)MethI __attribute__((availability(macosx,introduced=10.1.0,deprecated=10.2))) {} +@end + +// CHECK: @protocol P +// CHECK: - (void) MethP __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @interface I : NSObject

+// CHECK: - (void) MethI __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @interface I(CAT) +// CHECK: - (void) MethCAT __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))); +// CHECK: @end + +// CHECK: @implementation I +// CHECK: - (void) MethP __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))) { +// CHECK: } + +// CHECK: - (void) MethI __attribute__((availability(macosx, introduced=10.1.0, deprecated=10.2))) { +// CHECK: } + +// CHECK: @end