Skip to content

Commit 1a763c0

Browse files
authored
Merge pull request swiftlang#63336 from hyp/eng/emit-symbolic-interfaces
[interop] Emit symbolic interfaces while indexing
2 parents 30531c2 + c352200 commit 1a763c0

22 files changed

+758
-32
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,17 @@ REMARK(remark_indexing_system_module,none,
271271
"%select{|; skipping because of a broken swiftinterface}1",
272272
(StringRef, bool))
273273

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))
280+
REMARK(remark_emitting_symbolic_interface_module,none,
281+
"emitting symbolic interface at %0"
282+
"%select{|; skipping because it's up to date}1",
283+
(StringRef, bool))
284+
274285
ERROR(error_wrong_number_of_arguments,none,
275286
"wrong number of '%0' arguments (expected %1, got %2)",
276287
(StringRef, int, int))

include/swift/Basic/Features.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ EXPERIMENTAL_FEATURE(BuiltinMacros, false)
167167
/// declare an attribute which is discoverable and constructable at runtime.
168168
EXPERIMENTAL_FEATURE(RuntimeDiscoverableAttrs, false)
169169

170+
/// Import C++ class templates as semantically-meaningless symbolic
171+
/// Swift types and C++ methods as symbolic functions with blank
172+
/// signatures.
173+
EXPERIMENTAL_FEATURE(ImportSymbolicCXXDecls, false)
174+
170175
#undef EXPERIMENTAL_FEATURE
171176
#undef UPCOMING_FEATURE
172177
#undef SUPPRESSIBLE_LANGUAGE_FEATURE

include/swift/ClangImporter/ClangImporter.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,9 @@ class ClangImporter final : public ClangModuleLoader {
555555
/// Emit diagnostics for declarations named name that are members
556556
/// of the provided baseType.
557557
void diagnoseMemberValue(const DeclName &name, const Type &baseType) override;
558+
559+
/// Enable the symbolic import experimental feature for the given callback.
560+
void withSymbolicFeatureEnabled(llvm::function_ref<void(void)> callback);
558561
};
559562

560563
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,
@@ -569,6 +572,13 @@ getModuleCachePathFromClang(const clang::CompilerInstance &Instance);
569572
/// Whether the given parameter name identifies a completion handler.
570573
bool isCompletionHandlerParamName(StringRef paramName);
571574

575+
namespace importer {
576+
577+
/// Returns true if the given module has a 'cplusplus' requirement.
578+
bool requiresCPlusPlus(const clang::Module *module);
579+
580+
} // namespace importer
581+
572582
} // end namespace swift
573583

574584
#endif

include/swift/IDE/ModuleInterfacePrinting.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include <string>
2020
#include <vector>
2121

22+
namespace clang {
23+
class Module;
24+
}
25+
2226
namespace swift {
2327
class ASTContext;
2428
class ASTPrinter;
@@ -68,6 +72,10 @@ void printHeaderInterface(StringRef Filename, ASTContext &Ctx,
6872
void printSwiftSourceInterface(SourceFile &File, ASTPrinter &Printer,
6973
const PrintOptions &Options);
7074

75+
/// Print the symbolic Swift interface for a given imported clang module.
76+
void printSymbolicSwiftClangModuleInterface(ModuleDecl *M, ASTPrinter &Printer,
77+
const clang::Module *clangModule);
78+
7179
} // namespace ide
7280

7381
} // namespace swift

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,6 +3169,8 @@ static bool usesFeatureBuiltinMacros(Decl *decl) {
31693169
return false;
31703170
}
31713171

3172+
static bool usesFeatureImportSymbolicCXXDecls(Decl *decl) { return false; }
3173+
31723174
static void
31733175
suppressingFeatureNoAsyncAvailability(PrintOptions &options,
31743176
llvm::function_ref<void()> action) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,13 +2263,13 @@ ClangImporter::Implementation::Implementation(
22632263
!ctx.ClangImporterOpts.BridgingHeader.empty()),
22642264
DisableOverlayModules(ctx.ClangImporterOpts.DisableOverlayModules),
22652265
EnableClangSPI(ctx.ClangImporterOpts.EnableClangSPI),
2266+
importSymbolicCXXDecls(
2267+
ctx.LangOpts.hasFeature(Feature::ImportSymbolicCXXDecls)),
22662268
IsReadingBridgingPCH(false),
22672269
CurrentVersion(ImportNameVersion::fromOptions(ctx.LangOpts)),
2268-
Walker(DiagnosticWalker(*this)),
2269-
BuffersForDiagnostics(ctx.SourceMgr),
2270+
Walker(DiagnosticWalker(*this)), BuffersForDiagnostics(ctx.SourceMgr),
22702271
BridgingHeaderLookupTable(new SwiftLookupTable(nullptr)),
2271-
platformAvailability(ctx.LangOpts),
2272-
nameImporter(),
2272+
platformAvailability(ctx.LangOpts), nameImporter(),
22732273
DisableSourceImport(ctx.ClangImporterOpts.DisableSourceImport),
22742274
DWARFImporter(dwarfImporterDelegate) {}
22752275

@@ -6558,3 +6558,32 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
65586558

65596559
return {CustomRefCountingOperationResult::tooManyFound, nullptr, name};
65606560
}
6561+
6562+
void ClangImporter::withSymbolicFeatureEnabled(
6563+
llvm::function_ref<void(void)> callback) {
6564+
llvm::SaveAndRestore<bool> oldImportSymbolicCXXDecls(
6565+
Impl.importSymbolicCXXDecls, true);
6566+
Impl.nameImporter->enableSymbolicImportFeature(true);
6567+
auto importedDeclsCopy = Impl.ImportedDecls;
6568+
Impl.ImportedDecls.clear();
6569+
callback();
6570+
Impl.ImportedDecls = std::move(importedDeclsCopy);
6571+
Impl.nameImporter->enableSymbolicImportFeature(
6572+
oldImportSymbolicCXXDecls.get());
6573+
}
6574+
6575+
bool importer::requiresCPlusPlus(const clang::Module *module) {
6576+
// The libc++ modulemap doesn't currently declare the requirement.
6577+
if (module->getTopLevelModuleName() == "std")
6578+
return true;
6579+
6580+
// Modulemaps often declare the requirement for the top-level module only.
6581+
if (auto parent = module->Parent) {
6582+
if (requiresCPlusPlus(parent))
6583+
return true;
6584+
}
6585+
6586+
return llvm::any_of(module->Requirements, [](clang::Module::Requirement req) {
6587+
return req.first == "cplusplus";
6588+
});
6589+
}

lib/ClangImporter/ImportDecl.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,8 @@ namespace {
20052005
}
20062006

20072007
// TODO(https://github.com/apple/swift/issues/56206): Fix this once we support dependent types.
2008-
if (decl->getTypeForDecl()->isDependentType()) {
2008+
if (decl->getTypeForDecl()->isDependentType() &&
2009+
!Impl.importSymbolicCXXDecls) {
20092010
Impl.addImportDiagnostic(
20102011
decl, Diagnostic(
20112012
diag::record_is_dependent,
@@ -2682,6 +2683,12 @@ namespace {
26822683

26832684
Decl *VisitClassTemplateSpecializationDecl(
26842685
const clang::ClassTemplateSpecializationDecl *decl) {
2686+
// Treat a specific specialization like the unspecialized class template
2687+
// when importing it in symbolic mode.
2688+
if (Impl.importSymbolicCXXDecls)
2689+
return Impl.importDecl(decl->getSpecializedTemplate(),
2690+
Impl.CurrentVersion);
2691+
26852692
// Before we go any further, check if we've already got tens of thousands
26862693
// of specializations. If so, it means we're likely instantiating a very
26872694
// deep/complex template, or we've run into an infinite loop. In either
@@ -3068,6 +3075,8 @@ namespace {
30683075
Impl.SwiftContext, SourceLoc(), templateParams, SourceLoc());
30693076
}
30703077

3078+
bool importFuncWithoutSignature =
3079+
isa<clang::CXXMethodDecl>(decl) && Impl.importSymbolicCXXDecls;
30713080
if (!dc->isModuleScopeContext() && !isa<clang::CXXMethodDecl>(decl)) {
30723081
// Handle initializers.
30733082
if (name.getBaseName() == DeclBaseName::createConstructor()) {
@@ -3133,12 +3142,17 @@ namespace {
31333142
importedType =
31343143
Impl.importFunctionReturnType(dc, decl, allowNSUIntegerAsInt);
31353144
} else {
3136-
// Import the function type. If we have parameters, make sure their
3137-
// names get into the resulting function type.
3138-
importedType = Impl.importFunctionParamsAndReturnType(
3139-
dc, decl, {decl->param_begin(), decl->param_size()},
3140-
decl->isVariadic(), isInSystemModule(dc), name, bodyParams,
3141-
templateParams);
3145+
if (importFuncWithoutSignature) {
3146+
importedType = ImportedType{Impl.SwiftContext.getVoidType(), false};
3147+
bodyParams = ParameterList::createEmpty(Impl.SwiftContext);
3148+
} else {
3149+
// Import the function type. If we have parameters, make sure their
3150+
// names get into the resulting function type.
3151+
importedType = Impl.importFunctionParamsAndReturnType(
3152+
dc, decl, {decl->param_begin(), decl->param_size()},
3153+
decl->isVariadic(), isInSystemModule(dc), name, bodyParams,
3154+
templateParams);
3155+
}
31423156

31433157
if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
31443158
if (mdecl->isStatic()) {
@@ -3222,7 +3236,7 @@ namespace {
32223236
}
32233237
}
32243238

3225-
if (importedName.isSubscriptAccessor()) {
3239+
if (importedName.isSubscriptAccessor() && !importFuncWithoutSignature) {
32263240
assert(func->getParameters()->size() == 1);
32273241
auto typeDecl = dc->getSelfNominalTypeDecl();
32283242
auto parameter = func->getParameters()->get(0);
@@ -3497,6 +3511,12 @@ namespace {
34973511
auto name = importedName.getDeclName().getBaseIdentifier();
34983512
if (name.empty())
34993513
return nullptr;
3514+
3515+
if (Impl.importSymbolicCXXDecls)
3516+
// Import an unspecialized C++ class template as a Swift value/class
3517+
// type in symbolic mode.
3518+
return Impl.importDecl(decl->getTemplatedDecl(), Impl.CurrentVersion);
3519+
35003520
auto loc = Impl.importSourceLoc(decl->getLocation());
35013521
auto dc = Impl.importDeclContextOf(
35023522
decl, importedName.getEffectiveContext());

lib/ClangImporter/ImportName.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,6 +2173,11 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
21732173

21742174
if (auto classTemplateSpecDecl =
21752175
dyn_cast<clang::ClassTemplateSpecializationDecl>(D)) {
2176+
/// Symbolic specializations get imported as the symbolic class template
2177+
/// type.
2178+
if (importSymbolicCXXDecls)
2179+
return importNameImpl(classTemplateSpecDecl->getSpecializedTemplate(),
2180+
version, givenName);
21762181
if (!isa<clang::ClassTemplatePartialSpecializationDecl>(D)) {
21772182

21782183
auto &astContext = classTemplateSpecDecl->getASTContext();

lib/ClangImporter/ImportName.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,15 @@ class NameImporter {
387387
llvm::DenseMap<std::pair<const clang::ObjCInterfaceDecl *, char>,
388388
std::unique_ptr<InheritedNameSet>> allProperties;
389389

390+
bool importSymbolicCXXDecls;
391+
390392
public:
391393
NameImporter(ASTContext &ctx, const PlatformAvailability &avail,
392394
clang::Sema &cSema)
393395
: swiftCtx(ctx), availability(avail), clangSema(cSema),
394-
enumInfos(clangSema.getPreprocessor()) {}
396+
enumInfos(clangSema.getPreprocessor()),
397+
importSymbolicCXXDecls(
398+
ctx.LangOpts.hasFeature(Feature::ImportSymbolicCXXDecls)) {}
395399

396400
/// Determine the Swift name for a Clang decl
397401
ImportedName importName(const clang::NamedDecl *decl,
@@ -454,6 +458,10 @@ class NameImporter {
454458
clang::ObjCInterfaceDecl *classDecl,
455459
bool forInstance);
456460

461+
inline void enableSymbolicImportFeature(bool isEnabled) {
462+
importSymbolicCXXDecls = isEnabled;
463+
}
464+
457465
private:
458466
bool enableObjCInterop() const { return swiftCtx.LangOpts.EnableObjCInterop; }
459467

lib/ClangImporter/ImportType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ bool ClangImporter::Implementation::isOverAligned(const clang::TypeDecl *decl) {
6666
}
6767

6868
bool ClangImporter::Implementation::isOverAligned(clang::QualType type) {
69+
// Do not check type layout for a clang type in symbolic mode as the
70+
// type could be a dependent type.
71+
if (importSymbolicCXXDecls)
72+
return false;
6973
auto align = getClangASTContext().getTypeAlignInChars(type);
7074
return align > clang::CharUnits::fromQuantity(MaximumAlignment);
7175
}

0 commit comments

Comments
 (0)