Skip to content

Commit 43e771e

Browse files
committed
Reapply ClangImporter changes to leverage Clang's module cache
This reapplies four commits for the ClangImporter. They broke the build on master because the associated commits on swift-clang's swift-5.1-branch never made it to stable due to automerger woes. This time I'll push everything through manually. These are the commits being reapplied: - a42bc62 "ClangImporter: Share a module cache between CompilerInstances" - 9eed342 "ClangImporter: Adjust to r355777, PCMCache => ModuleCache" - da8a1c5 "ClangImporter: Use the new CacheGeneratedPCH in Clang" - 2134b17 "ClangImporter: Test that PCHs are actually cached in memory" rdar://problem/48545366
1 parent f5a216f commit 43e771e

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,6 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
770770
*clangDiags,
771771
CI.getLangOpts(),
772772
clangSrcMgr,
773-
CI.getPCMCache(),
774773
headerSearchInfo,
775774
(clang::ModuleLoader &)CI,
776775
/*IILookup=*/nullptr,
@@ -783,7 +782,7 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
783782
// Note: Reusing the PCHContainerReader or ModuleFileExtensions could be
784783
// dangerous.
785784
std::unique_ptr<clang::ASTReader> Reader(new clang::ASTReader(
786-
PP, &ctx, CI.getPCHContainerReader(),
785+
PP, CI.getModuleCache(), &ctx, CI.getPCHContainerReader(),
787786
CI.getFrontendOpts().ModuleFileExtensions,
788787
CI.getHeaderSearchOpts().Sysroot,
789788
/*DisableValidation*/ false,
@@ -1395,7 +1394,8 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
13951394
invocation->getPreprocessorOpts().resetNonModularOptions();
13961395

13971396
clang::CompilerInstance rewriteInstance(
1398-
Impl.Instance->getPCHContainerOperations());
1397+
Impl.Instance->getPCHContainerOperations(),
1398+
&Impl.Instance->getModuleCache());
13991399
rewriteInstance.setInvocation(invocation);
14001400
rewriteInstance.createDiagnostics(new clang::IgnoringDiagConsumer);
14011401

@@ -1451,9 +1451,11 @@ ClangImporter::emitBridgingPCH(StringRef headerPath,
14511451
invocation->getFrontendOpts().ProgramAction = clang::frontend::GeneratePCH;
14521452
invocation->getPreprocessorOpts().resetNonModularOptions();
14531453
invocation->getLangOpts()->NeededByPCHOrCompilationUsesPCH = true;
1454+
invocation->getLangOpts()->CacheGeneratedPCH = true;
14541455

14551456
clang::CompilerInstance emitInstance(
1456-
Impl.Instance->getPCHContainerOperations());
1457+
Impl.Instance->getPCHContainerOperations(),
1458+
&Impl.Instance->getModuleCache());
14571459
emitInstance.setInvocation(std::move(invocation));
14581460
emitInstance.createDiagnostics(&Impl.Instance->getDiagnosticClient(),
14591461
/*ShouldOwnClient=*/false);

unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if(SWIFT_INCLUDE_TOOLS)
66

77
add_subdirectory(AST)
88
add_subdirectory(Basic)
9+
add_subdirectory(ClangImporter)
910
add_subdirectory(Driver)
1011
add_subdirectory(FrontendTool)
1112
add_subdirectory(IDE)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
add_swift_unittest(SwiftClangImporterTests
2+
ClangImporterTests.cpp
3+
)
4+
5+
target_link_libraries(SwiftClangImporterTests
6+
PRIVATE
7+
swiftClangImporter
8+
swiftParse
9+
swiftAST
10+
)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include "swift/AST/ASTContext.h"
2+
#include "swift/AST/DiagnosticEngine.h"
3+
#include "swift/AST/SearchPathOptions.h"
4+
#include "swift/Basic/LLVMInitialize.h"
5+
#include "swift/Basic/LangOptions.h"
6+
#include "swift/Basic/SourceManager.h"
7+
#include "swift/ClangImporter/ClangImporter.h"
8+
#include "swift/ClangImporter/ClangImporterOptions.h"
9+
#include "llvm/Support/FileSystem.h"
10+
#include "llvm/Support/Path.h"
11+
#include "llvm/Support/raw_ostream.h"
12+
#include "gtest/gtest.h"
13+
14+
using namespace swift;
15+
16+
static std::string createFilename(StringRef base, StringRef name) {
17+
SmallString<256> path = base;
18+
llvm::sys::path::append(path, name);
19+
return llvm::Twine(path).str();
20+
}
21+
22+
static bool emitFileWithContents(StringRef path, StringRef contents,
23+
std::string *pathOut = nullptr) {
24+
int FD;
25+
if (llvm::sys::fs::openFileForWrite(path, FD))
26+
return true;
27+
if (pathOut)
28+
*pathOut = path;
29+
llvm::raw_fd_ostream file(FD, /*shouldClose=*/true);
30+
file << contents;
31+
return false;
32+
}
33+
34+
static bool emitFileWithContents(StringRef base, StringRef name,
35+
StringRef contents,
36+
std::string *pathOut = nullptr) {
37+
return emitFileWithContents(createFilename(base, name), contents, pathOut);
38+
}
39+
40+
TEST(ClangImporterTest, emitPCHInMemory) {
41+
// Create a temporary cache on disk and clean it up at the end.
42+
ClangImporterOptions options;
43+
SmallString<256> temp;
44+
ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory(
45+
"ClangImporterTest.emitPCHInMemory", temp));
46+
SWIFT_DEFER { llvm::sys::fs::remove_directories(temp); };
47+
48+
// Create a cache subdirectory for the modules and PCH.
49+
std::string cache = createFilename(temp, "cache");
50+
ASSERT_FALSE(llvm::sys::fs::create_directory(cache));
51+
options.ModuleCachePath = cache;
52+
options.PrecompiledHeaderOutputDir = cache;
53+
54+
// Create the includes.
55+
std::string include = createFilename(temp, "include");
56+
ASSERT_FALSE(llvm::sys::fs::create_directory(include));
57+
options.ExtraArgs.emplace_back("-nosysteminc");
58+
options.ExtraArgs.emplace_back((llvm::Twine("-I") + include).str());
59+
ASSERT_FALSE(emitFileWithContents(include, "module.modulemap",
60+
"module A {\n"
61+
" header \"A.h\"\n"
62+
"}\n"));
63+
ASSERT_FALSE(emitFileWithContents(include, "A.h", "int foo(void);\n"));
64+
65+
// Create a bridging header.
66+
ASSERT_FALSE(emitFileWithContents(temp, "bridging.h", "#import <A.h>\n",
67+
&options.BridgingHeader));
68+
69+
// Set up the importer and emit a bridging PCH.
70+
swift::LangOptions langOpts;
71+
langOpts.Target = llvm::Triple("x86_64", "apple", "darwin");
72+
INITIALIZE_LLVM();
73+
swift::SearchPathOptions searchPathOpts;
74+
swift::SourceManager sourceMgr;
75+
swift::DiagnosticEngine diags(sourceMgr);
76+
std::unique_ptr<ASTContext> context(
77+
ASTContext::get(langOpts, searchPathOpts, sourceMgr, diags));
78+
auto importer = ClangImporter::create(*context, options);
79+
80+
std::string PCH = createFilename(cache, "bridging.h.pch");
81+
ASSERT_FALSE(importer->canReadPCH(PCH));
82+
ASSERT_FALSE(importer->emitBridgingPCH(options.BridgingHeader, PCH));
83+
ASSERT_TRUE(importer->canReadPCH(PCH));
84+
85+
// Overwrite the PCH with garbage. We should still be able to read it from
86+
// the in-memory cache.
87+
ASSERT_FALSE(emitFileWithContents(PCH, "garbage"));
88+
ASSERT_TRUE(importer->canReadPCH(PCH));
89+
}

0 commit comments

Comments
 (0)