diff options
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 25 | ||||
-rw-r--r-- | test/Index/comment-cplus-decls.cpp | 146 |
2 files changed, 171 insertions, 0 deletions
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 493e46be47..d06ccc5157 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -52,6 +52,7 @@ namespace { void VisitRecordDecl(RecordDecl *D); void VisitEnumConstantDecl(EnumConstantDecl *D); void VisitFunctionDecl(FunctionDecl *D); + void VisitFriendDecl(FriendDecl *D); void VisitFieldDecl(FieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitLabelDecl(LabelDecl *D); @@ -580,6 +581,30 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } } +void DeclPrinter::VisitFriendDecl(FriendDecl *D) { + if (TypeSourceInfo *TSI = D->getFriendType()) { + if (CXXRecordDecl *FriendD = TSI->getType()->getAsCXXRecordDecl()) { + Out << "friend "; + VisitCXXRecordDecl(FriendD); + } + } + else if (FunctionDecl *FD = + dyn_cast<FunctionDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitFunctionDecl(FD); + } + else if (FunctionTemplateDecl *FTD = + dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitFunctionTemplateDecl(FTD); + } + else if (ClassTemplateDecl *CTD = + dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) { + Out << "friend "; + VisitClassTemplateDecl(CTD); + } +} + void DeclPrinter::VisitFieldDecl(FieldDecl *D) { if (!Policy.SuppressSpecifiers && D->isMutable()) Out << "mutable "; diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp new file mode 100644 index 0000000000..3d997a5007 --- /dev/null +++ b/test/Index/comment-cplus-decls.cpp @@ -0,0 +1,146 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 %s > %t/out +// RUN: FileCheck %s < %t/out + +// Ensure that XML we generate is not invalid. +// RUN: FileCheck %s -check-prefix=WRONG < %t/out +// WRONG-NOT: CommentXMLInvalid +// rdar://12378714 + +/** + * \brief plain c++ class +*/ +class Test +{ +public: +/** + * \brief plain c++ constructor +*/ + Test () : reserved (new data()) {} + +/** + * \brief plain c++ member function +*/ + unsigned getID() const + { + return reserved->objectID; + } +/** + * \brief plain c++ destructor +*/ + ~Test () {} +protected: + struct data { + unsigned objectID; + }; +/** + * \brief plain c++ data field +*/ + data* reserved; +}; +// CHECK: <Declaration>class Test {\n}</Declaration> +// CHECK: <Declaration>Test() : reserved(new Test::data())</Declaration> +// CHECK: <Declaration>unsigned int getID() const</Declaration> +// CHECK: <Declaration>void ~Test()</Declaration> +// CHECK: <Declaration>Test::data *reserved</Declaration> + + +class S { +/** + * \brief Aaa +*/ + friend class Test; +/** + * \brief Bbb +*/ + friend void foo() {} + +/** + * \brief Ccc +*/ + friend int int_func(); + +/** + * \brief Ddd +*/ + friend bool operator==(const Test &, const Test &); + +/** + * \brief Eee +*/ +template <typename T> friend void TemplateFriend(); + +/** + * \brief Eee +*/ + template <typename T> friend class TemplateFriendClass; + +}; +// CHECK: <Declaration>friend class Test {\n}</Declaration> +// CHECK: <Declaration>friend void foo()</Declaration> +// CHECK: <Declaration>friend int int_func()</Declaration> +// CHECK: <Declaration>friend bool operator==(const Test &, const Test &)</Declaration> +// CHECK: <Declaration>friend template <typename T> void TemplateFriend()</Declaration> +// CHECK: <Declaration>friend template <typename T> class TemplateFriendClass</Declaration> + +namespace test0 { + namespace ns { + void f(int); + } + + struct A { +/** + * \brief Fff +*/ + friend void ns::f(int a); + }; +} +// CHECK: <Declaration>friend void f(int a)</Declaration> + +namespace test1 { + template <class T> struct Outer { + void foo(T); + struct Inner { +/** + * \brief Ggg +*/ + friend void Outer::foo(T); + }; + }; +} +// CHECK: <Declaration>friend void foo(T)</Declaration> + +namespace test2 { + namespace foo { + void Func(int x); + } + + class Bar { +/** + * \brief Hhh +*/ + friend void ::test2::foo::Func(int x); + }; +} +// CHECK: <Declaration>friend void Func(int x)</Declaration> + +namespace test3 { + template<class T> class vector { + public: + vector(int i) {} +/** + * \brief Iii +*/ + void f(const T& t = T()) {} + }; + class A { + private: +/** + * \brief Jjj +*/ + friend void vector<A>::f(const A&); + }; +} +// CHECK: <Declaration>void f(const T &t = T())</Declaration> +// CHECK: <Declaration>friend void f(const test3::A &)</Declaration> |