[libc++][Android] BuildKite CI: update Clang and sysroot versions (#116151)
[llvm-project.git] / clang / unittests / Serialization / PreambleInNamedModulesTest.cpp
blobd26e1cb633654f678294138ccedab5dc19f3ee51
1 //===- unittests/Serialization/PreambleInNamedModulesTest.cpp -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "clang/Frontend/CompilerInstance.h"
10 #include "clang/Frontend/CompilerInvocation.h"
11 #include "clang/Frontend/FrontendActions.h"
12 #include "clang/Frontend/PrecompiledPreamble.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/Support/FileSystem.h"
15 #include "llvm/Support/raw_ostream.h"
17 #include "gtest/gtest.h"
19 using namespace llvm;
20 using namespace clang;
22 namespace {
24 class PreambleInNamedModulesTest : public ::testing::Test {
25 void SetUp() override {
26 ASSERT_FALSE(sys::fs::createUniqueDirectory("modules-test", TestDir));
29 void TearDown() override { sys::fs::remove_directories(TestDir); }
31 public:
32 using PathType = SmallString<256>;
34 PathType TestDir;
36 void addFile(StringRef Path, StringRef Contents, PathType &AbsPath) {
37 ASSERT_FALSE(sys::path::is_absolute(Path));
39 AbsPath = TestDir;
40 sys::path::append(AbsPath, Path);
42 ASSERT_FALSE(
43 sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath)));
45 std::error_code EC;
46 llvm::raw_fd_ostream OS(AbsPath, EC);
47 ASSERT_FALSE(EC);
48 OS << Contents;
51 void addFile(StringRef Path, StringRef Contents) {
52 PathType UnusedAbsPath;
53 addFile(Path, Contents, UnusedAbsPath);
57 // Testing that the use of Preamble in named modules can work basically.
58 // See https://github.com/llvm/llvm-project/issues/80570
59 TEST_F(PreambleInNamedModulesTest, BasicTest) {
60 addFile("foo.h", R"cpp(
61 enum class E {
67 )cpp");
69 PathType MainFilePath;
70 addFile("A.cppm", R"cpp(
71 module;
72 #include "foo.h"
73 export module A;
74 export using ::E;
75 )cpp",
76 MainFilePath);
78 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
79 CompilerInstance::createDiagnostics(new DiagnosticOptions());
80 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
81 llvm::vfs::createPhysicalFileSystem();
83 CreateInvocationOptions CIOpts;
84 CIOpts.Diags = Diags;
85 CIOpts.VFS = VFS;
87 const char *Args[] = {"clang++", "-std=c++20", "-working-directory",
88 TestDir.c_str(), MainFilePath.c_str()};
89 std::shared_ptr<CompilerInvocation> Invocation =
90 createInvocation(Args, CIOpts);
91 ASSERT_TRUE(Invocation);
93 llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> ContentsBuffer =
94 llvm::MemoryBuffer::getFile(MainFilePath, /*IsText=*/true);
95 EXPECT_TRUE(ContentsBuffer);
96 std::unique_ptr<MemoryBuffer> Buffer = std::move(*ContentsBuffer);
98 PreambleBounds Bounds =
99 ComputePreambleBounds(Invocation->getLangOpts(), *Buffer, 0);
101 PreambleCallbacks Callbacks;
102 llvm::ErrorOr<PrecompiledPreamble> BuiltPreamble = PrecompiledPreamble::Build(
103 *Invocation, Buffer.get(), Bounds, *Diags, VFS,
104 std::make_shared<PCHContainerOperations>(),
105 /*StoreInMemory=*/false, /*StoragePath=*/TestDir, Callbacks);
107 ASSERT_FALSE(Diags->hasErrorOccurred());
109 EXPECT_TRUE(BuiltPreamble);
110 EXPECT_TRUE(BuiltPreamble->CanReuse(*Invocation, *Buffer, Bounds, *VFS));
111 BuiltPreamble->OverridePreamble(*Invocation, VFS, Buffer.get());
113 auto Clang = std::make_unique<CompilerInstance>(
114 std::make_shared<PCHContainerOperations>());
115 Clang->setInvocation(std::move(Invocation));
116 Clang->setDiagnostics(Diags.get());
118 if (auto VFSWithRemapping = createVFSFromCompilerInvocation(
119 Clang->getInvocation(), Clang->getDiagnostics(), VFS))
120 VFS = VFSWithRemapping;
122 Clang->createFileManager(VFS);
123 EXPECT_TRUE(Clang->createTarget());
125 Buffer.release();
127 SyntaxOnlyAction Action;
128 EXPECT_TRUE(Clang->ExecuteAction(Action));
129 EXPECT_FALSE(Clang->getDiagnosticsPtr()->hasErrorOccurred());
132 } // namespace