Skip to content

Commit f75c1e3

Browse files
committed
[ClangImporter] Always rebuild any bridging PCH that has errors
If a PCH was output with errors, it may not have serialized all its inputs. If there was a change to the search path or a headermap now exists where it didn't previously, it's possible those inputs will now be found. Ideally we would only rebuild in this particular case rather than any error in general, but explicit module builds are the real solution there. For now, just treat PCH with errors as out of date. Resolves rdar://117037471. (cherry picked from commit 322b03d)
1 parent d0afa07 commit f75c1e3

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -892,9 +892,6 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
892892
invocation->getHeaderSearchOpts().ModulesValidateSystemHeaders = true;
893893
invocation->getLangOpts()->NeededByPCHOrCompilationUsesPCH = true;
894894
invocation->getLangOpts()->CacheGeneratedPCH = true;
895-
// If the underlying invocation is allowing PCH errors, then it "can be read",
896-
// even if it has its error bit set. Thus, don't override
897-
// `AllowPCHWithCompilerErrors`.
898895

899896
// ClangImporter::create adds a remapped MemoryBuffer that we don't need
900897
// here. Moreover, it's a raw pointer owned by the preprocessor options; if
@@ -932,6 +929,14 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
932929
clang::ASTReader::ARR_OutOfDate |
933930
clang::ASTReader::ARR_VersionMismatch;
934931

932+
// If a PCH was output with errors, it may not have serialized all its
933+
// inputs. If there was a change to the search path or a headermap now
934+
// exists where it didn't previously, it's possible those inputs will now be
935+
// found. Ideally we would only rebuild in this particular case rather than
936+
// any error in general, but explicit module builds are the real solution
937+
// there. For now, just treat PCH with errors as out of date.
938+
failureCapabilities |= clang::ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate;
939+
935940
auto result = Reader.ReadAST(PCHFilename, clang::serialization::MK_PCH,
936941
clang::SourceLocation(), failureCapabilities);
937942
switch (result) {

test/ClangImporter/AllowErrors/invalid-pch-bridging-header.swift

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,48 @@
33
// RUN: %empty-directory(%t)
44
// RUN: mkdir -p %t/pch %t/pch-dir
55
// RUN: split-file %s %t
6+
// RUN: sed -e "s|TEST_DIR|%/t|g" %t/hmap.json > %t/inner.json
67

78
// Check that the pch is output even though it has errors
8-
// RUN: %target-swift-frontend -emit-pch -o %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/bridging-header.h
9-
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
9+
// RUN: %target-swift-frontend -emit-pch -o %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/bridging-header.h -Xcc -I%t/inner.hmap
10+
// RUN: not %target-swift-frontend -typecheck -import-objc-header %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift -Xcc -I%t/inner.hmap 2>&1 | %FileCheck %s -check-prefix MISSING_HMAP
1011
// RUN: ls %t/pch/*.pch | count 1
1112

1213
// Same but with implicit PCH instead
13-
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
14+
// RUN: not %target-swift-frontend -typecheck -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift -Xcc -I%t/inner.hmap 2>&1 | %FileCheck %s -check-prefix MISSING_HMAP
1415
// RUN: ls %t/pch-dir/*.pch | count 1
1516

1617
// Second implicit run since we may go down a different path if the PCH already
1718
// exists
18-
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
19+
// RUN: not %target-swift-frontend -typecheck -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift -Xcc -I%t/inner.hmap 2>&1 | %FileCheck %s -check-prefix MISSING_HMAP
20+
// RUN: ls %t/pch-dir/*.pch | count 1
21+
22+
// Create the headermap, should now have no errors
23+
// RUN: %hmaptool write %t/inner.json %t/inner.hmap
24+
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift -Xcc -I%t/inner.hmap
1925
// RUN: ls %t/pch-dir/*.pch | count 1
2026

2127
//--- bridging-header.h
22-
@import DoesNotExist;
28+
#include "inner.h"
2329

2430
struct SomeTy {
2531
int a;
2632
};
2733

34+
//--- inner/inner.h
35+
struct InnerTy {
36+
int b;
37+
};
38+
39+
//--- hmap.json
40+
{
41+
"mappings": {
42+
"inner.h": "TEST_DIR/inner/inner.h"
43+
}
44+
}
45+
2846
//--- use.swift
29-
func use(s: SomeTy) {}
47+
func use(s: SomeTy, s2: InnerTy) {}
48+
// MISSING_HMAP-NOT: cannot find type 'SomeTy' in scope
49+
// MISSING_HMAP: cannot find type 'InnerTy' in scope
50+
// MISSING_HMAP-NOT: cannot find type 'SomeTy' in scope

0 commit comments

Comments
 (0)