//===- 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 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( "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"); IntrusiveRefCntPtr Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions()); CreateInvocationOptions CIOpts; CIOpts.Diags = Diags; CIOpts.VFS = llvm::vfs::createPhysicalFileSystem(); std::string CacheBMIPath = llvm::Twine(TestDir + "/Comments.pcm").str(); const char *Args[] = { "clang++", "-std=c++20", "--precompile", "-working-directory", TestDir.c_str(), "Comments.cppm", "-o", CacheBMIPath.c_str()}; std::shared_ptr Invocation = createInvocation(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); Instance.setInvocation(Invocation); GenerateModuleInterfaceAction Action; ASSERT_TRUE(Instance.ExecuteAction(Action)); ASSERT_FALSE(Diags->hasErrorOccurred()); std::string DepArg = llvm::Twine("-fmodule-file=Comments=" + CacheBMIPath).str(); std::unique_ptr 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( "foo", match(functionDecl(hasName("foo")).bind("foo"), Ctx)); EXPECT_TRUE(foo); const RawComment *RC = getCompletionComment(Ctx, foo); EXPECT_FALSE(RC); } } // anonymous namespace