|  | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s | 
|  | // RUN: %clang_cc1 -std=c++14 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s | 
|  |  | 
|  | // This file contains lots of corner cases, so ensure that XML we generate is not invalid. | 
|  | // RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG | 
|  | // WRONG-NOT: CommentXMLInvalid | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{expected quoted string after equals sign}} | 
|  | /// <a href=> | 
|  | int test_html1(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{expected quoted string after equals sign}} | 
|  | /// <a href==> | 
|  | int test_html2(int); | 
|  |  | 
|  | // expected-warning@+3 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+2 {{expected quoted string after equals sign}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a href= blah | 
|  | int test_html3(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a => | 
|  | int test_html4(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a "aaa"> | 
|  | int test_html5(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a a="b" => | 
|  | int test_html6(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a a="b" "aaa"> | 
|  | int test_html7(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML tag 'a' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /// <a a="b" = | 
|  | int test_html8(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML start tag prematurely ended, expected attribute name or '>'}} expected-note@+1 {{HTML tag started here}} | 
|  | /** Aaa bbb<img ddd eee | 
|  | * fff ggg. | 
|  | */ | 
|  | int test_html9(int); | 
|  |  | 
|  | // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}} | 
|  | /** Aaa bbb<img ddd eee 42% | 
|  | * fff ggg. | 
|  | */ | 
|  | int test_html10(int); | 
|  |  | 
|  | // expected-warning@+1 {{HTML end tag 'br' is forbidden}} | 
|  | /// <br></br> | 
|  | int test_html11(int); | 
|  |  | 
|  | /// Aaa bbb<img/> | 
|  | int test_html12(int); | 
|  |  | 
|  | /// Aaa bbb<img /> | 
|  | int test_html13(int); | 
|  |  | 
|  | /// Aaa bbb<img src=""> | 
|  | int test_html14(int); | 
|  |  | 
|  | /// Aaa bbb<img src=""/> | 
|  | int test_html15(int); | 
|  |  | 
|  | /// Aaa bbb<img src="" /> | 
|  | int test_html16(int); | 
|  |  | 
|  | /// <blockquote>Meow</blockquote> | 
|  | int test_html_nesting1(int); | 
|  |  | 
|  | /// <b><i>Meow</i></b> | 
|  | int test_html_nesting2(int); | 
|  |  | 
|  | /// <p>Aaa<br> | 
|  | /// Bbb</p> | 
|  | int test_html_nesting3(int); | 
|  |  | 
|  | /// <p>Aaa<br /> | 
|  | /// Bbb</p> | 
|  | int test_html_nesting4(int); | 
|  |  | 
|  | // expected-warning@+3 {{HTML tag 'b' requires an end tag}} | 
|  | // expected-warning@+2 {{HTML tag 'i' requires an end tag}} | 
|  | // expected-warning@+1 {{HTML end tag does not match any start tag}} | 
|  | /// <b><i>Meow</a> | 
|  | int test_html_nesting5(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML start tag 'i' closed by 'b'}} | 
|  | // expected-warning@+1 {{HTML end tag does not match any start tag}} | 
|  | /// <b><i>Meow</b></b> | 
|  | int test_html_nesting6(int); | 
|  |  | 
|  | // expected-warning@+2 {{HTML start tag 'i' closed by 'b'}} | 
|  | // expected-warning@+1 {{HTML end tag does not match any start tag}} | 
|  | /// <b><i>Meow</b></i> | 
|  | int test_html_nesting7(int); | 
|  |  | 
|  | // expected-warning@+1 {{HTML tag 'b' requires an end tag}} | 
|  | /// <b>Meow | 
|  | int test_html_nesting8(int); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\returns Aaa | 
|  | int test_block_command1(int); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief \returns Aaa | 
|  | int test_block_command2(int); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief | 
|  | /// \returns Aaa | 
|  | int test_block_command3(int); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief | 
|  | /// | 
|  | /// \returns Aaa | 
|  | int test_block_command4(int); | 
|  |  | 
|  | // There is trailing whitespace on one of the following lines, don't remove it! | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief | 
|  | /// | 
|  | /// \returns Aaa | 
|  | int test_block_command5(int); | 
|  |  | 
|  | /// \brief \c Aaa | 
|  | int test_block_command6(int); | 
|  |  | 
|  | // We don't recognize comments in double quotes. | 
|  | /// "\brief \returns Aaa" | 
|  | int test_block_command7(int); | 
|  |  | 
|  | // But only if they're single-line. (Doxygen treats multi-line quotes inconsistently.) | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// "\brief | 
|  | /// \returns Aaa" | 
|  | int test_block_command8(int); | 
|  |  | 
|  | // expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\brief' here}} | 
|  | /// \brief Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \brief Ccc | 
|  | int test_duplicate_brief1(int); | 
|  |  | 
|  | // expected-warning@+5 {{duplicated command '\short'}} expected-note@+1 {{previous command '\short' here}} | 
|  | /// \short Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \short Ccc | 
|  | int test_duplicate_brief2(int); | 
|  |  | 
|  | // expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\short' (an alias of '\brief') here}} | 
|  | /// \short Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \brief Ccc | 
|  | int test_duplicate_brief3(int); | 
|  |  | 
|  |  | 
|  | /// \return Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \return Ccc | 
|  | int test_multiple_returns1(int); | 
|  |  | 
|  | /// \returns Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \returns Ccc | 
|  | int test_multiple_returns2(int); | 
|  |  | 
|  | /// \result Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \result Ccc | 
|  | int test_multiple_returns3(int); | 
|  |  | 
|  | /// \returns Aaa | 
|  | /// | 
|  | /// Bbb | 
|  | /// | 
|  | /// \return Ccc | 
|  | int test_multiple_returns4(int); | 
|  |  | 
|  |  | 
|  | /// expected-warning@+1 {{empty paragraph passed to '\retval' command}} | 
|  | /// \retval 0 | 
|  | int test_retval_no_paragraph(); | 
|  |  | 
|  | /// \retval 0 Everything is fine. | 
|  | int test_retval_fine(); | 
|  |  | 
|  |  | 
|  | // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | /// \param a Blah blah. | 
|  | int test_param1_backslash; | 
|  |  | 
|  | // Check that the diagnostic uses the same command marker as the comment. | 
|  | // expected-warning@+1 {{'@param' command used in a comment that is not attached to a function declaration}} | 
|  | /// @param a Blah blah. | 
|  | int test_param1_at; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\param' command}} | 
|  | /// \param | 
|  | /// \param a Blah blah. | 
|  | int test_param2(int a); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\param' command}} | 
|  | /// \param a | 
|  | int test_param3(int a); | 
|  |  | 
|  | /// \param a Blah blah. | 
|  | int test_param4(int a); | 
|  |  | 
|  | /// \param [in] a Blah blah. | 
|  | int test_param5(int a); | 
|  |  | 
|  | /// \param [out] a Blah blah. | 
|  | int test_param6(int a); | 
|  |  | 
|  | /// \param [in,out] a Blah blah. | 
|  | int test_param7(int a); | 
|  |  | 
|  | // expected-warning@+1 {{whitespace is not allowed in parameter passing direction}} | 
|  | /// \param [ in ] a Blah blah. | 
|  | int test_param8(int a); | 
|  |  | 
|  | // expected-warning@+1 {{whitespace is not allowed in parameter passing direction}} | 
|  | /// \param [in, out] a Blah blah. | 
|  | int test_param9(int a); | 
|  |  | 
|  | // expected-warning@+1 {{unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'}} | 
|  | /// \param [ junk] a Blah blah. | 
|  | int test_param10(int a); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'a' not found in the function declaration}} | 
|  | /// \param a Blah blah. | 
|  | int test_param11(); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}} | 
|  | /// \param A Blah blah. | 
|  | int test_param12(int a); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}} | 
|  | /// \param aab Blah blah. | 
|  | int test_param13(int aaa, int bbb); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'aab' not found in the function declaration}} expected-note@+2 {{did you mean 'bbb'?}} | 
|  | /// \param aaa Blah blah. | 
|  | /// \param aab Blah blah. | 
|  | int test_param14(int aaa, int bbb); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} | 
|  | /// \param aab Blah blah. | 
|  | int test_param15(int bbb, int ccc); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} | 
|  | /// \param aab Ccc. | 
|  | /// \param aaa Aaa. | 
|  | /// \param bbb Bbb. | 
|  | int test_param16(int aaa, int bbb); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'aab' not found in the function declaration}} | 
|  | /// \param aaa Aaa. | 
|  | /// \param aab Ccc. | 
|  | /// \param bbb Bbb. | 
|  | int test_param17(int aaa, int bbb); | 
|  |  | 
|  | // expected-warning@+3 {{parameter 'aab' not found in the function declaration}} | 
|  | /// \param aaa Aaa. | 
|  | /// \param bbb Bbb. | 
|  | /// \param aab Ccc. | 
|  | int test_param18(int aaa, int bbb); | 
|  |  | 
|  | class C { | 
|  | // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}} | 
|  | /// \param aaa Blah blah. | 
|  | C(int bbb, int ccc); | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}} | 
|  | /// \param aaa Blah blah. | 
|  | int test_param19(int bbb, int ccc); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} | 
|  | /// \param aab Blah blah. | 
|  | template<typename T> | 
|  | void test_param20(int bbb, int ccc); | 
|  |  | 
|  | // expected-warning@+3 {{parameter 'a' is already documented}} | 
|  | // expected-note@+1 {{previous documentation}} | 
|  | /// \param a Aaa. | 
|  | /// \param a Aaa. | 
|  | int test_param21(int a); | 
|  |  | 
|  | // expected-warning@+4 {{parameter 'x2' is already documented}} | 
|  | // expected-note@+2 {{previous documentation}} | 
|  | /// \param x1 Aaa. | 
|  | /// \param x2 Bbb. | 
|  | /// \param x2 Ccc. | 
|  | int test_param22(int x1, int x2, int x3); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\param' command}} | 
|  | /// \param a | 
|  | /// \retval 0 Blah blah. | 
|  | int test_param23(int a); | 
|  |  | 
|  | /// \param a \ref test_param23 has an empty paragraph, this doesn't. | 
|  | int test_param24(int a); | 
|  |  | 
|  | //===--- | 
|  | // Test that we treat typedefs to some non-function types as functions for the | 
|  | // purposes of documentation comment parsing. | 
|  | //===--- | 
|  |  | 
|  | namespace foo { | 
|  | inline namespace bar { | 
|  | template<typename> | 
|  | struct function_wrapper {}; | 
|  |  | 
|  | template<unsigned> | 
|  | struct not_a_function_wrapper {}; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef int test_function_like_typedef1(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef int (*test_function_like_typedef2)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef int (* const test_function_like_typedef3)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef int (C::*test_function_like_typedef4)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef foo::function_wrapper<int (int aaa, int ccc)> test_function_like_typedef5; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef foo::function_wrapper<int (int aaa, int ccc)> *test_function_like_typedef6; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef foo::function_wrapper<int (int aaa, int ccc)> &test_function_like_typedef7; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | typedef foo::function_wrapper<int (int aaa, int ccc)> &&test_function_like_typedef8; | 
|  |  | 
|  |  | 
|  | typedef int (*test_not_function_like_typedef1)(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | /// \param aaa Meow. | 
|  | typedef test_not_function_like_typedef1 test_not_function_like_typedef2; | 
|  |  | 
|  | // Check that the diagnostic uses the same command marker as the comment. | 
|  | // expected-warning@+1 {{'@param' command used in a comment that is not attached to a function declaration}} | 
|  | /// @param aaa Meow. | 
|  | typedef unsigned int test_not_function_like_typedef3; | 
|  |  | 
|  | // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | /// \param aaa Meow. | 
|  | typedef foo::not_a_function_wrapper<1> test_not_function_like_typedef4; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using1 = int (int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using2 = int (*)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using3 = int (* const)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using4 = int (C::*)(int aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using5 = foo::function_wrapper<int (int aaa, int ccc)>; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using6 = foo::function_wrapper<int (int aaa, int ccc)> *; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using7 = foo::function_wrapper<int (int aaa, int ccc)> &; | 
|  |  | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \returns aaa. | 
|  | using test_function_like_using8 = foo::function_wrapper<int (int aaa, int ccc)> &&; | 
|  |  | 
|  | // expected-warning@+4 {{template parameter 'U' not found in the template declaration}} expected-note@+4 {{did you mean 'T'?}} | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \tparam U Uuu. | 
|  | template<typename T> | 
|  | using test_function_like_using9 = int(T aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+4 {{template parameter 'U' not found in the template declaration}} expected-note@+4 {{did you mean 'T'?}} | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \tparam U Uuu. | 
|  | template<typename T> | 
|  | using test_function_like_using10 = int (*)(T aaa, int ccc); | 
|  |  | 
|  | // expected-warning@+4 {{template parameter 'U' not found in the template declaration}} expected-note@+4 {{did you mean 'T'?}} | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \tparam U Uuu. | 
|  | template<typename T> | 
|  | using test_function_like_using11 = foo::function_wrapper<int (T aaa, int ccc)>; | 
|  |  | 
|  | // expected-warning@+4 {{template parameter 'U' not found in the template declaration}} expected-note@+4 {{did you mean 'T'?}} | 
|  | // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}} | 
|  | /// \param aaa Meow. | 
|  | /// \param bbb Bbb. | 
|  | /// \tparam U Uuu. | 
|  | template<typename T> | 
|  | using test_function_like_using12 = foo::function_wrapper<int (T aaa, int ccc)> *; | 
|  |  | 
|  | using test_not_function_like_using1 = int (*)(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | /// \param aaa Meow. | 
|  | using test_not_function_like_using2 = test_not_function_like_using1; | 
|  |  | 
|  | // Check that the diagnostic uses the same command marker as the comment. | 
|  | // expected-warning@+1 {{'@param' command used in a comment that is not attached to a function declaration}} | 
|  | /// @param aaa Meow. | 
|  | using test_not_function_like_using3 = unsigned int; | 
|  |  | 
|  | // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | /// \param aaa Meow. | 
|  | using test_not_function_like_using4 = foo::not_a_function_wrapper<1>; | 
|  |  | 
|  | /// \param aaa Aaa | 
|  | /// \param ... Vararg | 
|  | int test_vararg_param1(int aaa, ...); | 
|  |  | 
|  | /// \param ... Vararg | 
|  | int test_vararg_param2(...); | 
|  |  | 
|  | // expected-warning@+1 {{parameter '...' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}} | 
|  | /// \param ... Vararg | 
|  | int test_vararg_param3(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{parameter '...' not found in the function declaration}} | 
|  | /// \param ... Vararg | 
|  | int test_vararg_param4(); | 
|  |  | 
|  |  | 
|  | /// \param aaa Aaa | 
|  | /// \param ... Vararg | 
|  | template<typename T> | 
|  | int test_template_vararg_param1(int aaa, ...); | 
|  |  | 
|  | /// \param ... Vararg | 
|  | template<typename T> | 
|  | int test_template_vararg_param2(...); | 
|  |  | 
|  | // expected-warning@+1 {{parameter '...' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}} | 
|  | /// \param ... Vararg | 
|  | template<typename T> | 
|  | int test_template_vararg_param3(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{parameter '...' not found in the function declaration}} | 
|  | /// \param ... Vararg | 
|  | template<typename T> | 
|  | int test_template_vararg_param4(); | 
|  |  | 
|  |  | 
|  | // expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}} | 
|  | /// \tparam T Aaa | 
|  | int test_tparam1; | 
|  |  | 
|  | // expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}} | 
|  | /// \tparam T Aaa | 
|  | void test_tparam2(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\tparam' command}} | 
|  | /// \tparam | 
|  | /// \param aaa Blah blah | 
|  | template<typename T> | 
|  | void test_tparam3(T aaa); | 
|  |  | 
|  | // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}} | 
|  | /// \tparam T Aaa | 
|  | template<typename TT> | 
|  | void test_tparam4(TT aaa); | 
|  |  | 
|  | // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}} | 
|  | /// \tparam T Aaa | 
|  | template<typename TT> | 
|  | class test_tparam5 { | 
|  | // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TTT'?}} | 
|  | /// \tparam T Aaa | 
|  | template<typename TTT> | 
|  | void test_tparam6(TTT aaa); | 
|  | }; | 
|  |  | 
|  | /// \tparam T1 Aaa | 
|  | /// \tparam T2 Bbb | 
|  | template<typename T1, typename T2> | 
|  | void test_tparam7(T1 aaa, T2 bbb); | 
|  |  | 
|  | // expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}} | 
|  | /// \tparam SomTy Aaa | 
|  | /// \tparam OtherTy Bbb | 
|  | template<typename SomeTy, typename OtherTy> | 
|  | void test_tparam8(SomeTy aaa, OtherTy bbb); | 
|  |  | 
|  | // expected-warning@+2 {{template parameter 'T1' is already documented}} expected-note@+1 {{previous documentation}} | 
|  | /// \tparam T1 Aaa | 
|  | /// \tparam T1 Bbb | 
|  | template<typename T1, typename T2> | 
|  | void test_tparam9(T1 aaa, T2 bbb); | 
|  |  | 
|  | /// \tparam T Aaa | 
|  | /// \tparam TT Bbb | 
|  | template<template<typename T> class TT> | 
|  | void test_tparam10(TT<int> aaa); | 
|  |  | 
|  | /// \tparam T Aaa | 
|  | /// \tparam TT Bbb | 
|  | /// \tparam TTT Ccc | 
|  | template<template<template<typename T> class TT, class C> class TTT> | 
|  | void test_tparam11(); | 
|  |  | 
|  | /// \tparam I Aaa | 
|  | template<int I> | 
|  | void test_tparam12(); | 
|  |  | 
|  | template<typename T, typename U> | 
|  | class test_tparam13 { }; | 
|  |  | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | using test_tparam14 = test_tparam13<T, int>; | 
|  |  | 
|  | // expected-warning@+1 {{template parameter 'U' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}} | 
|  | /// \tparam U Aaa | 
|  | template<typename T> | 
|  | using test_tparam15 = test_tparam13<T, int>; | 
|  |  | 
|  | // ---- | 
|  |  | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | class test_tparam16 { }; | 
|  |  | 
|  | typedef test_tparam16<int> test_tparam17; | 
|  | typedef test_tparam16<double> test_tparam18; | 
|  |  | 
|  | // ---- | 
|  |  | 
|  | template<typename T> | 
|  | class test_tparam19; | 
|  |  | 
|  | typedef test_tparam19<int> test_tparam20; | 
|  | typedef test_tparam19<double> test_tparam21; | 
|  |  | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | class test_tparam19 { }; | 
|  |  | 
|  | // ---- | 
|  |  | 
|  | // expected-warning@+1 {{'@tparam' command used in a comment that is not attached to a template declaration}} | 
|  | /// @tparam T Aaa | 
|  | int test_tparam22; | 
|  |  | 
|  | // ---- | 
|  |  | 
|  |  | 
|  | /// Aaa | 
|  | /// \deprecated Bbb | 
|  | void test_deprecated_1(int a) __attribute__((deprecated)); | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | /// Aaa | 
|  | /// \deprecated Bbb | 
|  | [[deprecated]] void test_deprecated_no_warning_std14(int a); | 
|  | #endif | 
|  |  | 
|  | // We don't want \deprecated to warn about empty paragraph.  It is fine to use | 
|  | // \deprecated by itself without explanations. | 
|  |  | 
|  | /// Aaa | 
|  | /// \deprecated | 
|  | void test_deprecated_2(int a) __attribute__((deprecated)); | 
|  |  | 
|  | /// Aaa | 
|  | /// \deprecated | 
|  | void test_deprecated_3(int a) __attribute__((availability(macosx,introduced=10.4))); | 
|  |  | 
|  | /// Aaa | 
|  | /// \deprecated | 
|  | void test_deprecated_4(int a) __attribute__((unavailable)); | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+3 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// Aaa | 
|  | /// \deprecated | 
|  | void test_deprecated_5(int a); | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '@deprecated' command but does not have a deprecation attribute}} expected-note@+3 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// Aaa | 
|  | /// @deprecated | 
|  | void test_deprecated_6(int a) { | 
|  | } | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | /// Aaa | 
|  | /// \deprecated | 
|  | template<typename T> | 
|  | void test_deprecated_7(T aaa); | 
|  |  | 
|  | class PR43753 { | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | static void test_deprecated_static(); | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | static auto test_deprecated_static_trailing_return() -> int; | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | static decltype(auto) test_deprecated_static_decltype_auto() { return 1; } | 
|  | #endif | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | void test_deprecated_const() const; | 
|  |  | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | auto test_deprecated_trailing_return() -> int; | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | // expected-warning@+2 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} | 
|  | // expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}} | 
|  | /// \deprecated | 
|  | decltype(auto) test_deprecated_decltype_auto() const { return a; } | 
|  |  | 
|  | private: | 
|  | int a{0}; | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | // expected-note@+2 {{previous command '\headerfile' here}} | 
|  | // expected-warning@+2 {{duplicated command '\headerfile'}} | 
|  | /// \headerfile "" | 
|  | /// \headerfile foo.h | 
|  | int test__headerfile_1(int a); | 
|  |  | 
|  |  | 
|  | /// \invariant aaa | 
|  | void test_invariant_1(int a); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\invariant' command}} | 
|  | /// \invariant | 
|  | void test_invariant_2(int a); | 
|  |  | 
|  |  | 
|  | // no-warning | 
|  | /// \returns Aaa | 
|  | int test_returns_right_decl_1(int); | 
|  |  | 
|  | class test_returns_right_decl_2 { | 
|  | // no-warning | 
|  | /// \returns Aaa | 
|  | int test_returns_right_decl_3(int); | 
|  | }; | 
|  |  | 
|  | // no-warning | 
|  | /// \returns Aaa | 
|  | template<typename T> | 
|  | int test_returns_right_decl_4(T aaa); | 
|  |  | 
|  | // no-warning | 
|  | /// \returns Aaa | 
|  | template<> | 
|  | int test_returns_right_decl_4(int aaa); | 
|  |  | 
|  | /// \returns Aaa | 
|  | template<typename T> | 
|  | T test_returns_right_decl_5(T aaa); | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | int test_returns_wrong_decl_1_backslash; | 
|  |  | 
|  | // Check that the diagnostic uses the same command marker as the comment. | 
|  | // expected-warning@+1 {{'@returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// @returns Aaa | 
|  | int test_returns_wrong_decl_1_at; | 
|  |  | 
|  | // expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \return Aaa | 
|  | int test_returns_wrong_decl_2; | 
|  |  | 
|  | // expected-warning@+1 {{'\result' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \result Aaa | 
|  | int test_returns_wrong_decl_3; | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} | 
|  | /// \returns Aaa | 
|  | void test_returns_wrong_decl_4(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} | 
|  | /// \returns Aaa | 
|  | template<typename T> | 
|  | void test_returns_wrong_decl_5(T aaa); | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}} | 
|  | /// \returns Aaa | 
|  | template<> | 
|  | void test_returns_wrong_decl_5(int aaa); | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | struct test_returns_wrong_decl_6 { }; | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | class test_returns_wrong_decl_7 { | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is attached to a constructor}} | 
|  | /// \returns Aaa | 
|  | test_returns_wrong_decl_7(); | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is attached to a destructor}} | 
|  | /// \returns Aaa | 
|  | ~test_returns_wrong_decl_7(); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | enum test_returns_wrong_decl_8 { | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | test_returns_wrong_decl_9 | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /// \returns Aaa | 
|  | namespace test_returns_wrong_decl_10 { }; | 
|  |  | 
|  | // expected-warning@+1 {{'@function' command should be used in a comment attached to a function declaration}} | 
|  | /*!	@function test_function | 
|  | */ | 
|  | typedef unsigned int Base64Flags; | 
|  | unsigned test_function(Base64Flags inFlags); | 
|  |  | 
|  | // expected-warning@+1 {{'@callback' command should be used in a comment attached to a pointer to function declaration}} | 
|  | /*! @callback test_callback | 
|  | */ | 
|  | typedef unsigned int BaseFlags; | 
|  | unsigned (*test_callback)(BaseFlags inFlags); | 
|  |  | 
|  | // expected-warning@+1 {{'\endverbatim' command does not terminate a verbatim text block}} | 
|  | /// \endverbatim | 
|  | int test_verbatim_1(); | 
|  |  | 
|  | // expected-warning@+1 {{'\endcode' command does not terminate a verbatim text block}} | 
|  | /// \endcode | 
|  | int test_verbatim_2(); | 
|  |  | 
|  | // FIXME: we give a bad diagnostic here because we throw away non-documentation | 
|  | // comments early. | 
|  | // | 
|  | // expected-warning@+3 {{'\endcode' command does not terminate a verbatim text block}} | 
|  | /// \code | 
|  | //  foo | 
|  | /// \endcode | 
|  | int test_verbatim_3(); | 
|  |  | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | int test1; ///< \brief\author Aaa | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | int test2, ///< \brief\author Aaa | 
|  | test3; ///< \brief\author Aaa | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | int test4; ///< \brief | 
|  | ///< \author Aaa | 
|  |  | 
|  |  | 
|  | class TestRelates {}; | 
|  |  | 
|  | /// \relates TestRelates | 
|  | /// \brief Aaa | 
|  | void test_relates_1(); | 
|  |  | 
|  | /// \related TestRelates | 
|  | /// \brief Aaa | 
|  | void test_relates_2(); | 
|  |  | 
|  | /// \relatesalso TestRelates | 
|  | /// \brief Aaa | 
|  | void test_relates_3(); | 
|  |  | 
|  | /// \relatedalso TestRelates | 
|  | /// \brief Aaa | 
|  | void test_relates_4(); | 
|  |  | 
|  |  | 
|  | // Check that we attach the comment to the declaration during parsing in the | 
|  | // following cases.  The test is based on the fact that we don't parse | 
|  | // documentation comments that are not attached to anything. | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach1; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach2(int); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | struct test_attach3 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach4; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | int test_attach5; ///< \brief\author Aaa | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach6(int); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | class test_attach7 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach8; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | int test_attach9; ///< \brief\author Aaa | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach10(int); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | enum test_attach9 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | test_attach10, | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | test_attach11 ///< \brief\author Aaa | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | struct test_noattach12 *test_attach13; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | typedef struct test_noattach14 *test_attach15; | 
|  |  | 
|  | // expected-warning@+1 + {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | typedef struct test_attach16 { int a; } test_attach17; | 
|  |  | 
|  | struct S { int a; }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | struct S *test_attach18; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | typedef struct S *test_attach19; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | struct test_attach20; | 
|  |  | 
|  | // expected-warning@+1 + {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | typedef struct test_attach21 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | int test_attach22; | 
|  | } test_attach23; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | namespace test_attach24 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | namespace test_attach25 { | 
|  | } | 
|  | } | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | void test_attach26(T aaa); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T, typename U> | 
|  | void test_attach27(T aaa, U bbb); | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<> | 
|  | void test_attach27(int aaa, int bbb); | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | class test_attach28 { | 
|  | T aaa; | 
|  | }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | using test_attach29 = test_attach28<int>; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T, typename U> | 
|  | class test_attach30 { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | class test_attach30<T, int> { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | template<> | 
|  | class test_attach30<int, int> { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | template<typename T> | 
|  | using test_attach31 = test_attach30<T, int>; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T, typename U, typename V> | 
|  | class test_attach32 { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T, typename U> | 
|  | class test_attach32<T, U, int> { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | class test_attach32<T, int, int> { }; | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<> | 
|  | class test_attach32<int, int, int> { }; | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | class test_attach33 { | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T, typename U> | 
|  | void test_attach34(T aaa, U bbb); | 
|  | }; | 
|  |  | 
|  | template<typename T> | 
|  | class test_attach35 { | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename TT, typename UU> | 
|  | void test_attach36(TT aaa, UU bbb); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<> template<> | 
|  | void test_attach35<int>::test_attach36(int aaa, int bbb) {} | 
|  |  | 
|  | template<typename T> | 
|  | class test_attach37 { | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{'\tparam' command used in a comment that is not attached to a template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | void test_attach38(int aaa, int bbb); | 
|  |  | 
|  | void test_attach39(int aaa, int bbb); | 
|  | }; | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '\brief' command}} | 
|  | // expected-warning@+2 {{template parameter 'T' not found in the template declaration}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<> | 
|  | void test_attach37<int>::test_attach38(int aaa, int bbb) {} | 
|  |  | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \brief\author Aaa | 
|  | /// \tparam T Aaa | 
|  | template<typename T> | 
|  | void test_attach37<T>::test_attach39(int aaa, int bbb) {} | 
|  |  | 
|  | // We used to emit warning that parameter 'a' is not found because we parsed | 
|  | // the comment in context of the redeclaration which does not have parameter | 
|  | // names. | 
|  | template <typename T> | 
|  | struct test_attach38 { | 
|  | /*! | 
|  | \param a  First param | 
|  | \param b  Second param | 
|  | */ | 
|  | template <typename B> | 
|  | void test_attach39(T a, B b); | 
|  | }; | 
|  |  | 
|  | template <> | 
|  | template <typename B> | 
|  | void test_attach38<int>::test_attach39(int, B); | 
|  |  | 
|  | // The inline comments expect a string after the command. | 
|  | // expected-warning@+1 {{'\a' command has no word arguments, expected 1}} | 
|  | /// \a | 
|  | int test_inline_no_argument_a_bad(int); | 
|  |  | 
|  | /// \a A | 
|  | int test_inline_no_argument_a_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\anchor' command has no word arguments, expected 1}} | 
|  | /// \anchor | 
|  | int test_inline_no_argument_anchor_bad(int); | 
|  |  | 
|  | /// \anchor A | 
|  | int test_inline_no_argument_anchor_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'@b' command has no word arguments, expected 1}} | 
|  | /// @b | 
|  | int test_inline_no_argument_b_bad(int); | 
|  |  | 
|  | /// @b A | 
|  | int test_inline_no_argument_b_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\c' command has no word arguments, expected 1}} | 
|  | /// \c | 
|  | int test_inline_no_argument_c_bad(int); | 
|  |  | 
|  | /// \c A | 
|  | int test_inline_no_argument_c_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\e' command has no word arguments, expected 1}} | 
|  | /// \e | 
|  | int test_inline_no_argument_e_bad(int); | 
|  |  | 
|  | /// \e A | 
|  | int test_inline_no_argument_e_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\em' command has no word arguments, expected 1}} | 
|  | /// \em | 
|  | int test_inline_no_argument_em_bad(int); | 
|  |  | 
|  | /// \em A | 
|  | int test_inline_no_argument_em_good(int); | 
|  |  | 
|  | // expected-warning@+1 {{'\p' command has no word arguments, expected 1}} | 
|  | /// \p | 
|  | int test_inline_no_argument_p_bad(int); | 
|  |  | 
|  | /// \p A | 
|  | int test_inline_no_argument_p_good(int); | 
|  |  | 
|  | // PR13411, reduced.  We used to crash on this. | 
|  | /** | 
|  | * @code Aaa. | 
|  | */ | 
|  | void test_nocrash1(int); | 
|  |  | 
|  | // We used to crash on this. | 
|  | // expected-warning@+2 {{empty paragraph passed to '\param' command}} | 
|  | // expected-warning@+1 {{empty paragraph passed to '\brief' command}} | 
|  | /// \param\brief | 
|  | void test_nocrash2(int); | 
|  |  | 
|  | // PR13593, example 1 and 2 | 
|  |  | 
|  | /** | 
|  | * Bla. | 
|  | */ | 
|  | template <typename> | 
|  | void test_nocrash3(); | 
|  |  | 
|  | /// Foo | 
|  | template <typename, typename> | 
|  | void test_nocrash4() { } | 
|  |  | 
|  | template <typename> | 
|  | void test_nocrash3() | 
|  | { | 
|  | } | 
|  |  | 
|  | // PR13593, example 3 | 
|  |  | 
|  | /** | 
|  | * aaa | 
|  | */ | 
|  | template <typename T> | 
|  | inline T test_nocrash5(T a1) | 
|  | { | 
|  | return a1; | 
|  | } | 
|  |  | 
|  | /// | 
|  | //, | 
|  |  | 
|  | inline void test_nocrash6() | 
|  | { | 
|  | test_nocrash5(1); | 
|  | } | 
|  |  | 
|  | // We used to crash on this. | 
|  |  | 
|  | /*! | 
|  | Blah. | 
|  | */ | 
|  | typedef const struct test_nocrash7 * test_nocrash8; | 
|  |  | 
|  | // We used to crash on this. | 
|  |  | 
|  | // expected-warning@+1 {{unknown command tag name}} | 
|  | /// aaa \unknown aaa \unknown aaa | 
|  | int test_nocrash9; | 
|  |  | 
|  | // We used to crash on this.  PR15068 | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '@param' command}} | 
|  | // expected-warning@+2 {{empty paragraph passed to '@param' command}} | 
|  | ///@param x | 
|  | ///@param y | 
|  | int test_nocrash10(int x, int y); | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '@param' command}} expected-warning@+2 {{parameter 'x' not found in the function declaration}} | 
|  | // expected-warning@+2 {{empty paragraph passed to '@param' command}} expected-warning@+2 {{parameter 'y' not found in the function declaration}} | 
|  | ///@param x | 
|  | ///@param y | 
|  | int test_nocrash11(); | 
|  |  | 
|  | // expected-warning@+3 {{empty paragraph passed to '@param' command}} expected-warning@+3 {{parameter 'x' not found in the function declaration}} | 
|  | // expected-warning@+3 {{empty paragraph passed to '@param' command}} expected-warning@+3 {{parameter 'y' not found in the function declaration}} | 
|  | /** | 
|  | @param x | 
|  | @param y | 
|  | **/ | 
|  | int test_nocrash12(); | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '@param' command}} | 
|  | // expected-warning@+1 {{empty paragraph passed to '@param' command}} | 
|  | ///@param x@param y | 
|  | int test_nocrash13(int x, int y); | 
|  |  | 
|  | /** | 
|  | * \verbatim | 
|  | * Aaa | 
|  | **/ | 
|  | int test_nocrash14(); | 
|  |  | 
|  | // expected-warning@+2 {{'@union' command should not be used in a comment attached to a non-union declaration}} | 
|  | /*! | 
|  | @union U This is new | 
|  | */ | 
|  | struct U { int iS; }; | 
|  |  | 
|  | /*! | 
|  | @union U1 | 
|  | */ | 
|  | union U1 {int i; }; | 
|  |  | 
|  | // expected-warning@+2 {{'@struct' command should not be used in a comment attached to a non-struct declaration}} | 
|  | /*! | 
|  | @struct S2 | 
|  | */ | 
|  | union S2 {}; | 
|  |  | 
|  | /*! | 
|  | @class C1 | 
|  | */ | 
|  | class C1; | 
|  |  | 
|  | /*! | 
|  | @struct S3; | 
|  | */ | 
|  | class S3; | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | /// @class Predicate Predicate.h "lldb/Host/Predicate.h" | 
|  | /// @brief A C++ wrapper class for providing threaded access to a value | 
|  | /// of type T. | 
|  | /// | 
|  | /// A templatized class. | 
|  | /// specified values. | 
|  | //---------------------------------------------------------------------- | 
|  | template <class T, class T1> | 
|  | class Predicate | 
|  | { | 
|  | }; | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | /// @class Predicate<int, char> Predicate.h "lldb/Host/Predicate.h" | 
|  | /// @brief A C++ wrapper class for providing threaded access to a value | 
|  | /// of type T. | 
|  | /// | 
|  | /// A template specialization class. | 
|  | //---------------------------------------------------------------------- | 
|  | template<> class Predicate<int, char> | 
|  | { | 
|  | }; | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | /// @class Predicate<T, int> Predicate.h "lldb/Host/Predicate.h" | 
|  | /// @brief A C++ wrapper class for providing threaded access to a value | 
|  | /// of type T. | 
|  | /// | 
|  | /// A partial specialization template class. | 
|  | //---------------------------------------------------------------------- | 
|  | template<class T> class Predicate<T, int> | 
|  | { | 
|  | }; | 
|  |  | 
|  | /*!     @function test_function | 
|  | */ | 
|  | template <class T> T test_function (T arg); | 
|  |  | 
|  | /*!     @function test_function<int> | 
|  | */ | 
|  | template <> int test_function<int> (int arg); | 
|  |  | 
|  | namespace AllowParamAndReturnsOnFunctionPointerVars { | 
|  |  | 
|  | /** | 
|  | * functionPointerVariable | 
|  | * | 
|  | * @param i is integer. | 
|  | * @returns integer. | 
|  | */ | 
|  | int (*functionPointerVariable)(int i); | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | /** | 
|  | * functionPointerVariableTemplate | 
|  | * | 
|  | * @param i is something. | 
|  | * @returns integer. | 
|  | */ | 
|  | template<typename T> | 
|  | int (*functionPointerVariableTemplate)(T i); | 
|  | #endif | 
|  |  | 
|  | struct HasFields { | 
|  | /** | 
|  | * functionPointerField | 
|  | * | 
|  | * @param i is integer. | 
|  | * @returns integer. | 
|  | */ | 
|  | int (*functionPointerField)(int i); | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | /** | 
|  | * functionPointerTemplateMember | 
|  | * | 
|  | * @tparam T some type. | 
|  | * @param i is integer. | 
|  | * @returns integer. | 
|  | */ | 
|  | template<typename T> | 
|  | static int (*functionPointerTemplateMember)(int i); | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | // expected-warning@+5 {{parameter 'p' not found in the function declaration}} | 
|  | // expected-warning@+5 {{'\returns' command used in a comment that is attached to a function returning void}} | 
|  | /** | 
|  | * functionPointerVariable | 
|  | * | 
|  | * \param p not here. | 
|  | * \returns integer. | 
|  | */ | 
|  | void (*functionPointerVariableThatLeadsNowhere)(); | 
|  |  | 
|  | #if __cplusplus >= 201402L | 
|  | // expected-warning@+8 {{template parameter 'X' not found in the template declaration}} | 
|  | // expected-note@+7 {{did you mean 'T'?}} | 
|  | // expected-warning@+7 {{parameter 'p' not found in the function declaration}} | 
|  | // expected-note@+6 {{did you mean 'x'?}} | 
|  | // expected-warning@+6 {{'\returns' command used in a comment that is attached to a function returning void}} | 
|  | /** | 
|  | * functionPointerVariable | 
|  | * | 
|  | * \tparam X typo | 
|  | * \param p not here. | 
|  | * \returns integer. | 
|  | */ | 
|  | template<typename T> | 
|  | void (*functionPointerVariableTemplateThatLeadsNowhere)(T x); | 
|  | #endif | 
|  |  | 
|  | // Still warn about param/returns commands for variables that don't specify | 
|  | // the type directly: | 
|  |  | 
|  | /** | 
|  | * FunctionPointerTypedef | 
|  | * | 
|  | * \param i is integer. | 
|  | * \returns integer. | 
|  | */ | 
|  | typedef int (*FunctionPointerTypedef)(int i); | 
|  |  | 
|  | /** | 
|  | * FunctionPointerTypealias | 
|  | * | 
|  | * \param i is integer. | 
|  | * \returns integer. | 
|  | */ | 
|  | using FunctionPointerTypealias = int (*)(int i); | 
|  |  | 
|  | // expected-warning@+5 {{'@param' command used in a comment that is not attached to a function declaration}} | 
|  | // expected-warning@+5 {{'@returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /** | 
|  | * functionPointerVariable | 
|  | * | 
|  | * @param i is integer. | 
|  | * @returns integer. | 
|  | */ | 
|  | FunctionPointerTypedef functionPointerTypedefVariable; | 
|  |  | 
|  | struct HasMoreFields { | 
|  | // expected-warning@+5 {{'\param' command used in a comment that is not attached to a function declaration}} | 
|  | // expected-warning@+5 {{'\returns' command used in a comment that is not attached to a function or method declaration}} | 
|  | /** | 
|  | * functionPointerTypealiasField | 
|  | * | 
|  | * \param i is integer. | 
|  | * \returns integer. | 
|  | */ | 
|  | FunctionPointerTypealias functionPointerTypealiasField; | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | /*! | 
|  | * Function pointer typedef with variadic params. | 
|  | * | 
|  | * @param a | 
|  | * works | 
|  | * | 
|  | * @param ... | 
|  | * now should work too. | 
|  | */ | 
|  | typedef void (*VariadicFnType)(int a, ...); | 
|  |  | 
|  | /*! | 
|  | * Function pointer type alias with variadic params. | 
|  | * | 
|  | * @param a | 
|  | * works | 
|  | * | 
|  | * @param ... | 
|  | * now should work too. | 
|  | */ | 
|  | using VariadicFnType2 = void (*)(int a, ...); | 
|  |  | 
|  | /*! | 
|  | * Function pointer type variable. | 
|  | * | 
|  | * @param a | 
|  | * works | 
|  | * | 
|  | * @param ... | 
|  | * now should work too. | 
|  | */ | 
|  | void (*variadicFnVar)(int a, ...); | 
|  |  | 
|  | // expected-warning@+2 {{empty paragraph passed to '@note' command}} | 
|  | /** | 
|  | @note | 
|  | \f$\texttt{mu}_{00}=\texttt{m}_{00}\f$, \f$\texttt{nu}_{00}=1\f$ | 
|  | \f$\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0\f$ | 
|  | */ | 
|  | class EmptyNoteNoCrash { | 
|  | }; | 
|  |  | 
|  | namespace PR42844 { // Assertion failures when using typedefed function pointers | 
|  | typedef void (*AA)(); | 
|  | typedef AA A(); | 
|  | A *a; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | typedef void B(); | 
|  | B *b; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | void CC(); | 
|  | typedef void C(); | 
|  | C &c = CC; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | using DD = void(*)(); | 
|  | using D = DD(); | 
|  | D *d; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | using E = void(); | 
|  | E *e; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | void FF(); | 
|  | using F = void(); | 
|  | F &f = FF; ///< \return none | 
|  | // expected-warning@-1 {{'\return' command used in a comment that is not attached to a function or method declaration}} | 
|  |  | 
|  | } // namespace PR42844 |