@@ -2738,72 +2738,87 @@ static void addNamespaceMembers(Decl *decl,
2738
2738
if (declOwner && declOwner != redeclOwner->getTopLevelModule ())
2739
2739
continue ;
2740
2740
}
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
- }
2755
2741
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
+ }
2781
2760
}
2782
- }
2783
- }
2784
- };
2785
2761
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)
2801
2806
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
+ }
2803
2818
}
2804
- }
2805
- }
2806
- }
2819
+ };
2820
+
2821
+ addDeclsFromContext (redecl);
2807
2822
}
2808
2823
}
2809
2824
0 commit comments