File tree Expand file tree Collapse file tree 3 files changed +20
-5
lines changed Expand file tree Collapse file tree 3 files changed +20
-5
lines changed Original file line number Diff line number Diff 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 )
Original file line number Diff line number Diff 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)).
Original file line number Diff line number Diff 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 ()) {
You can’t perform that action at this time.
0 commit comments