Skip to content

Commit a44a98b

Browse files
committed
[interop] clear importer decl when emitting symbolic interface
This ensures that our interface do not reference already instantiated and imported specializations.
1 parent 0e60775 commit a44a98b

File tree

5 files changed

+62
-24
lines changed

5 files changed

+62
-24
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -562,10 +562,6 @@ struct PrintOptions {
562562
/// If false, we print them as ordinary associated types.
563563
bool PrintPrimaryAssociatedTypes = true;
564564

565-
/// If true, import and print C++ declarations with symbolic import feature
566-
/// enabled.
567-
bool PrintSymbolicCXXDecls = false;
568-
569565
/// If this is not \c nullptr then function bodies (including accessors
570566
/// and constructors) will be printed by this function.
571567
std::function<void(const ValueDecl *, ASTPrinter &)> FunctionBody;

include/swift/ClangImporter/ClangImporter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,8 @@ class ClangImporter final : public ClangModuleLoader {
556556
/// of the provided baseType.
557557
void diagnoseMemberValue(const DeclName &name, const Type &baseType) override;
558558

559-
/// Enable/disable the symbolic import experimental feature.
560-
void enableSymbolicImportFeature(bool isEnabled = true);
559+
/// Enable the symbolic import experimental feature for the given callback.
560+
void withSymbolicFeatureEnabled(llvm::function_ref<void(void)> callback);
561561
};
562562

563563
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,

lib/ClangImporter/ClangImporter.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6565,9 +6565,17 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
65656565
return {CustomRefCountingOperationResult::tooManyFound, nullptr, name};
65666566
}
65676567

6568-
void ClangImporter::enableSymbolicImportFeature(bool isEnabled) {
6569-
Impl.importSymbolicCXXDecls = isEnabled;
6570-
Impl.nameImporter->enableSymbolicImportFeature(isEnabled);
6568+
void ClangImporter::withSymbolicFeatureEnabled(
6569+
llvm::function_ref<void(void)> callback) {
6570+
llvm::SaveAndRestore<bool> oldImportSymbolicCXXDecls(
6571+
Impl.importSymbolicCXXDecls, true);
6572+
Impl.nameImporter->enableSymbolicImportFeature(true);
6573+
auto importedDeclsCopy = Impl.ImportedDecls;
6574+
Impl.ImportedDecls.clear();
6575+
callback();
6576+
Impl.ImportedDecls = std::move(importedDeclsCopy);
6577+
Impl.nameImporter->enableSymbolicImportFeature(
6578+
oldImportSymbolicCXXDecls.get());
65716579
}
65726580

65736581
bool importer::requiresCPlusPlus(const clang::Module *module) {

lib/IDE/ModuleInterfacePrinting.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -544,18 +544,6 @@ void swift::ide::printModuleInterface(
544544
auto &SwiftContext = TopLevelMod->getASTContext();
545545
auto &Importer =
546546
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
547-
if (Options.PrintSymbolicCXXDecls)
548-
Importer.enableSymbolicImportFeature(true);
549-
struct SymbolicImportRAII {
550-
bool PrintSymbolicCXXDecls;
551-
ClangImporter &Importer;
552-
SymbolicImportRAII(bool PrintSymbolicCXXDecls, ClangImporter &Importer)
553-
: PrintSymbolicCXXDecls(PrintSymbolicCXXDecls), Importer(Importer) {}
554-
~SymbolicImportRAII() {
555-
if (PrintSymbolicCXXDecls)
556-
Importer.enableSymbolicImportFeature(false);
557-
}
558-
} deferDisableSymbolicImport(Options.PrintSymbolicCXXDecls, Importer);
559547

560548
auto AdjustedOptions = Options;
561549
adjustPrintOptions(AdjustedOptions);
@@ -1159,9 +1147,14 @@ void swift::ide::printSymbolicSwiftClangModuleInterface(
11591147
opts |= ModuleTraversal::VisitSubmodules;
11601148
auto popts =
11611149
PrintOptions::printModuleInterface(/*printFullConvention=*/false);
1162-
popts.PrintSymbolicCXXDecls = true;
11631150
popts.PrintDocumentationComments = false;
11641151
popts.PrintRegularClangComments = false;
1165-
printModuleInterface(M, {}, opts, Printer, popts,
1166-
/*SynthesizeExtensions=*/false);
1152+
1153+
auto &SwiftContext = M->getTopLevelModule()->getASTContext();
1154+
auto &Importer =
1155+
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
1156+
Importer.withSymbolicFeatureEnabled([&]() {
1157+
printModuleInterface(M, {}, opts, Printer, popts,
1158+
/*SynthesizeExtensions=*/false);
1159+
});
11671160
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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-store-path %t/store -enable-experimental-cxx-interop 2>&1
5+
// RUN: cat %t/store/interfaces/CxxModule* | %FileCheck --check-prefix=CHECK %s
6+
7+
//--- Inputs/module.modulemap
8+
module CxxModule {
9+
header "header.h"
10+
requires cplusplus
11+
}
12+
13+
//--- Inputs/header.h
14+
15+
namespace ns {
16+
template<class T>
17+
struct TemplateRecord {
18+
void methodFunc(int x) const;
19+
};
20+
}
21+
22+
using TemplateRecordInt = ns::TemplateRecord<int>;
23+
24+
//--- test.swift
25+
26+
import CxxModule
27+
28+
public func useConcreteTemplate() {
29+
let x = TemplateRecordInt()
30+
x.methodFunc(2)
31+
}
32+
33+
// CHECK: // Swift interface for module 'CxxModule'
34+
// CHECK: public enum ns {
35+
// CHECK-EMPTY:
36+
// CHECK-NEXT: public struct TemplateRecord {
37+
// CHECK-EMPTY:
38+
// CHECK-NEXT: public func methodFunc()
39+
// CHECK-NEXT:}
40+
// CHECK-NEXT:}
41+
// CHECK-NEXT: public typealias TemplateRecordInt = ns.TemplateRecord

0 commit comments

Comments
 (0)