Skip to content

Commit 6e9bf50

Browse files
committed
[cxx-interop] Lazily load the result of imported functions.
Note: we only lazily load the result if it's a record, because otherwise it's trivial to load when importing the function. Also, we still eagerly import operator's results types.
1 parent d9110de commit 6e9bf50

File tree

7 files changed

+37
-5
lines changed

7 files changed

+37
-5
lines changed

include/swift/AST/ClangModuleLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ class ClangModuleLoader : public ModuleLoader {
238238
SubstitutionMap subst) = 0;
239239

240240
virtual bool isCXXMethodMutating(const clang::CXXMethodDecl *method) = 0;
241+
242+
virtual Type importFunctionReturnType(const clang::FunctionDecl *clangDecl,
243+
DeclContext *dc) = 0;
241244
};
242245

243246
/// Describes a C++ template instantiation error.

include/swift/ClangImporter/ClangImporter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ class ClangImporter final : public ClangModuleLoader {
458458
DeclName importName(const clang::NamedDecl *D,
459459
clang::DeclarationName givenName);
460460

461+
Type importFunctionReturnType(const clang::FunctionDecl *clangDecl,
462+
DeclContext *dc) override;
463+
461464
Optional<std::string>
462465
getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
463466
StringRef SwiftPCHHash);

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7773,7 +7773,7 @@ FuncDecl *FuncDecl::createImported(ASTContext &Context, SourceLoc FuncLoc,
77737773
Type FnRetType,
77747774
GenericParamList *GenericParams,
77757775
DeclContext *Parent, ClangNode ClangN) {
7776-
assert(ClangN && FnRetType);
7776+
assert(ClangN);
77777777
auto *const FD = FuncDecl::createImpl(
77787778
Context, SourceLoc(), StaticSpellingKind::None, FuncLoc, Name, NameLoc,
77797779
Async, SourceLoc(), Throws, SourceLoc(), GenericParams, Parent, ClangN);

lib/ClangImporter/ClangImporter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4234,6 +4234,19 @@ importName(const clang::NamedDecl *D,
42344234
getDeclName();
42354235
}
42364236

4237+
Type ClangImporter::importFunctionReturnType(
4238+
const clang::FunctionDecl *clangDecl, DeclContext *dc) {
4239+
bool isInSystemModule =
4240+
cast<ClangModuleUnit>(dc->getModuleScopeContext())->isSystemModule();
4241+
bool allowNSUIntegerAsInt =
4242+
Impl.shouldAllowNSUIntegerAsInt(isInSystemModule, clangDecl);
4243+
if (auto imported =
4244+
Impl.importFunctionReturnType(dc, clangDecl, allowNSUIntegerAsInt)
4245+
.getType())
4246+
return imported;
4247+
return dc->getASTContext().getNeverType();
4248+
}
4249+
42374250
bool ClangImporter::isInOverlayModuleForImportedModule(
42384251
const DeclContext *overlayDC,
42394252
const DeclContext *importedDC) {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4162,8 +4162,9 @@ namespace {
41624162
if (!bodyParams)
41634163
return nullptr;
41644164

4165-
importedType =
4166-
Impl.importFunctionReturnType(dc, decl, allowNSUIntegerAsInt);
4165+
if (decl->getReturnType()->isScalarType())
4166+
importedType =
4167+
Impl.importFunctionReturnType(dc, decl, allowNSUIntegerAsInt);
41674168
} else {
41684169
// Import the function type. If we have parameters, make sure their
41694170
// names get into the resulting function type.
@@ -4199,7 +4200,7 @@ namespace {
41994200
name = DeclName(Impl.SwiftContext, name.getBaseName(), bodyParams);
42004201
}
42014202

4202-
if (!importedType)
4203+
if (!bodyParams)
42034204
return nullptr;
42044205

42054206
auto loc = Impl.importSourceLoc(decl->getLocation());

lib/ClangImporter/ImportType.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1827,12 +1827,17 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
18271827
bool allowNSUIntegerAsInt =
18281828
shouldAllowNSUIntegerAsInt(isFromSystemModule, clangDecl);
18291829

1830+
// Only eagerly import the return type if it's not too expensive (the current
1831+
// huristic for that is if it's not a record type).
18301832
ImportedType importedType;
18311833
if (auto templateType =
18321834
dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType())) {
18331835
importedType = {findGenericTypeInGenericDecls(templateType, genericParams),
18341836
false};
1835-
} else {
1837+
} else if (!isa<clang::RecordType>(clangDecl->getReturnType()) ||
1838+
// TODO: we currently don't lazily load operator return types, but
1839+
// this should be trivial to add.
1840+
clangDecl->isOverloadedOperator()) {
18361841
importedType =
18371842
importFunctionReturnType(dc, clangDecl, allowNSUIntegerAsInt);
18381843
if (!importedType)

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,13 @@ ResultTypeRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
20152015
resultTyRepr = cast<SubscriptDecl>(decl)->getElementTypeRepr();
20162016
}
20172017

2018+
if (!resultTyRepr && decl->getClangDecl() &&
2019+
isa<clang::FunctionDecl>(decl->getClangDecl())) {
2020+
auto clangFn = cast<clang::FunctionDecl>(decl->getClangDecl());
2021+
return ctx.getClangModuleLoader()->importFunctionReturnType(
2022+
clangFn, decl->getDeclContext());
2023+
}
2024+
20182025
// Nothing to do if there's no result type.
20192026
if (resultTyRepr == nullptr)
20202027
return TupleType::getEmpty(ctx);

0 commit comments

Comments
 (0)