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
[] = {"clang++", "-std=c++20",
73 "--precompile", "-working-directory",
74 TestDir
.c_str(), "a.cppm"};
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 Instance
.getFrontendOpts().OutputFile
= BMIPath
;
93 if (auto VFSWithRemapping
= createVFSFromCompilerInvocation(
94 Instance
.getInvocation(), Instance
.getDiagnostics(), CIOpts
.VFS
))
95 CIOpts
.VFS
= VFSWithRemapping
;
96 Instance
.createFileManager(CIOpts
.VFS
);
98 Instance
.getHeaderSearchOpts().ValidateASTInputFilesContent
= true;
100 GenerateReducedModuleInterfaceAction Action
;
101 EXPECT_TRUE(Instance
.ExecuteAction(Action
));
102 EXPECT_FALSE(Diags
->hasErrorOccurred());
106 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
107 CompilerInstance::createDiagnostics(new DiagnosticOptions());
108 CreateInvocationOptions CIOpts
;
109 CIOpts
.Diags
= Diags
;
110 CIOpts
.VFS
= llvm::vfs::createPhysicalFileSystem();
112 std::string BMIPath
= llvm::Twine(TestDir
+ "/a.pcm").str();
113 const char *Args
[] = {
114 "clang++", "-std=c++20", "--precompile", "-working-directory",
115 TestDir
.c_str(), "a.cppm", "-o", BMIPath
.c_str()};
116 std::shared_ptr
<CompilerInvocation
> Invocation
=
117 createInvocation(Args
, CIOpts
);
118 EXPECT_TRUE(Invocation
);
119 Invocation
->getFrontendOpts().DisableFree
= false;
121 CompilerInstance Clang
;
123 Clang
.setInvocation(Invocation
);
124 Clang
.setDiagnostics(Diags
.get());
125 FileManager
*FM
= Clang
.createFileManager(CIOpts
.VFS
);
126 Clang
.createSourceManager(*FM
);
128 EXPECT_TRUE(Clang
.createTarget());
129 Clang
.createPreprocessor(TU_Complete
);
130 Clang
.getHeaderSearchOpts().ForceCheckCXX20ModulesInputFiles
= true;
131 Clang
.getHeaderSearchOpts().ValidateASTInputFilesContent
= true;
132 Clang
.createASTReader();
134 addFile("a.cppm", R
"cpp(
140 Clang
.getASTReader()->ReadAST(BMIPath
, serialization::MK_MainFile
,
141 SourceLocation(), ASTReader::ARR_None
);
143 // We shall be able to detect the content change here.
144 EXPECT_NE(ReadResult
, ASTReader::Success
);
148 } // anonymous namespace