aboutsummaryrefslogtreecommitdiff
path: root/clang/unittests/Serialization/NoCommentsTest.cpp
blob: 05efeef990d43617a1e3075d6c45fccc10e9a88d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//===- unittests/Serialization/NoComments.cpp - CI tests -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"

#include "gtest/gtest.h"

using namespace llvm;
using namespace clang;

namespace {

class NoComments : public ::testing::Test {
  void SetUp() override {
    ASSERT_FALSE(
        sys::fs::createUniqueDirectory("modules-no-comments-test", TestDir));
  }

  void TearDown() override { sys::fs::remove_directories(TestDir); }

public:
  SmallString<256> TestDir;

  void addFile(StringRef Path, StringRef Contents) {
    ASSERT_FALSE(sys::path::is_absolute(Path));

    SmallString<256> AbsPath(TestDir);
    sys::path::append(AbsPath, Path);

    ASSERT_FALSE(
        sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath)));

    std::error_code EC;
    llvm::raw_fd_ostream OS(AbsPath, EC);
    ASSERT_FALSE(EC);
    OS << Contents;
  }
};

TEST_F(NoComments, NonModulesTest) {
  std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(
      R"cpp(
/// Any comments
void foo() {}
        )cpp",
      /*Args=*/{"-std=c++20"});
  EXPECT_TRUE(AST);

  ASTContext &Ctx = AST->getASTContext();

  using namespace clang::ast_matchers;
  auto *foo = selectFirst<FunctionDecl>(
      "foo", match(functionDecl(hasName("foo")).bind("foo"), Ctx));
  EXPECT_TRUE(foo);

  const RawComment *RC = getCompletionComment(Ctx, foo);
  EXPECT_TRUE(RC);
  EXPECT_TRUE(RC->getRawText(Ctx.getSourceManager()).trim() ==
              "/// Any comments");
}

TEST_F(NoComments, ModulesTest) {
  addFile("Comments.cppm", R"cpp(
export module Comments;

/// Any comments
void foo() {}
  )cpp");

  CreateInvocationOptions CIOpts;
  CIOpts.VFS = llvm::vfs::createPhysicalFileSystem();
  DiagnosticOptions DiagOpts;
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts);
  CIOpts.Diags = Diags;

  std::string CacheBMIPath = llvm::Twine(TestDir + "/Comments.pcm").str();
  const char *Args[] = {"clang++",       "-std=c++20",
                        "--precompile",  "-working-directory",
                        TestDir.c_str(), "Comments.cppm"};
  std::shared_ptr<CompilerInvocation> Invocation =
      createInvocation(Args, CIOpts);
  ASSERT_TRUE(Invocation);

  CompilerInstance Instance(std::move(Invocation));
  Instance.setDiagnostics(Diags.get());
  Instance.getFrontendOpts().OutputFile = CacheBMIPath;
  GenerateReducedModuleInterfaceAction Action;
  ASSERT_TRUE(Instance.ExecuteAction(Action));
  ASSERT_FALSE(Diags->hasErrorOccurred());

  std::string DepArg =
      llvm::Twine("-fmodule-file=Comments=" + CacheBMIPath).str();
  std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(
      R"cpp(
import Comments;
        )cpp",
      /*Args=*/{"-std=c++20", DepArg.c_str()});
  EXPECT_TRUE(AST);

  ASTContext &Ctx = AST->getASTContext();

  using namespace clang::ast_matchers;
  auto *foo = selectFirst<FunctionDecl>(
      "foo", match(functionDecl(hasName("foo")).bind("foo"), Ctx));
  EXPECT_TRUE(foo);

  const RawComment *RC = getCompletionComment(Ctx, foo);
  EXPECT_FALSE(RC);
}

} // anonymous namespace