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,
2176
2176
for (auto redecl : namespaceDecl->redecls ()) {
2177
2177
for (auto member : redecl->decls ()) {
2178
2178
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) {
2181
2185
if (auto import =
2182
2186
ctx.getClangModuleLoader ()->importDeclDirectly (spec))
2183
2187
if (addedMembers.insert (import ).second )
Original file line number Diff line number Diff line change @@ -8745,9 +8745,19 @@ void ClangImporter::Implementation::importAttributes(
8745
8745
// Map __attribute__((warn_unused_result)).
8746
8746
if (!ClangDecl->hasAttr <clang::WarnUnusedResultAttr>()) {
8747
8747
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)
8749
8760
MD->getAttrs ().add (new (C) DiscardableResultAttr (/* implicit*/ true ));
8750
- }
8751
8761
}
8752
8762
}
8753
8763
// Map __attribute__((const)).
Original file line number Diff line number Diff line change @@ -1837,7 +1837,8 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
1837
1837
dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType ())) {
1838
1838
importedType = {findGenericTypeInGenericDecls (templateType, genericParams),
1839
1839
false };
1840
- } else if (!isa<clang::RecordType>(clangDecl->getReturnType ()) ||
1840
+ } else if (!(isa<clang::RecordType>(clangDecl->getReturnType ()) ||
1841
+ isa<clang::TemplateSpecializationType>(clangDecl->getReturnType ())) ||
1841
1842
// TODO: we currently don't lazily load operator return types, but
1842
1843
// this should be trivial to add.
1843
1844
clangDecl->isOverloadedOperator ()) {
You can’t perform that action at this time.
0 commit comments