22
22
#include " lib/Lib/Diagnostics.hpp"
23
23
#include < mrdocs/Metadata.hpp>
24
24
#include < mrdocs/Support/ScopeExit.hpp>
25
+ #include < mrdocs/Support/Algorithm.hpp>
25
26
#include < clang/AST/AST.h>
26
27
#include < clang/AST/Attr.h>
27
28
#include < clang/AST/ODRHash.h>
@@ -180,7 +181,7 @@ traverse(UsingDirectiveDecl const* D)
180
181
MRDOCS_ASSERT (res);
181
182
MRDOCS_ASSERT (res->isIdentifier ());
182
183
if (NameInfo NI = *res;
183
- std::ranges::find (PNI->UsingDirectives , NI) == PNI-> UsingDirectives . end ( ))
184
+ ! contains (PNI->UsingDirectives , NI))
184
185
{
185
186
PNI->UsingDirectives .push_back (std::move (NI));
186
187
}
@@ -1582,7 +1583,7 @@ populateAttributes(InfoTy& I, Decl const* D)
1582
1583
{
1583
1584
continue ;
1584
1585
}
1585
- if (std::ranges::find (I.Attributes , II->getName ()) == I. Attributes . end ( ))
1586
+ if (! contains (I.Attributes , II->getName ()))
1586
1587
{
1587
1588
I.Attributes .emplace_back (II->getName ());
1588
1589
}
@@ -1779,7 +1780,7 @@ void
1779
1780
ASTVisitor::
1780
1781
addMember (std::vector<SymbolID>& container, Info const & Member) const
1781
1782
{
1782
- if (std::ranges::find (container, Member.id ) == container. end ( ))
1783
+ if (! contains (container, Member.id ))
1783
1784
{
1784
1785
container.push_back (Member.id );
1785
1786
}
@@ -2821,45 +2822,48 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
2821
2822
// Update cache
2822
2823
auto updateCache = [this , D](ExtractionInfo const result) {
2823
2824
extraction_.emplace (D, result);
2825
+ return result;
2824
2826
};
2825
2827
2826
2828
// If not a NamedDecl, then symbol filters don't apply
2827
2829
auto const * ND = dyn_cast<NamedDecl>(D);
2828
2830
if (!ND)
2829
2831
{
2830
- ExtractionInfo const res{ExtractionMode::Regular, ExtractionMatchType::Strict};
2831
- updateCache (res);
2832
- return res;
2832
+ constexpr ExtractionInfo res{ExtractionMode::Regular, ExtractionMatchType::Strict};
2833
+ return updateCache (res);
2833
2834
}
2834
2835
2835
2836
// Get the symbol name
2836
2837
SmallString<256 > const name = qualifiedName (ND);
2837
2838
auto const symbolName = name.str ();
2838
2839
2839
- // We should check the exclusion filters first. If a symbol is
2840
+ // Function to check if parent is of a certain extraction mode
2841
+ auto ParentIs = [&](Decl const * D, ExtractionMode expected) {
2842
+ if (Decl const * P = getParent (D);
2843
+ P &&
2844
+ !isa<TranslationUnitDecl>(P))
2845
+ {
2846
+ auto const [parentMode, kind] = checkSymbolFilters (P);
2847
+ return parentMode == expected;
2848
+ }
2849
+ return false ;
2850
+ };
2851
+
2852
+ // 0) We should check the exclusion filters first. If a symbol is
2840
2853
// explicitly excluded, there's nothing else to check.
2841
2854
if (!config_->excludeSymbols .empty ())
2842
2855
{
2843
2856
if (checkSymbolFiltersImpl<Strict>(config_->excludeSymbols , symbolName))
2844
2857
{
2845
2858
ExtractionInfo const res{ExtractionMode::Dependency, ExtractionMatchType::Strict};
2846
- updateCache (res);
2847
- return res;
2859
+ return updateCache (res);
2848
2860
}
2849
- // If the parent scope is excluded, the symbol should also be excluded
2850
- // since it would not be possible to refer to this member.
2851
- if (AllowParent)
2861
+
2862
+ // 0a) Check if the parent is excluded
2863
+ if (AllowParent &&
2864
+ ParentIs (D, ExtractionMode::Dependency))
2852
2865
{
2853
- if (Decl const * P = getParent (D))
2854
- {
2855
- if (auto const [mode, kind] = checkSymbolFilters (P);
2856
- mode == ExtractionMode::Dependency)
2857
- {
2858
- ExtractionInfo const res = {mode, ExtractionMatchType::StrictParent};
2859
- updateCache (res);
2860
- return res;
2861
- }
2862
- }
2866
+ return updateCache ({ExtractionMode::Dependency, ExtractionMatchType::StrictParent});
2863
2867
}
2864
2868
}
2865
2869
@@ -2875,14 +2879,47 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
2875
2879
};
2876
2880
2877
2881
// 1) The symbol strictly matches one of the patterns
2878
- for (auto const & [patterns, mode ] : patternsAndModes)
2882
+ for (auto const & [patterns, patternsMode ] : patternsAndModes)
2879
2883
{
2880
- if (!patterns->empty () &&
2881
- checkSymbolFiltersImpl<Strict>(*patterns, symbolName))
2884
+ if (!patterns->empty ())
2882
2885
{
2883
- ExtractionInfo res = {mode, ExtractionMatchType::Strict};
2884
- updateCache (res);
2885
- return res;
2886
+ if (checkSymbolFiltersImpl<Strict>(*patterns, symbolName))
2887
+ {
2888
+ ExtractionInfo const res = {patternsMode, ExtractionMatchType::Strict};
2889
+ return updateCache (res);
2890
+ }
2891
+
2892
+ // 1a) Check if the parent in the same exclusion category
2893
+ // (see-below or implementation defined).
2894
+ if (AllowParent &&
2895
+ patternsMode != ExtractionMode::Regular &&
2896
+ ParentIs (D, patternsMode))
2897
+ {
2898
+ if (patternsMode == ExtractionMode::ImplementationDefined)
2899
+ {
2900
+ // A child of implementation defined is also
2901
+ // implementation defined.
2902
+ return updateCache (
2903
+ { ExtractionMode::ImplementationDefined,
2904
+ ExtractionMatchType::StrictParent });
2905
+ }
2906
+ if (patternsMode == ExtractionMode::SeeBelow)
2907
+ {
2908
+ // A child of see-below is also see-below (if namespace)
2909
+ // or dependency (if record)
2910
+ if (Decl const * P = getParent (D);
2911
+ P &&
2912
+ isa<NamespaceDecl>(P))
2913
+ {
2914
+ return updateCache (
2915
+ { ExtractionMode::SeeBelow,
2916
+ ExtractionMatchType::StrictParent });
2917
+ }
2918
+ return updateCache (
2919
+ { ExtractionMode::Dependency,
2920
+ ExtractionMatchType::StrictParent });
2921
+ }
2922
+ }
2886
2923
}
2887
2924
}
2888
2925
@@ -2922,8 +2959,7 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
2922
2959
checkSymbolFiltersImpl<Literal>(*patterns, namespaceName.str ()))
2923
2960
{
2924
2961
ExtractionInfo const res = {mode, ExtractionMatchType::LiteralParent};
2925
- updateCache (res);
2926
- return res;
2962
+ return updateCache (res);
2927
2963
}
2928
2964
}
2929
2965
}
@@ -2996,9 +3032,8 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
2996
3032
}
2997
3033
if (childrenMode != ExtractionMode::Dependency)
2998
3034
{
2999
- ExtractionInfo const res = {mode, ExtractionMatchType::Prefix};
3000
- updateCache (res);
3001
- return res;
3035
+ ExtractionInfo const res = {childrenMode, ExtractionMatchType::Prefix};
3036
+ return updateCache (res);
3002
3037
}
3003
3038
}
3004
3039
}
@@ -3028,8 +3063,7 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
3028
3063
// being extracted so that symbols that match
3029
3064
// the full pattern are included and not all symbols.
3030
3065
ExtractionInfo const res = {mode, ExtractionMatchType::StrictParent};
3031
- updateCache (res);
3032
- return res;
3066
+ return updateCache (res);
3033
3067
}
3034
3068
}
3035
3069
}
@@ -3042,14 +3076,12 @@ checkSymbolFilters(Decl const* D, bool const AllowParent)
3042
3076
if (config_->includeSymbols .empty ())
3043
3077
{
3044
3078
constexpr ExtractionInfo res = {ExtractionMode::Regular, ExtractionMatchType::Strict};
3045
- updateCache (res);
3046
- return res;
3079
+ return updateCache (res);
3047
3080
}
3048
3081
// 4b) Otherwise, we don't extract the symbol
3049
3082
// because it doesn't match any of `include-symbol` filters
3050
3083
constexpr ExtractionInfo res = {ExtractionMode::Dependency, ExtractionMatchType::Strict};
3051
- updateCache (res);
3052
- return res;
3084
+ return updateCache (res);
3053
3085
}
3054
3086
3055
3087
template <ASTVisitor::SymbolCheckType t>
0 commit comments