@@ -545,3 +545,313 @@ TEST(Decl, TemplateArgumentDefaulted) {
545
545
EXPECT_TRUE (ArgList.get (2 ).getIsDefaulted ());
546
546
EXPECT_TRUE (ArgList.get (3 ).getIsDefaulted ());
547
547
}
548
+
549
+ TEST (Decl, CommentsAttachedToDecl1) {
550
+ const SmallVector<StringRef> Sources{
551
+ R"(
552
+ /// Test comment
553
+ void f();
554
+ )" ,
555
+
556
+ R"(
557
+ /// Test comment
558
+
559
+ void f();
560
+ )" ,
561
+
562
+ R"(
563
+ /// Test comment
564
+ #if 0
565
+ // tralala
566
+ #endif
567
+ void f();
568
+ )" ,
569
+
570
+ R"(
571
+ /// Test comment
572
+
573
+ #if 0
574
+ // tralala
575
+ #endif
576
+
577
+ void f();
578
+ )" ,
579
+
580
+ R"(
581
+ /// Test comment
582
+ #ifdef DOCS
583
+ template<typename T>
584
+ #endif
585
+ void f();
586
+ )" ,
587
+
588
+ R"(
589
+ /// Test comment
590
+
591
+ #ifdef DOCS
592
+ template<typename T>
593
+ #endif
594
+
595
+ void f();
596
+ )" ,
597
+ };
598
+
599
+ for (const auto code : Sources) {
600
+ auto AST = tooling::buildASTFromCodeWithArgs (code, /* Args=*/ {" -std=c++20" });
601
+ ASTContext &Ctx = AST->getASTContext ();
602
+
603
+ auto const *F = selectFirst<FunctionDecl>(
604
+ " id" , match (functionDecl (hasName (" f" )).bind (" id" ), Ctx));
605
+ ASSERT_NE (F, nullptr );
606
+
607
+ auto const *C = Ctx.getRawCommentForDeclNoCache (F);
608
+ ASSERT_NE (C, nullptr );
609
+ EXPECT_EQ (C->getRawText (Ctx.getSourceManager ()), " /// Test comment" );
610
+ }
611
+ }
612
+
613
+ TEST (Decl, CommentsAttachedToDecl2) {
614
+ const SmallVector<StringRef> Sources{
615
+ R"(
616
+ /** Test comment
617
+ */
618
+ void f();
619
+ )" ,
620
+
621
+ R"(
622
+ /** Test comment
623
+ */
624
+
625
+ void f();
626
+ )" ,
627
+
628
+ R"(
629
+ /** Test comment
630
+ */
631
+ #if 0
632
+ /* tralala */
633
+ #endif
634
+ void f();
635
+ )" ,
636
+
637
+ R"(
638
+ /** Test comment
639
+ */
640
+
641
+ #if 0
642
+ /* tralala */
643
+ #endif
644
+
645
+ void f();
646
+ )" ,
647
+
648
+ R"(
649
+ /** Test comment
650
+ */
651
+ #ifdef DOCS
652
+ template<typename T>
653
+ #endif
654
+ void f();
655
+ )" ,
656
+
657
+ R"(
658
+ /** Test comment
659
+ */
660
+
661
+ #ifdef DOCS
662
+ template<typename T>
663
+ #endif
664
+
665
+ void f();
666
+ )" ,
667
+ };
668
+
669
+ for (const auto code : Sources) {
670
+ auto AST = tooling::buildASTFromCodeWithArgs (code, /* Args=*/ {" -std=c++20" });
671
+ ASTContext &Ctx = AST->getASTContext ();
672
+
673
+ auto const *F = selectFirst<FunctionDecl>(
674
+ " id" , match (functionDecl (hasName (" f" )).bind (" id" ), Ctx));
675
+ ASSERT_NE (F, nullptr );
676
+
677
+ auto const *C = Ctx.getRawCommentForDeclNoCache (F);
678
+ ASSERT_NE (C, nullptr );
679
+ EXPECT_EQ (C->getRawText (Ctx.getSourceManager ()),
680
+ " /** Test comment\n */" );
681
+ }
682
+ }
683
+
684
+ TEST (Decl, CommentsAttachedToDecl3) {
685
+ const SmallVector<StringRef> Sources{
686
+ R"(
687
+ /// @brief Test comment
688
+ void f();
689
+ )" ,
690
+
691
+ R"(
692
+ /// @brief Test comment
693
+
694
+ void f();
695
+ )" ,
696
+
697
+ R"(
698
+ /// @brief Test comment
699
+ #if 0
700
+ // tralala
701
+ #endif
702
+ void f();
703
+ )" ,
704
+
705
+ R"(
706
+ /// @brief Test comment
707
+
708
+ #if 0
709
+ // tralala
710
+ #endif
711
+
712
+ void f();
713
+ )" ,
714
+
715
+ R"(
716
+ /// @brief Test comment
717
+ #ifdef DOCS
718
+ template<typename T>
719
+ #endif
720
+ void f();
721
+ )" ,
722
+
723
+ R"(
724
+ /// @brief Test comment
725
+
726
+ #ifdef DOCS
727
+ template<typename T>
728
+ #endif
729
+
730
+ void f();
731
+ )" ,
732
+ };
733
+
734
+ for (const auto code : Sources) {
735
+ auto AST = tooling::buildASTFromCodeWithArgs (code, /* Args=*/ {" -std=c++20" });
736
+ ASTContext &Ctx = AST->getASTContext ();
737
+
738
+ auto const *F = selectFirst<FunctionDecl>(
739
+ " id" , match (functionDecl (hasName (" f" )).bind (" id" ), Ctx));
740
+ ASSERT_NE (F, nullptr );
741
+
742
+ auto const *C = Ctx.getRawCommentForDeclNoCache (F);
743
+ ASSERT_NE (C, nullptr );
744
+ EXPECT_EQ (C->getRawText (Ctx.getSourceManager ()), " /// @brief Test comment" );
745
+ }
746
+ }
747
+
748
+ TEST (Decl, CommentsAttachedToDecl4) {
749
+ const SmallVector<StringRef> Sources{
750
+ R"(
751
+ /** \brief Test comment
752
+ */
753
+ void f();
754
+ )" ,
755
+
756
+ R"(
757
+ /** \brief Test comment
758
+ */
759
+
760
+ void f();
761
+ )" ,
762
+
763
+ R"(
764
+ /** \brief Test comment
765
+ */
766
+ #if 0
767
+ /* tralala */
768
+ #endif
769
+ void f();
770
+ )" ,
771
+
772
+ R"(
773
+ /** \brief Test comment
774
+ */
775
+
776
+ #if 0
777
+ /* tralala */
778
+ #endif
779
+
780
+ void f();
781
+ )" ,
782
+
783
+ R"(
784
+ /** \brief Test comment
785
+ */
786
+ #ifdef DOCS
787
+ template<typename T>
788
+ #endif
789
+ void f();
790
+ )" ,
791
+
792
+ R"(
793
+ /** \brief Test comment
794
+ */
795
+
796
+ #ifdef DOCS
797
+ template<typename T>
798
+ #endif
799
+
800
+ void f();
801
+ )" ,
802
+ };
803
+
804
+ for (const auto code : Sources) {
805
+ auto AST = tooling::buildASTFromCodeWithArgs (code, /* Args=*/ {" -std=c++20" });
806
+ ASTContext &Ctx = AST->getASTContext ();
807
+
808
+ auto const *F = selectFirst<FunctionDecl>(
809
+ " id" , match (functionDecl (hasName (" f" )).bind (" id" ), Ctx));
810
+ ASSERT_NE (F, nullptr );
811
+
812
+ auto const *C = Ctx.getRawCommentForDeclNoCache (F);
813
+ ASSERT_NE (C, nullptr );
814
+ EXPECT_EQ (C->getRawText (Ctx.getSourceManager ()),
815
+ " /** \\ brief Test comment\n */" );
816
+ }
817
+ }
818
+
819
+ // / This example intentionally inserts characters between a doc comment and the
820
+ // / associated declaration to verify that the comment does not become associated
821
+ // / with the FunctionDecl.
822
+ // / By default, Clang does not allow for other declarations (aside from
823
+ // / preprocessor directives, as shown above) to be placed between a doc comment
824
+ // / and a declaration.
825
+ TEST (Decl, CommentsAttachedToDecl5) {
826
+ const SmallVector<StringRef> Sources{
827
+ R"(
828
+ /// Test comment
829
+ ;
830
+ void f();
831
+ )" ,
832
+
833
+ R"(
834
+ /// Test comment
835
+ // @
836
+ void f();
837
+ )" ,
838
+
839
+ R"(
840
+ /// Test comment
841
+ // {}
842
+ void f();
843
+ )" ,
844
+ };
845
+
846
+ for (const auto code : Sources) {
847
+ auto AST = tooling::buildASTFromCodeWithArgs (code, /* Args=*/ {" -std=c++20" });
848
+ ASTContext &Ctx = AST->getASTContext ();
849
+
850
+ auto const *F = selectFirst<FunctionDecl>(
851
+ " id" , match (functionDecl (hasName (" f" )).bind (" id" ), Ctx));
852
+ ASSERT_NE (F, nullptr );
853
+
854
+ auto const *C = Ctx.getRawCommentForDeclNoCache (F);
855
+ ASSERT_EQ (C, nullptr );
856
+ }
857
+ }
0 commit comments