1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s
2 
3 // This file contains lots of corner cases, so ensure that XML we generate is not invalid.
4 // RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG
5 // WRONG-NOT: CommentXMLInvalid
6 
7 // expected-warning@+1 {{expected quoted string after equals sign}}
8 /// <a href=>
9 int test_html1(int);
10 
11 // expected-warning@+1 {{expected quoted string after equals sign}}
12 /// <a href==>
13 int test_html2(int);
14 
15 // expected-warning@+2 {{expected quoted string after equals sign}}
16 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
17 /// <a href= blah
18 int test_html3(int);
19 
20 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
21 /// <a =>
22 int test_html4(int);
23 
24 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
25 /// <a "aaa">
26 int test_html5(int);
27 
28 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
29 /// <a a="b" =>
30 int test_html6(int);
31 
32 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
33 /// <a a="b" "aaa">
34 int test_html7(int);
35 
36 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
37 /// <a a="b" =
38 int test_html8(int);
39 
40 // expected-warning@+2 {{HTML start tag prematurely ended, expected attribute name or '>'}} expected-note@+1 {{HTML tag started here}}
41 /** Aaa bbb<ccc ddd eee
42  * fff ggg.
43  */
44 int test_html9(int);
45 
46 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
47 /** Aaa bbb<ccc ddd eee 42%
48  * fff ggg.
49  */
50 int test_html10(int);
51 
52 // expected-warning@+1 {{HTML end tag 'br' is forbidden}}
53 /// <br></br>
54 int test_html11(int);
55 
56 /// <blockquote>Meow</blockquote>
57 int test_html_nesting1(int);
58 
59 /// <b><i>Meow</i></b>
60 int test_html_nesting2(int);
61 
62 /// <p>Aaa<br>
63 /// Bbb</p>
64 int test_html_nesting3(int);
65 
66 /// <p>Aaa<br />
67 /// Bbb</p>
68 int test_html_nesting4(int);
69 
70 // expected-warning@+1 {{HTML end tag does not match any start tag}}
71 /// <b><i>Meow</a>
72 int test_html_nesting5(int);
73 
74 // expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
75 // expected-warning@+1 {{HTML end tag does not match any start tag}}
76 /// <b><i>Meow</b></b>
77 int test_html_nesting6(int);
78 
79 // expected-warning@+2 {{HTML start tag 'i' closed by 'b'}}
80 // expected-warning@+1 {{HTML end tag does not match any start tag}}
81 /// <b><i>Meow</b></i>
82 int test_html_nesting7(int);
83 
84 
85 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
86 /// \brief\returns Aaa
87 int test_block_command1(int);
88 
89 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
90 /// \brief \returns Aaa
91 int test_block_command2(int);
92 
93 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
94 /// \brief
95 /// \returns Aaa
96 int test_block_command3(int);
97 
98 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
99 /// \brief
100 ///
101 /// \returns Aaa
102 int test_block_command4(int);
103 
104 // There is trailing whitespace on one of the following lines, don't remove it!
105 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
106 /// \brief
107 ///
108 /// \returns Aaa
109 int test_block_command5(int);
110 
111 /// \brief \c Aaa
112 int test_block_command6(int);
113 
114 // expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\brief' here}}
115 /// \brief Aaa
116 ///
117 /// Bbb
118 ///
119 /// \brief Ccc
120 int test_duplicate_brief1(int);
121 
122 // expected-warning@+5 {{duplicated command '\short'}} expected-note@+1 {{previous command '\short' here}}
123 /// \short Aaa
124 ///
125 /// Bbb
126 ///
127 /// \short Ccc
128 int test_duplicate_brief2(int);
129 
130 // expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\short' (an alias of '\brief') here}}
131 /// \short Aaa
132 ///
133 /// Bbb
134 ///
135 /// \brief Ccc
136 int test_duplicate_brief3(int);
137 
138 
139 // expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\return' here}}
140 /// \return Aaa
141 ///
142 /// Bbb
143 ///
144 /// \return Ccc
145 int test_duplicate_returns1(int);
146 
147 // expected-warning@+5 {{duplicated command '\returns'}} expected-note@+1 {{previous command '\returns' here}}
148 /// \returns Aaa
149 ///
150 /// Bbb
151 ///
152 /// \returns Ccc
153 int test_duplicate_returns2(int);
154 
155 // expected-warning@+5 {{duplicated command '\result'}} expected-note@+1 {{previous command '\result' here}}
156 /// \result Aaa
157 ///
158 /// Bbb
159 ///
160 /// \result Ccc
161 int test_duplicate_returns3(int);
162 
163 // expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\returns' (an alias of '\return') here}}
164 /// \returns Aaa
165 ///
166 /// Bbb
167 ///
168 /// \return Ccc
169 int test_duplicate_returns4(int);
170 
171 
172 // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
173 /// \param a Blah blah.
174 int test_param1;
175 
176 // expected-warning@+1 {{empty paragraph passed to '\param' command}}
177 /// \param
178 /// \param a Blah blah.
179 int test_param2(int a);
180 
181 // expected-warning@+1 {{empty paragraph passed to '\param' command}}
182 /// \param a
183 int test_param3(int a);
184 
185 /// \param a Blah blah.
186 int test_param4(int a);
187 
188 /// \param [in] a Blah blah.
189 int test_param5(int a);
190 
191 /// \param [out] a Blah blah.
192 int test_param6(int a);
193 
194 /// \param [in,out] a Blah blah.
195 int test_param7(int a);
196 
197 // expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
198 /// \param [ in ] a Blah blah.
199 int test_param8(int a);
200 
201 // expected-warning@+1 {{whitespace is not allowed in parameter passing direction}}
202 /// \param [in, out] a Blah blah.
203 int test_param9(int a);
204 
205 // expected-warning@+1 {{unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'}}
206 /// \param [ junk] a Blah blah.
207 int test_param10(int a);
208 
209 // expected-warning@+1 {{parameter 'a' not found in the function declaration}}
210 /// \param a Blah blah.
211 int test_param11();
212 
213 // expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
214 /// \param A Blah blah.
215 int test_param12(int a);
216 
217 // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
218 /// \param aab Blah blah.
219 int test_param13(int aaa, int bbb);
220 
221 // expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
222 /// \param aab Blah blah.
223 int test_param14(int bbb, int ccc);
224 
225 class C {
226   // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
227   /// \param aaa Blah blah.
228   C(int bbb, int ccc);
229 
230   // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
231   /// \param aaa Blah blah.
232  int test_param15(int bbb, int ccc);
233 };
234 
235 // expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
236 /// \param aab Blah blah.
237 template<typename T>
238 void test_param16(int bbb, int ccc);
239 
240 // expected-warning@+3 {{parameter 'a' is already documented}}
241 // expected-note@+1 {{previous documentation}}
242 /// \param a Aaa.
243 /// \param a Aaa.
244 int test_param17(int a);
245 
246 // expected-warning@+4 {{parameter 'x2' is already documented}}
247 // expected-note@+2 {{previous documentation}}
248 /// \param x1 Aaa.
249 /// \param x2 Bbb.
250 /// \param x2 Ccc.
251 int test_param18(int x1, int x2, int x3);
252 
253 
254 // expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
255 /// \tparam T Aaa
256 int test_tparam1;
257 
258 // expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
259 /// \tparam T Aaa
260 void test_tparam2(int aaa);
261 
262 // expected-warning@+1 {{empty paragraph passed to '\tparam' command}}
263 /// \tparam
264 /// \param aaa Blah blah
265 template<typename T>
266 void test_tparam3(T aaa);
267 
268 // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}}
269 /// \tparam T Aaa
270 template<typename TT>
271 void test_tparam4(TT aaa);
272 
273 // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}}
274 /// \tparam T Aaa
275 template<typename TT>
276 class test_tparam5 {
277   // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TTT'?}}
278   /// \tparam T Aaa
279   template<typename TTT>
280   void test_tparam6(TTT aaa);
281 };
282 
283 /// \tparam T1 Aaa
284 /// \tparam T2 Bbb
285 template<typename T1, typename T2>
286 void test_tparam7(T1 aaa, T2 bbb);
287 
288 // expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}}
289 /// \tparam SomTy Aaa
290 /// \tparam OtherTy Bbb
291 template<typename SomeTy, typename OtherTy>
292 void test_tparam8(SomeTy aaa, OtherTy bbb);
293 
294 // expected-warning@+2 {{template parameter 'T1' is already documented}} expected-note@+1 {{previous documentation}}
295 /// \tparam T1 Aaa
296 /// \tparam T1 Bbb
297 template<typename T1, typename T2>
298 void test_tparam9(T1 aaa, T2 bbb);
299 
300 /// \tparam T Aaa
301 /// \tparam TT Bbb
302 template<template<typename T> class TT>
303 void test_tparam10(TT<int> aaa);
304 
305 /// \tparam T Aaa
306 /// \tparam TT Bbb
307 /// \tparam TTT Ccc
308 template<template<template<typename T> class TT, class C> class TTT>
309 void test_tparam11();
310 
311 /// \tparam I Aaa
312 template<int I>
313 void test_tparam12();
314 
315 template<typename T, typename U>
316 class test_tparam13 { };
317 
318 /// \tparam T Aaa
319 template<typename T>
320 using test_tparam14 = test_tparam13<T, int>;
321 
322 // expected-warning@+1 {{template parameter 'U' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}}
323 /// \tparam U Aaa
324 template<typename T>
325 using test_tparam15 = test_tparam13<T, int>;
326 
327 // no-warning
328 /// \returns Aaa
329 int test_returns_right_decl_1(int);
330 
331 class test_returns_right_decl_2 {
332   // no-warning
333   /// \returns Aaa
334   int test_returns_right_decl_3(int);
335 };
336 
337 // no-warning
338 /// \returns Aaa
339 template<typename T>
340 int test_returns_right_decl_4(T aaa);
341 
342 // no-warning
343 /// \returns Aaa
344 template<>
345 int test_returns_right_decl_4(int aaa);
346 
347 /// \returns Aaa
348 template<typename T>
349 T test_returns_right_decl_5(T aaa);
350 
351 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
352 /// \returns Aaa
353 int test_returns_wrong_decl_1;
354 
355 // expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}}
356 /// \return Aaa
357 int test_returns_wrong_decl_2;
358 
359 // expected-warning@+1 {{'\result' command used in a comment that is not attached to a function or method declaration}}
360 /// \result Aaa
361 int test_returns_wrong_decl_3;
362 
363 // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
364 /// \returns Aaa
365 void test_returns_wrong_decl_4(int);
366 
367 // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
368 /// \returns Aaa
369 template<typename T>
370 void test_returns_wrong_decl_5(T aaa);
371 
372 // expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
373 /// \returns Aaa
374 template<>
375 void test_returns_wrong_decl_5(int aaa);
376 
377 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
378 /// \returns Aaa
379 struct test_returns_wrong_decl_6 { };
380 
381 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
382 /// \returns Aaa
383 class test_returns_wrong_decl_7 {
384   // expected-warning@+1 {{'\returns' command used in a comment that is attached to a constructor}}
385   /// \returns Aaa
386   test_returns_wrong_decl_7();
387 
388   // expected-warning@+1 {{'\returns' command used in a comment that is attached to a destructor}}
389   /// \returns Aaa
390   ~test_returns_wrong_decl_7();
391 };
392 
393 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
394 /// \returns Aaa
395 enum test_returns_wrong_decl_8 {
396   // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
397   /// \returns Aaa
398   test_returns_wrong_decl_9
399 };
400 
401 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
402 /// \returns Aaa
403 namespace test_returns_wrong_decl_10 { };
404 
405 
406 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
407 int test1; ///< \brief\author Aaa
408 
409 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
410 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
411 int test2, ///< \brief\author Aaa
412     test3; ///< \brief\author Aaa
413 
414 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
415 int test4; ///< \brief
416            ///< \author Aaa
417 
418 
419 // Check that we attach the comment to the declaration during parsing in the
420 // following cases.  The test is based on the fact that we don't parse
421 // documentation comments that are not attached to anything.
422 
423 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
424 /// \brief\author Aaa
425 int test_attach1;
426 
427 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
428 /// \brief\author Aaa
429 int test_attach2(int);
430 
431 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
432 /// \brief\author Aaa
433 struct test_attach3 {
434   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
435   /// \brief\author Aaa
436   int test_attach4;
437 
438   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
439   int test_attach5; ///< \brief\author Aaa
440 
441   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
442   /// \brief\author Aaa
443   int test_attach6(int);
444 };
445 
446 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
447 /// \brief\author Aaa
448 class test_attach7 {
449   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
450   /// \brief\author Aaa
451   int test_attach8;
452 
453   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
454   int test_attach9; ///< \brief\author Aaa
455 
456   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
457   /// \brief\author Aaa
458   int test_attach10(int);
459 };
460 
461 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
462 /// \brief\author Aaa
463 enum test_attach9 {
464   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
465   /// \brief\author Aaa
466   test_attach10,
467 
468   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
469   test_attach11 ///< \brief\author Aaa
470 };
471 
472 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
473 /// \brief\author Aaa
474 struct test_noattach12 *test_attach13;
475 
476 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
477 /// \brief\author Aaa
478 typedef struct test_noattach14 *test_attach15;
479 
480 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
481 /// \brief\author Aaa
482 typedef struct test_attach16 { int a; } test_attach17;
483 
484 struct S { int a; };
485 
486 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
487 /// \brief\author Aaa
488 struct S *test_attach18;
489 
490 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
491 /// \brief\author Aaa
492 typedef struct S *test_attach19;
493 
494 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
495 /// \brief\author Aaa
496 struct test_attach20;
497 
498 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
499 /// \brief\author Aaa
500 typedef struct test_attach21 {
501   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
502   /// \brief\author Aaa
503   int test_attach22;
504 } test_attach23;
505 
506 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
507 /// \brief\author Aaa
508 namespace test_attach24 {
509   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
510   /// \brief\author Aaa
511   namespace test_attach25 {
512   }
513 }
514 
515 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
516 /// \brief\author Aaa
517 /// \tparam T Aaa
518 template<typename T>
519 void test_attach26(T aaa);
520 
521 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
522 /// \brief\author Aaa
523 /// \tparam T Aaa
524 template<typename T, typename U>
525 void test_attach27(T aaa, U bbb);
526 
527 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
528 // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
529 /// \brief\author Aaa
530 /// \tparam T Aaa
531 template<>
532 void test_attach27(int aaa, int bbb);
533 
534 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
535 /// \brief\author Aaa
536 /// \tparam T Aaa
537 template<typename T>
538 class test_attach28 {
539   T aaa;
540 };
541 
542 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
543 /// \brief\author Aaa
544 using test_attach29 = test_attach28<int>;
545 
546 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
547 /// \brief\author Aaa
548 /// \tparam T Aaa
549 template<typename T, typename U>
550 class test_attach30 { };
551 
552 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
553 /// \brief\author Aaa
554 /// \tparam T Aaa
555 template<typename T>
556 class test_attach30<T, int> { };
557 
558 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
559 /// \brief\author Aaa
560 template<>
561 class test_attach30<int, int> { };
562 
563 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
564 /// \brief\author Aaa
565 template<typename T>
566 using test_attach31 = test_attach30<T, int>;
567 
568 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
569 /// \brief\author Aaa
570 /// \tparam T Aaa
571 template<typename T, typename U, typename V>
572 class test_attach32 { };
573 
574 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
575 /// \brief\author Aaa
576 /// \tparam T Aaa
577 template<typename T, typename U>
578 class test_attach32<T, U, int> { };
579 
580 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
581 /// \brief\author Aaa
582 /// \tparam T Aaa
583 template<typename T>
584 class test_attach32<T, int, int> { };
585 
586 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
587 // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
588 /// \brief\author Aaa
589 /// \tparam T Aaa
590 template<>
591 class test_attach32<int, int, int> { };
592 
593 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
594 /// \brief\author Aaa
595 class test_attach33 {
596   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
597   /// \brief\author Aaa
598   /// \tparam T Aaa
599   template<typename T, typename U>
600   void test_attach34(T aaa, U bbb);
601 };
602 
603 template<typename T>
604 class test_attach35 {
605   // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
606   // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
607   /// \brief\author Aaa
608   /// \tparam T Aaa
609   template<typename TT, typename UU>
610   void test_attach36(TT aaa, UU bbb);
611 };
612 
613 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
614 // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
615 /// \brief\author Aaa
616 /// \tparam T Aaa
617 template<> template<>
618 void test_attach35<int>::test_attach36(int aaa, int bbb) {}
619 
620 template<typename T>
621 class test_attach37 {
622   // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
623   // expected-warning@+2 {{'\tparam' command used in a comment that is not attached to a template declaration}}
624   /// \brief\author Aaa
625   /// \tparam T Aaa
626   void test_attach38(int aaa, int bbb);
627 
628   void test_attach39(int aaa, int bbb);
629 };
630 
631 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
632 // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
633 /// \brief\author Aaa
634 /// \tparam T Aaa
635 template<>
636 void test_attach37<int>::test_attach38(int aaa, int bbb) {}
637 
638 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
639 /// \brief\author Aaa
640 /// \tparam T Aaa
641 template<typename T>
642 void test_attach37<T>::test_attach39(int aaa, int bbb) {}
643 
644 // We used to emit warning that parameter 'a' is not found because we parsed
645 // the comment in context of the redeclaration which does not have parameter
646 // names.
647 template <typename T>
648 struct test_attach38 {
649   /*!
650     \param a  First param
651     \param b  Second param
652   */
653   template <typename B>
654   void test_attach39(T a, B b);
655 };
656 
657 template <>
658 template <typename B>
659 void test_attach38<int>::test_attach39(int, B);
660 
661 
662 // PR13411, reduced.  We used to crash on this.
663 /**
664  * @code Aaa.
665  */
666 void test_nocrash1(int);
667 
668 // We used to crash on this.
669 // expected-warning@+2 {{empty paragraph passed to '\param' command}}
670 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
671 /// \param\brief
672 void test_nocrash2(int);
673 
674 // PR13593, example 1 and 2
675 
676 /**
677 * Bla.
678 */
679 template <typename>
680 void test_nocrash3();
681 
682 /// Foo
683 template <typename, typename>
684 void test_nocrash4() { }
685 
686 template <typename>
687 void test_nocrash3()
688 {
689 }
690 
691 // PR13593, example 3
692 
693 /**
694  * aaa
695  */
696 template <typename T>
697 inline T test_nocrash5(T a1)
698 {
699     return a1;
700 }
701 
702 ///
703 //,
704 
705 inline void test_nocrash6()
706 {
707     test_nocrash5(1);
708 }
709 
710 // We used to crash on this.
711 
712 /*!
713   Blah.
714 */
715 typedef const struct test_nocrash7 * test_nocrash8;
716 
717