Skip to content

Commit be52565

Browse files
authored
Merge pull request #39907 from zoecarver/fix-lazy-loading-result-types
[cxx-interop] Fix lazy loading for result types.
2 parents 0184075 + a5c0eb0 commit be52565

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,8 +2176,12 @@ static void addNamespaceMembers(Decl *decl,
21762176
for (auto redecl : namespaceDecl->redecls()) {
21772177
for (auto member : redecl->decls()) {
21782178
if (auto classTemplate = dyn_cast<clang::ClassTemplateDecl>(member)) {
2179-
// Hack in the class template specializations that live here.
2180-
for (auto spec : classTemplate->specializations()) {
2179+
// Add all specializtaions to a worklist so we don't accidently mutate
2180+
// the list of decls we're iterating over.
2181+
llvm::SmallPtrSet<const clang::ClassTemplateSpecializationDecl *, 16> specWorklist;
2182+
for (auto spec : classTemplate->specializations())
2183+
specWorklist.insert(spec);
2184+
for (auto spec : specWorklist) {
21812185
if (auto import =
21822186
ctx.getClangModuleLoader()->importDeclDirectly(spec))
21832187
if (addedMembers.insert(import).second)

lib/ClangImporter/ImportDecl.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8745,9 +8745,19 @@ void ClangImporter::Implementation::importAttributes(
87458745
// Map __attribute__((warn_unused_result)).
87468746
if (!ClangDecl->hasAttr<clang::WarnUnusedResultAttr>()) {
87478747
if (auto MD = dyn_cast<FuncDecl>(MappedDecl)) {
8748-
if (!MD->getResultInterfaceType()->isVoid()) {
8748+
// Ask if the clang function's return type is void to prevent eagerly
8749+
// loading the result type of the imported function.
8750+
bool hasVoidReturnType = false;
8751+
if (auto clangFunction = dyn_cast<clang::FunctionDecl>(ClangDecl))
8752+
hasVoidReturnType = clangFunction->getReturnType()->isVoidType();
8753+
if (auto clangMethod = dyn_cast<clang::ObjCMethodDecl>(ClangDecl))
8754+
hasVoidReturnType = clangMethod->getReturnType()->isVoidType();
8755+
// Async functions might get re-written to be non-void, so if this is an
8756+
// async function, eagerly load the result type and check.
8757+
if (MD->hasAsync())
8758+
hasVoidReturnType = MD->getResultInterfaceType()->isVoid();
8759+
if (!hasVoidReturnType)
87498760
MD->getAttrs().add(new (C) DiscardableResultAttr(/*implicit*/true));
8750-
}
87518761
}
87528762
}
87538763
// Map __attribute__((const)).

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,8 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
18371837
dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType())) {
18381838
importedType = {findGenericTypeInGenericDecls(templateType, genericParams),
18391839
false};
1840-
} else if (!isa<clang::RecordType>(clangDecl->getReturnType()) ||
1840+
} else if (!(isa<clang::RecordType>(clangDecl->getReturnType()) ||
1841+
isa<clang::TemplateSpecializationType>(clangDecl->getReturnType())) ||
18411842
// TODO: we currently don't lazily load operator return types, but
18421843
// this should be trivial to add.
18431844
clangDecl->isOverloadedOperator()) {

0 commit comments

Comments
 (0)