@@ -2808,6 +2808,8 @@ checkFileFilters(Decl const* D)
28082808
28092809 // Call the non-cached version of this function
28102810 bool const ok = checkFileFilters (fileInfo->full_path );
2811+
2812+ // Add to cache
28112813 fileInfo->passesFilters .emplace (ok);
28122814 return *fileInfo->passesFilters ;
28132815}
@@ -2943,45 +2945,41 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
29432945 // 1) The symbol strictly matches one of the patterns
29442946 for (auto const & [patterns, patternsMode] : patternsAndModes)
29452947 {
2946- if (!patterns->empty ())
2948+ MRDOCS_CHECK_OR_CONTINUE (!patterns->empty ());
2949+ if (checkSymbolFiltersImpl<Strict>(*patterns, symbolName))
29472950 {
2948- if (checkSymbolFiltersImpl<Strict>(*patterns, symbolName))
2949- {
2950- ExtractionInfo const res = {patternsMode, ExtractionMatchType::Strict};
2951- return updateCache (res);
2952- }
2951+ ExtractionInfo const res = {patternsMode, ExtractionMatchType::Strict};
2952+ return updateCache (res);
2953+ }
29532954
2954- // 1a) Check if the parent in the same exclusion category
2955- // (see-below or implementation defined).
2956- if (AllowParent &&
2957- patternsMode != ExtractionMode::Regular &&
2958- ParentIs (D, patternsMode))
2955+ // 1a) Check if the parent in the same exclusion category
2956+ // (see-below or implementation defined).
2957+ MRDOCS_CHECK_OR_CONTINUE (AllowParent);
2958+ MRDOCS_CHECK_OR_CONTINUE (patternsMode != ExtractionMode::Regular);
2959+ MRDOCS_CHECK_OR_CONTINUE (ParentIs (D, patternsMode));
2960+ if (patternsMode == ExtractionMode::ImplementationDefined)
2961+ {
2962+ // A child of implementation defined is also
2963+ // implementation defined.
2964+ return updateCache (
2965+ { ExtractionMode::ImplementationDefined,
2966+ ExtractionMatchType::StrictParent });
2967+ }
2968+ if (patternsMode == ExtractionMode::SeeBelow)
2969+ {
2970+ // A child of see-below is also see-below (if namespace)
2971+ // or dependency (if record)
2972+ if (Decl const * P = getParent (D);
2973+ P &&
2974+ isa<NamespaceDecl>(P))
29592975 {
2960- if (patternsMode == ExtractionMode::ImplementationDefined)
2961- {
2962- // A child of implementation defined is also
2963- // implementation defined.
2964- return updateCache (
2965- { ExtractionMode::ImplementationDefined,
2966- ExtractionMatchType::StrictParent });
2967- }
2968- if (patternsMode == ExtractionMode::SeeBelow)
2969- {
2970- // A child of see-below is also see-below (if namespace)
2971- // or dependency (if record)
2972- if (Decl const * P = getParent (D);
2973- P &&
2974- isa<NamespaceDecl>(P))
2975- {
2976- return updateCache (
2977- { ExtractionMode::SeeBelow,
2978- ExtractionMatchType::StrictParent });
2979- }
2980- return updateCache (
2981- { ExtractionMode::Dependency,
2982- ExtractionMatchType::StrictParent });
2983- }
2976+ return updateCache (
2977+ { ExtractionMode::SeeBelow,
2978+ ExtractionMatchType::StrictParent });
29842979 }
2980+ return updateCache (
2981+ { ExtractionMode::Dependency,
2982+ ExtractionMatchType::StrictParent });
29852983 }
29862984 }
29872985
@@ -3048,55 +3046,56 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
30483046 symbolAsPrefix += " ::" ;
30493047 for (auto const & [patterns, mode] : std::ranges::views::reverse (patternsAndModes))
30503048 {
3051- if (!patterns->empty () &&
3052- checkSymbolFiltersImpl<PrefixOnly>(*patterns, symbolAsPrefix.str ()))
3049+ MRDOCS_CHECK_OR_CONTINUE (!patterns->empty ());
3050+ MRDOCS_CHECK_OR_CONTINUE (
3051+ checkSymbolFiltersImpl<
3052+ PrefixOnly>(*patterns, symbolAsPrefix.str ()));
3053+ // We know this namespace matches one of the pattern
3054+ // prefixes that can potentially include children, but
3055+ // we have to check if any children actually matches
3056+ // the pattern strictly.
3057+ auto const * DC = cast<DeclContext>(D);
3058+ auto childrenMode = ExtractionMode::Dependency;
3059+ for (auto * M : DC->decls ())
30533060 {
3054- // We know this namespace matches one of the pattern
3055- // prefixes that can potentially include children, but
3056- // we have to check if any children actually matches
3057- // the pattern strictly.
3058- auto const * DC = cast<DeclContext>(D);
3059- auto childrenMode = ExtractionMode::Dependency;
3060- for (auto * M : DC->decls ())
3061+ MRDOCS_SYMBOL_TRACE (M, context_);
3062+ if (M->isImplicit () && !isa<IndirectFieldDecl>(M))
30613063 {
3062- if (M->isImplicit () && !isa<IndirectFieldDecl>(M))
3063- {
3064- // Ignore implicit members
3065- continue ;
3066- }
3067- if (getParent (M) != D)
3068- {
3069- // Not a semantic member
3070- continue ;
3071- }
3072- auto const R = checkSymbolFilters (M, false );
3073- if (R.mode == ExtractionMode::Dependency)
3074- {
3075- // The child should not be extracted.
3076- // Go to next child.
3077- continue ;
3078- }
3079- if (childrenMode == ExtractionMode::Dependency)
3080- {
3081- // Still a dependency. Initialize it with child mode.
3082- childrenMode = R.mode ;
3083- }
3084- else
3085- {
3086- // Children mode already initialized. Get the least specific one.
3087- childrenMode = leastSpecific (childrenMode, R.mode );
3088- }
3089- if (childrenMode == ExtractionMode::Regular)
3090- {
3091- // Already the least specific
3092- break ;
3093- }
3064+ // Ignore implicit members
3065+ continue ;
3066+ }
3067+ if (getParent (M) != D)
3068+ {
3069+ // Not a semantic member
3070+ continue ;
3071+ }
3072+ auto const [childMode, childKind] = checkSymbolFilters (M, false );
3073+ if (childMode == ExtractionMode::Dependency)
3074+ {
3075+ // The child should not be extracted.
3076+ // Go to next child.
3077+ continue ;
3078+ }
3079+ if (childrenMode == ExtractionMode::Dependency)
3080+ {
3081+ // Still a dependency. Initialize it with child mode.
3082+ childrenMode = childMode;
30943083 }
3095- if (childrenMode != ExtractionMode::Dependency)
3084+ else
30963085 {
3097- ExtractionInfo const res = {childrenMode, ExtractionMatchType::Prefix};
3098- return updateCache (res );
3086+ // Children mode already initialized. Get the least specific one.
3087+ childrenMode = leastSpecific (childrenMode, childMode );
30993088 }
3089+ if (childrenMode == ExtractionMode::Regular)
3090+ {
3091+ // Already the least specific
3092+ break ;
3093+ }
3094+ }
3095+ if (childrenMode != ExtractionMode::Dependency)
3096+ {
3097+ ExtractionInfo const res = {childrenMode, ExtractionMatchType::Prefix};
3098+ return updateCache (res);
31003099 }
31013100 }
31023101 }
@@ -3140,6 +3139,7 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
31403139 constexpr ExtractionInfo res = {ExtractionMode::Regular, ExtractionMatchType::Strict};
31413140 return updateCache (res);
31423141 }
3142+
31433143 // 4b) Otherwise, we don't extract the symbol
31443144 // because it doesn't match any of `include-symbol` filters
31453145 constexpr ExtractionInfo res = {ExtractionMode::Dependency, ExtractionMatchType::Strict};
@@ -3385,16 +3385,21 @@ upsert(DeclType const* D)
33853385 ExtractionMode const m = checkFilters (D);
33863386 if (m == ExtractionMode::Dependency)
33873387 {
3388+ // If the extraction mode is dependency, it means we
3389+ // should extract it as a dependency or that we
3390+ // should not extract it.
33883391 if (mode_ == Regular)
33893392 {
33903393 return Unexpected (Error (" Symbol should not be extracted" ));
33913394 }
33923395 if (isAnyExplicitSpecialization (D))
33933396 {
3394- // We should not extract explicit declarations in dependency mode.
3397+ // We should not extract explicit specializations in dependency mode.
3398+ // As this is a dependency, the corpus only needs to store the main
3399+ // template.
33953400 // The calling code should handle this case instead of
33963401 // populating the symbol table with instantiations.
3397- return Unexpected (Error (" Explicit declaration in dependency mode" ));
3402+ return Unexpected (Error (" Specialization in dependency mode" ));
33983403 }
33993404 }
34003405
@@ -3405,7 +3410,14 @@ upsert(DeclType const* D)
34053410 auto [I, isNew] = upsert<R>(id);
34063411
34073412 // Already populate the extraction mode
3408- I.Extraction = mostSpecific (I.Extraction , m);
3413+ if (isNew)
3414+ {
3415+ I.Extraction = m;
3416+ }
3417+ else
3418+ {
3419+ I.Extraction = leastSpecific (I.Extraction , m);
3420+ }
34093421
34103422 // Already populate the access specifier
34113423 AccessSpecifier const access = getAccess (D);
0 commit comments