[ObjcHeader] Fix objc header generation when pch is explicited passed

When swift-frontend is explicitly passed the pch file as bridging header
on command-line through `-import-objc-header`, it needs to print the
original source file name if needed to the generated objc header.

rdar://109411245
This commit is contained in:
Steven Wu
2023-05-17 14:13:41 -07:00
parent ee5b3b134b
commit 16e4cfae76
9 changed files with 68 additions and 6 deletions

View File

@@ -403,6 +403,9 @@ public:
/// if we need to persist a PCH for later reuse.
bool canReadPCH(StringRef PCHFilename);
/// Reads the original source file name from PCH.
std::string getOriginalSourceFile(StringRef PCHFilename);
/// Makes a temporary replica of the ClangImporter's CompilerInstance, reads a
/// module map into the replica and emits a PCM file for one of the modules it
/// declares. Delegates to clang for everything except construction of the

View File

@@ -667,6 +667,9 @@ public:
/// file.
SourceFile *getIDEInspectionFile() const;
/// Retrieve the printing path for bridging header.
std::string getBridgingHeaderPath() const;
private:
/// Set up the file system by loading and validating all VFS overlay YAML
/// files. If the process of validating VFS files failed, or the overlay

View File

@@ -915,6 +915,12 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
llvm_unreachable("unhandled result");
}
std::string ClangImporter::getOriginalSourceFile(StringRef PCHFilename) {
return clang::ASTReader::getOriginalSourceFile(
PCHFilename.str(), Impl.Instance->getFileManager(),
Impl.Instance->getPCHContainerReader(), Impl.Instance->getDiagnostics());
}
Optional<std::string>
ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
StringRef SwiftPCHHash, bool &isExplicit) {

View File

@@ -818,6 +818,26 @@ SourceFile *CompilerInstance::getIDEInspectionFile() const {
return evaluateOrDefault(eval, IDEInspectionFileRequest{mod}, nullptr);
}
static inline bool isPCHFilenameExtension(StringRef path) {
return llvm::sys::path::extension(path)
.endswith(file_types::getExtension(file_types::TY_PCH));
}
std::string CompilerInstance::getBridgingHeaderPath() const {
const FrontendOptions &opts = Invocation.getFrontendOptions();
if (!isPCHFilenameExtension(opts.ImplicitObjCHeaderPath))
return opts.ImplicitObjCHeaderPath;
auto clangImporter =
static_cast<ClangImporter *>(getASTContext().getClangModuleLoader());
// No clang importer created. Report error?
if (!clangImporter)
return std::string();
return clangImporter->getOriginalSourceFile(opts.ImplicitObjCHeaderPath);
}
bool CompilerInstance::setUpInputs() {
// Adds to InputSourceCodeBufferIDs, so may need to happen before the
// per-input setup.

View File

@@ -912,17 +912,14 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
if ((!Context.hadError() || opts.AllowModuleWithCompilerErrors) &&
opts.InputsAndOutputs.hasClangHeaderOutputPath()) {
std::string BridgingHeaderPathForPrint;
if (!opts.ImplicitObjCHeaderPath.empty()) {
std::string BridgingHeaderPathForPrint = Instance.getBridgingHeaderPath();
if (!BridgingHeaderPathForPrint.empty()) {
if (opts.BridgingHeaderDirForPrint.has_value()) {
// User specified preferred directory for including, use that dir.
llvm::SmallString<32> Buffer(*opts.BridgingHeaderDirForPrint);
llvm::sys::path::append(Buffer,
llvm::sys::path::filename(opts.ImplicitObjCHeaderPath));
llvm::sys::path::filename(BridgingHeaderPathForPrint));
BridgingHeaderPathForPrint = (std::string)Buffer;
} else {
// By default, include the given bridging header path directly.
BridgingHeaderPathForPrint = opts.ImplicitObjCHeaderPath;
}
}
hadAnyError |= printAsClangHeaderIfNeeded(

View File

@@ -0,0 +1,5 @@
@import Foundation;
@protocol TestProto
@property id strongProp;
@end

View File

@@ -0,0 +1,8 @@
#import <Foundation.h>
@interface ObjCClass : NSObject
- (nullable id)swiftMethod;
@end

View File

@@ -63,3 +63,8 @@ module objc_implementation {
header "objc_implementation/objc_implementation.h"
export *
}
module bridging_header {
header "bridging_header/bridging_header.h"
export *
}

View File

@@ -0,0 +1,15 @@
// REQUIRES: objc_interop
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-pch -o %t/bridging-header.pch %S/Inputs/bridging_header-Bridging-Header.h
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -I %S/Inputs/custom-modules -import-objc-header %t/bridging-header.pch -import-underlying-module -o %t %s -disable-objc-attr-requires-foundation-module -emit-objc-header-path %t/bridging_header-Swift.h
// RUN: %FileCheck %s --input-file %t/bridging_header-Swift.h
// CHECK: bridging_header-Bridging-Header.h
// CHECK-NOT: bridging-header.pch
@objc class Test : NSObject, TestProto {
var strongProp: Any?
}