@@ -2738,72 +2738,87 @@ static void addNamespaceMembers(Decl *decl,
27382738 if (declOwner && declOwner != redeclOwner->getTopLevelModule ())
27392739 continue ;
27402740 }
2741- for (auto member : redecl->decls ()) {
2742- if (auto classTemplate = dyn_cast<clang::ClassTemplateDecl>(member)) {
2743- // Add all specializations to a worklist so we don't accidentally mutate
2744- // the list of decls we're iterating over.
2745- llvm::SmallPtrSet<const clang::ClassTemplateSpecializationDecl *, 16 > specWorklist;
2746- for (auto spec : classTemplate->specializations ())
2747- specWorklist.insert (spec);
2748- for (auto spec : specWorklist) {
2749- if (auto import =
2750- ctx.getClangModuleLoader ()->importDeclDirectly (spec))
2751- if (addedMembers.insert (import ).second )
2752- members.push_back (import );
2753- }
2754- }
27552741
2756- auto lookupAndAddMembers = [&](DeclName name) {
2757- auto allResults = evaluateOrDefault (
2758- ctx.evaluator , ClangDirectLookupRequest ({decl, redecl, name}), {});
2759-
2760- for (auto found : allResults) {
2761- auto clangMember = cast<clang::NamedDecl *>(found);
2762- if (auto importedDecl =
2763- ctx.getClangModuleLoader ()->importDeclDirectly (clangMember)) {
2764- if (addedMembers.insert (importedDecl).second ) {
2765- members.push_back (importedDecl);
2766-
2767- // Handle macro-expanded declarations.
2768- importedDecl->visitAuxiliaryDecls ([&](Decl *decl) {
2769- auto valueDecl = dyn_cast<ValueDecl>(decl);
2770- if (!valueDecl)
2771- return ;
2772-
2773- // Bail out if the auxiliary decl was not produced by a macro.
2774- auto module = decl->getDeclContext ()->getParentModule ();
2775- auto *sf = module ->getSourceFileContainingLocation (decl->getLoc ());
2776- if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
2777- return ;
2778-
2779- members.push_back (valueDecl);
2780- });
2742+ std::function<void (clang::DeclContext *)> addDeclsFromContext =
2743+ [&](clang::DeclContext *declContext) {
2744+ for (auto member : declContext->decls ()) {
2745+ if (auto classTemplate =
2746+ dyn_cast<clang::ClassTemplateDecl>(member)) {
2747+ // Add all specializations to a worklist so we don't accidentally
2748+ // mutate the list of decls we're iterating over.
2749+ llvm::SmallPtrSet<const clang::ClassTemplateSpecializationDecl *,
2750+ 16 >
2751+ specWorklist;
2752+ for (auto spec : classTemplate->specializations ())
2753+ specWorklist.insert (spec);
2754+ for (auto spec : specWorklist) {
2755+ if (auto import =
2756+ ctx.getClangModuleLoader ()->importDeclDirectly (spec))
2757+ if (addedMembers.insert (import ).second )
2758+ members.push_back (import );
2759+ }
27812760 }
2782- }
2783- }
2784- };
27852761
2786- auto namedDecl = dyn_cast<clang::NamedDecl>(member);
2787- if (!namedDecl)
2788- continue ;
2789- auto name = ctx.getClangModuleLoader ()->importName (namedDecl);
2790- if (!name)
2791- continue ;
2792- lookupAndAddMembers (name);
2793-
2794- // Unscoped enums could have their enumerators present
2795- // in the parent namespace.
2796- if (auto *ed = dyn_cast<clang::EnumDecl>(member)) {
2797- if (!ed->isScoped ()) {
2798- for (const auto *ecd : ed->enumerators ()) {
2799- auto name = ctx.getClangModuleLoader ()->importName (ecd);
2800- if (!name)
2762+ auto lookupAndAddMembers = [&](clang::NamedDecl *namedDecl) {
2763+ auto name = ctx.getClangModuleLoader ()->importName (namedDecl);
2764+ if (!name)
2765+ return ;
2766+
2767+ auto allResults = evaluateOrDefault (
2768+ ctx.evaluator , ClangDirectLookupRequest ({decl, redecl, name}),
2769+ {});
2770+
2771+ for (auto found : allResults) {
2772+ auto clangMember = cast<clang::NamedDecl *>(found);
2773+ if (auto importedDecl =
2774+ ctx.getClangModuleLoader ()->importDeclDirectly (
2775+ clangMember)) {
2776+ if (addedMembers.insert (importedDecl).second ) {
2777+ members.push_back (importedDecl);
2778+
2779+ // Handle macro-expanded declarations.
2780+ importedDecl->visitAuxiliaryDecls ([&](Decl *decl) {
2781+ auto valueDecl = dyn_cast<ValueDecl>(decl);
2782+ if (!valueDecl)
2783+ return ;
2784+
2785+ // Bail out if the auxiliary decl was not produced by a
2786+ // macro.
2787+ auto module = decl->getDeclContext ()->getParentModule ();
2788+ auto *sf = module ->getSourceFileContainingLocation (
2789+ decl->getLoc ());
2790+ if (!sf || sf->Kind != SourceFileKind::MacroExpansion)
2791+ return ;
2792+
2793+ members.push_back (valueDecl);
2794+ });
2795+ }
2796+ }
2797+ }
2798+ };
2799+
2800+ // Look through `extern` blocks.
2801+ if (auto linkageSpecDecl = dyn_cast<clang::LinkageSpecDecl>(member))
2802+ addDeclsFromContext (linkageSpecDecl);
2803+
2804+ auto namedDecl = dyn_cast<clang::NamedDecl>(member);
2805+ if (!namedDecl)
28012806 continue ;
2802- lookupAndAddMembers (name);
2807+ lookupAndAddMembers (namedDecl);
2808+
2809+ // Unscoped enums could have their enumerators present
2810+ // in the parent namespace.
2811+ if (auto *ed = dyn_cast<clang::EnumDecl>(member)) {
2812+ if (!ed->isScoped ()) {
2813+ for (auto *ecd : ed->enumerators ()) {
2814+ lookupAndAddMembers (ecd);
2815+ }
2816+ }
2817+ }
28032818 }
2804- }
2805- }
2806- }
2819+ };
2820+
2821+ addDeclsFromContext (redecl);
28072822 }
28082823}
28092824
0 commit comments