brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · c81e56b Raw
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