Skip to content

Commit 322b03d

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.
1 parent b7d8a9b commit 322b03d

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
@@ -894,9 +894,6 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
894894
invocation->getHeaderSearchOpts().ModulesValidateSystemHeaders = true;
895895
invocation->getLangOpts().NeededByPCHOrCompilationUsesPCH = true;
896896
invocation->getLangOpts().CacheGeneratedPCH = true;
897-
// If the underlying invocation is allowing PCH errors, then it "can be read",
898-
// even if it has its error bit set. Thus, don't override
899-
// `AllowPCHWithCompilerErrors`.
900897

901898
// ClangImporter::create adds a remapped MemoryBuffer that we don't need
902899
// here. Moreover, it's a raw pointer owned by the preprocessor options; if
@@ -934,6 +931,14 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
934931
clang::ASTReader::ARR_OutOfDate |
935932
clang::ASTReader::ARR_VersionMismatch;
936933

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