1 //===- unittests/Serialization/ForceCheckFileInputTest.cpp - CI tests -----===//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/ASTMatchers/ASTMatchFinder.h"
10 #include "clang/ASTMatchers/ASTMatchers.h"
11 #include "clang/Basic/FileManager.h"
12 #include "clang/Frontend/CompilerInstance.h"
13 #include "clang/Frontend/CompilerInvocation.h"
14 #include "clang/Frontend/FrontendActions.h"
15 #include "clang/Frontend/Utils.h"
16 #include "clang/Lex/HeaderSearch.h"
17 #include "clang/Lex/PreprocessorOptions.h"
18 #include "clang/Serialization/ASTReader.h"
19 #include "clang/Tooling/Tooling.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/raw_ostream.h"
24 #include "gtest/gtest.h"
27 using namespace clang
;
31 class ForceCheckFileInputTest
: public ::testing::Test
{
32 void SetUp() override
{
33 EXPECT_FALSE(sys::fs::createUniqueDirectory("modules-test", TestDir
));
36 void TearDown() override
{ sys::fs::remove_directories(TestDir
); }
39 SmallString
<256> TestDir
;
41 void addFile(StringRef Path
, StringRef Contents
) {
42 EXPECT_FALSE(sys::path::is_absolute(Path
));
44 SmallString
<256> AbsPath(TestDir
);
45 sys::path::append(AbsPath
, Path
);
48 sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath
)));
51 llvm::raw_fd_ostream
OS(AbsPath
, EC
);
57 TEST_F(ForceCheckFileInputTest
, ForceCheck
) {
58 addFile("a.cppm", R
"cpp(
63 std::string BMIPath
= llvm::Twine(TestDir
+ "/a.pcm").str();
66 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
67 CompilerInstance::createDiagnostics(new DiagnosticOptions());
68 CreateInvocationOptions CIOpts
;
70 CIOpts
.VFS
= llvm::vfs::createPhysicalFileSystem();
72 const char *Args
[] = {
73 "clang++", "-std=c++20", "--precompile", "-working-directory",
74 TestDir
.c_str(), "a.cppm", "-o", BMIPath
.c_str()};
75 std::shared_ptr
<CompilerInvocation
> Invocation
=
76 createInvocation(Args
, CIOpts
);
77 EXPECT_TRUE(Invocation
);
78 Invocation
->getFrontendOpts().DisableFree
= false;
80 auto Buf
= CIOpts
.VFS
->getBufferForFile("a.cppm");
83 Invocation
->getPreprocessorOpts().addRemappedFile("a.cppm", Buf
->get());
87 CompilerInstance Instance
;
88 Instance
.setDiagnostics(Diags
.get());
89 Instance
.setInvocation(Invocation
);
91 if (auto VFSWithRemapping
= createVFSFromCompilerInvocation(
92 Instance
.getInvocation(), Instance
.getDiagnostics(), CIOpts
.VFS
))
93 CIOpts
.VFS
= VFSWithRemapping
;
94 Instance
.createFileManager(CIOpts
.VFS
);
96 Instance
.getHeaderSearchOpts().ValidateASTInputFilesContent
= true;
98 GenerateModuleInterfaceAction Action
;
99 EXPECT_TRUE(Instance
.ExecuteAction(Action
));
100 EXPECT_FALSE(Diags
->hasErrorOccurred());
104 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
105 CompilerInstance::createDiagnostics(new DiagnosticOptions());
106 CreateInvocationOptions CIOpts
;
107 CIOpts
.Diags
= Diags
;
108 CIOpts
.VFS
= llvm::vfs::createPhysicalFileSystem();
110 std::string BMIPath
= llvm::Twine(TestDir
+ "/a.pcm").str();
111 const char *Args
[] = {
112 "clang++", "-std=c++20", "--precompile", "-working-directory",
113 TestDir
.c_str(), "a.cppm", "-o", BMIPath
.c_str()};
114 std::shared_ptr
<CompilerInvocation
> Invocation
=
115 createInvocation(Args
, CIOpts
);
116 EXPECT_TRUE(Invocation
);
117 Invocation
->getFrontendOpts().DisableFree
= false;
119 CompilerInstance Clang
;
121 Clang
.setInvocation(Invocation
);
122 Clang
.setDiagnostics(Diags
.get());
123 FileManager
*FM
= Clang
.createFileManager(CIOpts
.VFS
);
124 Clang
.createSourceManager(*FM
);
126 EXPECT_TRUE(Clang
.createTarget());
127 Clang
.createPreprocessor(TU_Complete
);
128 Clang
.getHeaderSearchOpts().ForceCheckCXX20ModulesInputFiles
= true;
129 Clang
.getHeaderSearchOpts().ValidateASTInputFilesContent
= true;
130 Clang
.createASTReader();
132 addFile("a.cppm", R
"cpp(
138 Clang
.getASTReader()->ReadAST(BMIPath
, serialization::MK_MainFile
,
139 SourceLocation(), ASTReader::ARR_None
);
141 // We shall be able to detect the content change here.
142 EXPECT_NE(ReadResult
, ASTReader::Success
);
146 } // anonymous namespace