1 | //===- unittests/AST/RawCommentForDeclTestTest.cpp |
2 | //-------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "clang/AST/ASTConsumer.h" |
11 | #include "clang/AST/DeclGroup.h" |
12 | #include "clang/Frontend/CompilerInstance.h" |
13 | #include "clang/Frontend/FrontendAction.h" |
14 | #include "clang/Tooling/Tooling.h" |
15 | |
16 | #include "gmock/gmock-matchers.h" |
17 | #include "gtest/gtest.h" |
18 | |
19 | namespace clang { |
20 | |
21 | struct { |
22 | std::string ; |
23 | bool ; |
24 | std::string ; |
25 | |
26 | bool (const FoundComment &RHS) const { |
27 | return DeclName == RHS.DeclName && IsDefinition == RHS.IsDefinition && |
28 | Comment == RHS.Comment; |
29 | } |
30 | friend llvm::raw_ostream &(llvm::raw_ostream &Stream, |
31 | const FoundComment &C) { |
32 | return Stream << "{Name: " << C.DeclName << ", Def: " << C.IsDefinition |
33 | << ", Comment: " << C.Comment << "}" ; |
34 | } |
35 | }; |
36 | |
37 | class : public ASTFrontendAction { |
38 | public: |
39 | (std::vector<FoundComment> &) |
40 | : Comments(Comments) {} |
41 | |
42 | std::unique_ptr<ASTConsumer> (CompilerInstance &CI, |
43 | llvm::StringRef) override { |
44 | CI.getLangOpts().CommentOpts.ParseAllComments = true; |
45 | return std::make_unique<Consumer>(args&: *this); |
46 | } |
47 | |
48 | std::vector<FoundComment> &; |
49 | |
50 | private: |
51 | class : public clang::ASTConsumer { |
52 | private: |
53 | CollectCommentsAction &; |
54 | |
55 | public: |
56 | (CollectCommentsAction &Action) : Action(Action) {} |
57 | |
58 | bool HandleTopLevelDecl(DeclGroupRef DG) override { |
59 | for (Decl *D : DG) { |
60 | if (NamedDecl *ND = dyn_cast<NamedDecl>(Val: D)) { |
61 | auto &Ctx = D->getASTContext(); |
62 | const auto *RC = Ctx.getRawCommentForAnyRedecl(D); |
63 | Action.Comments.push_back(x: FoundComment{ |
64 | .DeclName: ND->getNameAsString(), .IsDefinition: IsDefinition(D), |
65 | .Comment: RC ? RC->getRawText(SourceMgr: Ctx.getSourceManager()).str() : "" }); |
66 | } |
67 | } |
68 | |
69 | return true; |
70 | } |
71 | |
72 | static bool (const Decl *D) { |
73 | if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Val: D)) { |
74 | return FD->isThisDeclarationADefinition(); |
75 | } |
76 | if (const TagDecl *TD = dyn_cast<TagDecl>(Val: D)) { |
77 | return TD->isThisDeclarationADefinition(); |
78 | } |
79 | return false; |
80 | } |
81 | }; |
82 | }; |
83 | |
84 | TEST(RawCommentForDecl, DefinitionComment) { |
85 | std::vector<FoundComment> ; |
86 | auto Action = std::make_unique<CollectCommentsAction>(args&: Comments); |
87 | ASSERT_TRUE(tooling::runToolOnCode(std::move(Action), R"cpp( |
88 | void f(); |
89 | |
90 | // f is the best |
91 | void f() {} |
92 | )cpp" )); |
93 | EXPECT_THAT(Comments, testing::ElementsAre( |
94 | FoundComment{"f" , false, "" }, |
95 | FoundComment{"f" , true, "// f is the best" })); |
96 | } |
97 | |
98 | } // namespace clang |
99 | |