diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 22ee0cfcb6907a2a7afd4918af285b2c6f60562b..29f1d7bd1af5bd1776333c100371b36a099bae23 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -451,6 +451,51 @@ comments::FullComment *ASTContext::getCommentForDecl( if (comments::FullComment *FC = getCommentForDecl(TD, PP)) return cloneFullComment(FC, D); } + else if (const ObjCInterfaceDecl *IC = dyn_cast<ObjCInterfaceDecl>(D)) { + while (IC->getSuperClass()) { + IC = IC->getSuperClass(); + if (comments::FullComment *FC = getCommentForDecl(IC, PP)) + return cloneFullComment(FC, D); + } + } + else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { + if (const ObjCInterfaceDecl *IC = CD->getClassInterface()) + if (comments::FullComment *FC = getCommentForDecl(IC, PP)) + return cloneFullComment(FC, D); + } + else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { + if (!(RD = RD->getDefinition())) + return NULL; + // Check non-virtual bases. + for (CXXRecordDecl::base_class_const_iterator I = + RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { + if (I->isVirtual()) + continue; + QualType Ty = I->getType(); + if (Ty.isNull()) + continue; + if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) { + if (!(NonVirtualBase= NonVirtualBase->getDefinition())) + continue; + + if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP)) + return cloneFullComment(FC, D); + } + } + // Check virtual bases. + for (CXXRecordDecl::base_class_const_iterator I = + RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) { + QualType Ty = I->getType(); + if (Ty.isNull()) + continue; + if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) { + if (!(VirtualBase= VirtualBase->getDefinition())) + continue; + if (comments::FullComment *FC = getCommentForDecl((VirtualBase), PP)) + return cloneFullComment(FC, D); + } + } + } return NULL; } diff --git a/test/Misc/ast-dump-subclass-comment.mm b/test/Misc/ast-dump-subclass-comment.mm new file mode 100644 index 0000000000000000000000000000000000000000..4e05a2a612353f31281980556ba08933009657b2 --- /dev/null +++ b/test/Misc/ast-dump-subclass-comment.mm @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -x objective-c++ -Wdocumentation -ast-dump %s | FileCheck %s +// rdar://13647476 + +//! NSObject is root of all. +@interface NSObject +@end +// CHECK: ObjCInterfaceDecl{{.*}}NSObject +// CHECK-NEXT: FullComment 0x{{[^ ]*}} <line:[[@LINE-4]]:4, col:28> +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:28> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:28> Text=" NSObject is root of all." + +//! An umbrella class for super classes. +@interface SuperClass +@end +// CHECK: ObjCInterfaceDecl{{.*}}SuperClass +// CHECK-NEXT: FullComment 0x{{[^ ]*}} <line:[[@LINE-4]]:4, col:40> +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:40> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:40> Text=" An umbrella class for super classes." + +@interface SubClass : SuperClass +@end +// CHECK: ObjCInterfaceDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:2> SubClass +// CHECK-NEXT: ObjCInterface 0x{{[^ ]*}} 'SuperClass' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:40> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:40> Text=" An umbrella class for super classes." + +@interface SubSubClass : SubClass +@end +// CHECK: ObjCInterfaceDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:2> SubSubClass +// CHECK-NEXT: ObjCInterface{{.*}} 'SubClass' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:40> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:40> Text=" An umbrella class for super classes." + +@interface SubSubClass (Private) +@end +// CHECK: ObjCCategoryDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:2> Private +// CHECK-NEXT: ObjCInterface{{.*}} 'SubSubClass' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:40> +// CHECK-TEXT: TextComment{{.*}} <col:4, col:40> Text=" An umbrella class for super classes." + +//! Something valuable to the organization. +class Asset { + +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-3]]:1, line:[[@LINE-1]]:1> class Asset +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:43> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:43> Text=" Something valuable to the organization." + +//! An individual human or human individual. +class Person : public Asset { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class Person +// CHECK-NEXT: public 'class Asset' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:44> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:44> Text=" An individual human or human individual." + +class Student : public Person { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class Student +// CHECK-NEXT: public 'class Person' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:44> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:44> Text=" An individual human or human individual." + +//! Every thing is a part +class Parts { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class Parts +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:25> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:25> Text=" Every thing is a part" + +class Window : virtual Parts { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class Window +// CHECK-NEXT: virtual private 'class Parts' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:25> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:25> Text=" Every thing is a part" + +class Door : virtual Parts { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class Door +// CHECK-NEXT: virtual private 'class Parts' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:25> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:25> Text=" Every thing is a part" + +class House : Window, Door { +}; +// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:1, line:[[@LINE-1]]:1> class House +// CHECK-NEXT: private 'class Window' +// CHECK-NEXT: private 'class Door' +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment{{.*}} <col:4, col:25> +// CHECK-NEXT: TextComment{{.*}} <col:4, col:25> Text=" Every thing is a part"