99 lines · cpp
1//===- unittests/AST/RawCommentForDeclTestTest.cpp2//-------------------------===//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-exception7//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 19namespace clang {20 21struct FoundComment {22 std::string DeclName;23 bool IsDefinition;24 std::string Comment;25 26 bool operator==(const FoundComment &RHS) const {27 return DeclName == RHS.DeclName && IsDefinition == RHS.IsDefinition &&28 Comment == RHS.Comment;29 }30 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &Stream,31 const FoundComment &C) {32 return Stream << "{Name: " << C.DeclName << ", Def: " << C.IsDefinition33 << ", Comment: " << C.Comment << "}";34 }35};36 37class CollectCommentsAction : public ASTFrontendAction {38public:39 CollectCommentsAction(std::vector<FoundComment> &Comments)40 : Comments(Comments) {}41 42 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,43 llvm::StringRef) override {44 CI.getLangOpts().CommentOpts.ParseAllComments = true;45 return std::make_unique<Consumer>(*this);46 }47 48 std::vector<FoundComment> &Comments;49 50private:51 class Consumer : public clang::ASTConsumer {52 private:53 CollectCommentsAction &Action;54 55 public:56 Consumer(CollectCommentsAction &Action) : Action(Action) {}57 58 bool HandleTopLevelDecl(DeclGroupRef DG) override {59 for (Decl *D : DG) {60 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {61 auto &Ctx = D->getASTContext();62 const auto *RC = Ctx.getRawCommentForAnyRedecl(D);63 Action.Comments.push_back(FoundComment{64 ND->getNameAsString(), IsDefinition(D),65 RC ? RC->getRawText(Ctx.getSourceManager()).str() : ""});66 }67 }68 69 return true;70 }71 72 static bool IsDefinition(const Decl *D) {73 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {74 return FD->isThisDeclarationADefinition();75 }76 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {77 return TD->isThisDeclarationADefinition();78 }79 return false;80 }81 };82};83 84TEST(RawCommentForDecl, DefinitionComment) {85 std::vector<FoundComment> Comments;86 auto Action = std::make_unique<CollectCommentsAction>(Comments);87 ASSERT_TRUE(tooling::runToolOnCode(std::move(Action), R"cpp(88 void f();89 90 // f is the best91 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 clang99