Skip to content

Commit c352200

Browse files
committed
[interop] review fixes for symbolic interface emission
1 parent 3459242 commit c352200

File tree

5 files changed

+92
-51
lines changed

5 files changed

+92
-51
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,13 @@ REMARK(remark_indexing_system_module,none,
270270
"indexing system module at %0"
271271
"%select{|; skipping because of a broken swiftinterface}1",
272272
(StringRef, bool))
273+
274+
ERROR(error_create_symbolic_interfaces_dir,none,
275+
"creating symbolic interfaces directory: %0", (StringRef))
276+
ERROR(error_symbolic_interfaces_failed_status_check,none,
277+
"failed file status check: %0", (StringRef))
278+
ERROR(error_write_symbolic_interface,none,
279+
"writing symbolic interface file: %0", (StringRef))
273280
REMARK(remark_emitting_symbolic_interface_module,none,
274281
"emitting symbolic interface at %0"
275282
"%select{|; skipping because it's up to date}1",

lib/Index/IndexRecord.cpp

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -401,18 +401,13 @@ appendSymbolicInterfaceToIndexStorePath(SmallVectorImpl<char> &resultingPath) {
401401
llvm::sys::path::append(resultingPath, "interfaces");
402402
}
403403

404-
static bool initSymbolicInterfaceStorePath(StringRef storePath,
405-
std::string &error) {
406-
using namespace llvm::sys;
404+
static llvm::Error initSymbolicInterfaceStorePath(StringRef storePath) {
407405
SmallString<128> subPath = storePath;
408406
appendSymbolicInterfaceToIndexStorePath(subPath);
409-
std::error_code ec = fs::create_directories(subPath);
410-
if (ec) {
411-
llvm::raw_string_ostream err(error);
412-
err << "failed to create directory '" << subPath << "': " << ec.message();
413-
return true;
414-
}
415-
return false;
407+
std::error_code ec = llvm::sys::fs::create_directories(subPath);
408+
if (ec)
409+
return llvm::errorCodeToError(ec);
410+
return llvm::Error::success();
416411
}
417412

418413
static void appendSymbolicInterfaceClangModuleFilename(
@@ -423,32 +418,29 @@ static void appendSymbolicInterfaceClangModuleFilename(
423418
}
424419

425420
// FIXME (Alex): Share code with IndexUnitWriter in LLVM after refactoring it.
426-
static Optional<bool>
427-
isFileUpToDateForOutputFile(StringRef filePath,
428-
Optional<StringRef> timeCompareFilePath,
429-
std::string &error) {
421+
static llvm::Expected<bool>
422+
isFileUpToDateForOutputFile(StringRef filePath, StringRef timeCompareFilePath) {
423+
auto makeError = [](StringRef path, std::error_code ec) -> llvm::Error {
424+
std::string error;
425+
llvm::raw_string_ostream(error)
426+
<< "could not access path '" << path << "': " << ec.message();
427+
return llvm::createStringError(ec, error.c_str());
428+
};
430429
llvm::sys::fs::file_status unitStat;
431430
if (std::error_code ec = llvm::sys::fs::status(filePath, unitStat)) {
432-
if (ec != std::errc::no_such_file_or_directory) {
433-
llvm::raw_string_ostream err(error);
434-
err << "could not access path '" << filePath << "': " << ec.message();
435-
return {};
436-
}
431+
if (ec != std::errc::no_such_file_or_directory)
432+
return makeError(filePath, ec);
437433
return false;
438434
}
439435

440-
if (!timeCompareFilePath)
436+
if (timeCompareFilePath.empty())
441437
return true;
442438

443439
llvm::sys::fs::file_status compareStat;
444440
if (std::error_code ec =
445-
llvm::sys::fs::status(*timeCompareFilePath, compareStat)) {
446-
if (ec != std::errc::no_such_file_or_directory) {
447-
llvm::raw_string_ostream err(error);
448-
err << "could not access path '" << *timeCompareFilePath
449-
<< "': " << ec.message();
450-
return {};
451-
}
441+
llvm::sys::fs::status(timeCompareFilePath, compareStat)) {
442+
if (ec != std::errc::no_such_file_or_directory)
443+
return makeError(timeCompareFilePath, ec);
452444
return true;
453445
}
454446

@@ -477,9 +469,11 @@ static void emitSymbolicInterfaceForClangModule(
477469
return;
478470

479471
// Make sure the `interfaces` directory is created.
480-
std::string error;
481-
if (initSymbolicInterfaceStorePath(indexStorePath, error)) {
482-
diags.diagnose(SourceLoc(), diag::error_create_index_dir, error);
472+
if (auto err = initSymbolicInterfaceStorePath(indexStorePath)) {
473+
llvm::handleAllErrors(std::move(err), [&](const llvm::ECError &ec) {
474+
diags.diagnose(SourceLoc(), diag::error_create_symbolic_interfaces_dir,
475+
ec.convertToErrorCode().message());
476+
});
483477
return;
484478
}
485479

@@ -494,10 +488,16 @@ static void emitSymbolicInterfaceForClangModule(
494488
interfaceOutputPath);
495489

496490
// Check if the symbolic interface file is already up to date.
497-
auto upToDate = isFileUpToDateForOutputFile(
498-
interfaceOutputPath, StringRef(ModFile->FileName), error);
491+
std::string error;
492+
auto upToDate =
493+
isFileUpToDateForOutputFile(interfaceOutputPath, ModFile->FileName);
499494
if (!upToDate) {
500-
diags.diagnose(SourceLoc(), diag::error_index_failed_status_check, error);
495+
llvm::handleAllErrors(
496+
upToDate.takeError(), [&](const llvm::StringError &ec) {
497+
diags.diagnose(SourceLoc(),
498+
diag::error_symbolic_interfaces_failed_status_check,
499+
ec.getMessage());
500+
});
501501
return;
502502
}
503503
if (M->getASTContext().LangOpts.EnableIndexingSystemModuleRemarks) {
@@ -508,43 +508,44 @@ static void emitSymbolicInterfaceForClangModule(
508508
return;
509509

510510
// Output the interface to a temporary file first.
511-
SmallString<128> tempOutputPath;
512-
tempOutputPath = llvm::sys::path::parent_path(interfaceOutputPath);
513-
llvm::sys::path::append(tempOutputPath,
514-
llvm::sys::path::filename(interfaceOutputPath));
511+
SmallString<128> tempOutputPath = interfaceOutputPath;
515512
tempOutputPath += "-%%%%%%%%";
516513
int tempFD;
517514
if (llvm::sys::fs::createUniqueFile(tempOutputPath.str(), tempFD,
518515
tempOutputPath)) {
519516
llvm::raw_string_ostream errOS(error);
520517
errOS << "failed to create temporary file: " << tempOutputPath;
521-
diags.diagnose(SourceLoc(), diag::error_write_index_record, errOS.str());
518+
diags.diagnose(SourceLoc(), diag::error_write_symbolic_interface,
519+
errOS.str());
522520
return;
523521
}
524522

525523
llvm::raw_fd_ostream os(tempFD, /*shouldClose=*/true);
526-
std::unique_ptr<ASTPrinter> printer;
527-
printer.reset(new StreamPrinter(os));
528-
ide::printSymbolicSwiftClangModuleInterface(M, *printer, clangModule);
524+
StreamPrinter printer(os);
525+
ide::printSymbolicSwiftClangModuleInterface(M, printer, clangModule);
529526
os.close();
530527

531528
if (os.has_error()) {
532529
llvm::raw_string_ostream errOS(error);
533530
errOS << "failed to write '" << tempOutputPath
534531
<< "': " << os.error().message();
535-
diags.diagnose(SourceLoc(), diag::error_write_index_record, errOS.str());
532+
diags.diagnose(SourceLoc(), diag::error_write_symbolic_interface,
533+
errOS.str());
536534
os.clear_error();
535+
llvm::sys::fs::remove(tempOutputPath);
537536
return;
538537
}
539538

540539
// Move the resulting output to the destination symbolic interface file.
541540
std::error_code ec = llvm::sys::fs::rename(
542-
/*from=*/tempOutputPath.c_str(), /*to=*/interfaceOutputPath.c_str());
541+
/*from=*/tempOutputPath, /*to=*/interfaceOutputPath);
543542
if (ec) {
544543
llvm::raw_string_ostream errOS(error);
545544
errOS << "failed to rename '" << tempOutputPath << "' to '"
546545
<< interfaceOutputPath << "': " << ec.message();
547-
diags.diagnose(SourceLoc(), diag::error_write_index_record, errOS.str());
546+
diags.diagnose(SourceLoc(), diag::error_write_symbolic_interface,
547+
errOS.str());
548+
llvm::sys::fs::remove(tempOutputPath);
548549
return;
549550
}
550551
}
@@ -637,8 +638,10 @@ static void addModuleDependencies(ArrayRef<ImportedModule> imports,
637638
clang::index::emitIndexDataForModuleFile(clangMod,
638639
clangCI, unitWriter);
639640
// Emit the symbolic interface file in addition to index data.
640-
emitSymbolicInterfaceForClangModule(
641-
clangModUnit, mod, clangMod, indexStorePath, clangCI, diags);
641+
if (indexClangModules)
642+
emitSymbolicInterfaceForClangModule(clangModUnit, mod, clangMod,
643+
indexStorePath, clangCI,
644+
diags);
642645
}
643646
} else {
644647
// Serialized AST file.
@@ -673,8 +676,9 @@ static void addModuleDependencies(ArrayRef<ImportedModule> imports,
673676
SmallVector<ImportedModule, 4> imports;
674677
mod->getImportedModules(imports,
675678
ModuleDecl::ImportFilterKind::Exported);
676-
emitTransitiveClangSymbolicInterfacesForSwiftModuleImports(
677-
imports, indexStorePath, clangCI, diags);
679+
if (indexClangModules)
680+
emitTransitiveClangSymbolicInterfacesForSwiftModuleImports(
681+
imports, indexStorePath, clangCI, diags);
678682
}
679683
}
680684
clang::index::writer::OpaqueModule opaqMod =

test/Interop/Cxx/symbolic-imports/indexing-emit-libcxx-symbolic-module-interface.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
// Verify that symbolic interfaces are emitted.
55
//
6-
// RUN: %target-swift-frontend %t/test.swift -I %t -c -index-system-modules -index-store-path %t/store -enable-experimental-cxx-interop -Rindexing-system-module 2>&1 | %FileCheck --check-prefix=REMARK_NEW %s
6+
// RUN: %target-swift-frontend %t/test.swift -I %t -c -index-system-modules -index-store-path %t/store -enable-experimental-cxx-interop -Rindexing-system-module 2>%t/remarks
7+
// RUN: echo "EOF" >> %t/remarks
8+
// RUN: cat %t/remarks | %FileCheck --check-prefix=REMARK_NEW %s
79
// RUN: ls %t/store/interfaces | %FileCheck --check-prefix=FILES %s
810
// RUN: cat %t/store/interfaces/std* | %FileCheck --check-prefix=CHECK %s
911

@@ -30,7 +32,8 @@ import CxxStdlib
3032
import CxxModule
3133

3234
// REMARK_NEW: remark: emitting symbolic interface at {{.*}}/interfaces/std-{{.*}}.pcm.symbolicswiftinterface{{$}}
33-
// REMARK_NEW: remark: emitting symbolic interface at {{.*}}/interfaces/CxxModule-{{.*}}.pcm.symbolicswiftinterface{{$}}
35+
// REMARK_NEW-NEXT: remark: emitting symbolic interface at {{.*}}/interfaces/CxxModule-{{.*}}.pcm.symbolicswiftinterface{{$}}
36+
// REMARK_NEW-NEXT: EOF
3437

3538
// REMARK_NO_UPDATE: remark: emitting symbolic interface at {{.*}}/interfaces/std-{{.*}}.pcm.symbolicswiftinterface; skipping because it's up to date{{$}}
3639
// REMARK_NO_UPDATE: remark: emitting symbolic interface at {{.*}}/interfaces/CxxModule-{{.*}}.pcm.symbolicswiftinterface; skipping because it's up to date{{$}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
//
4+
// RUN: %target-swift-frontend %t/test.swift -I %t -c -index-system-modules -index-ignore-clang-modules -index-store-path %t/store -enable-experimental-cxx-interop -Rindexing-system-module 2>&1 | %FileCheck %s
5+
// RUN: not ls %t/store/interfaces
6+
7+
//--- Inputs/module.modulemap
8+
module CxxModule {
9+
header "headerA.h"
10+
requires cplusplus
11+
}
12+
13+
//--- Inputs/headerA.h
14+
15+
namespace ns {
16+
int freeFunction(int x, int y);
17+
}
18+
19+
//--- test.swift
20+
21+
import CxxModule
22+
23+
// CHECK-NOT: emitting symbolic interface at

test/Interop/Cxx/symbolic-imports/indexing-emit-symbolic-module-interface.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
// Verify that symbolic interfaces are emitted.
55
//
6-
// RUN: %target-swift-frontend %t/test.swift -I %t -c -index-system-modules -index-store-path %t/store -enable-experimental-cxx-interop -Rindexing-system-module 2>&1 | %FileCheck --check-prefix=REMARK_NEW %s
6+
// RUN: %target-swift-frontend %t/test.swift -I %t -c -index-system-modules -index-store-path %t/store -enable-experimental-cxx-interop -Rindexing-system-module 2>%t/remarks
7+
// RUN: echo "EOF" >> %t/remarks
8+
// RUN: cat %t/remarks | %FileCheck --check-prefixes=REMARK_NEW,REMARK_INITIAL %s
79
// RUN: ls %t/store/interfaces | %FileCheck --check-prefix=FILES %s
810
// RUN: cat %t/store/interfaces/CxxModule* | %FileCheck --check-prefix=CHECK %s
911

@@ -88,7 +90,9 @@ using MyType2 = TransitiveStruct<int>;
8890

8991
import CxxModule
9092

93+
// REMARK_INITIAL: remark: emitting symbolic interface at {{.*}}{{/|\\}}interfaces{{/|\\}}CxxShim-{{.*}}.pcm.symbolicswiftinterface{{$}}
9194
// REMARK_NEW: remark: emitting symbolic interface at {{.*}}{{/|\\}}interfaces{{/|\\}}CxxModule-{{.*}}.pcm.symbolicswiftinterface{{$}}
95+
// REMARK_INITIAL-NEXT: EOF
9296

9397
// REMARK_NO_UPDATE: remark: emitting symbolic interface at {{.*}}{{/|\\}}interfaces{{/|\\}}CxxModule-{{.*}}.pcm.symbolicswiftinterface; skipping because it's up to date{{$}}
9498

0 commit comments

Comments
 (0)