@@ -95,16 +95,44 @@ traverse(DeclTy const* D)
9595
9696 if constexpr (std::same_as<DeclTy, clang::Decl>)
9797 {
98- // Convert to the most derived type of the Decl
99- // and call the appropriate traverse function
100- return visit (D, [&]<typename DeclTyU>(DeclTyU* U) -> Symbol*
101- {
102- if constexpr (!std::same_as<DeclTyU, clang::Decl>)
103- {
104- return traverse (U);
105- }
106- return nullptr ;
107- });
98+ switch (D->getKind ())
99+ {
100+ #define X (V ) \
101+ case clang::Decl::V: \
102+ return traverse (llvm::cast<clang::V##Decl>(D))
103+ X (FunctionTemplate);
104+ X (UsingDirective);
105+ X (IndirectField);
106+
107+ X (TranslationUnit);
108+ X (Namespace);
109+ X (CXXRecord);
110+ X (ClassTemplateSpecialization);
111+ X (ClassTemplatePartialSpecialization);
112+ X (ClassTemplate);
113+ X (Function);
114+ X (CXXMethod);
115+ X (CXXConstructor);
116+ X (CXXDestructor);
117+ X (CXXConversion);
118+ X (Enum);
119+ X (EnumConstant);
120+ X (Typedef);
121+ X (TypeAlias);
122+ X (TypeAliasTemplate);
123+ X (Var);
124+ X (VarTemplateSpecialization);
125+ X (VarTemplatePartialSpecialization);
126+ X (VarTemplate);
127+ X (Field);
128+ X (CXXDeductionGuide);
129+ X (NamespaceAlias);
130+ X (Using);
131+ X (Concept);
132+ #undef X
133+ default :
134+ break ;
135+ }
108136 }
109137 else if constexpr (HasInfoTypeFor<DeclTy> || std::derived_from<InfoTy, Symbol>)
110138 {
@@ -1510,86 +1538,85 @@ populate(
15101538 clang::NamedDecl const * N)
15111539{
15121540 MRDOCS_ASSERT (!I.valueless_after_move ());
1513- visit (N, [&]< typename DeclTy>(DeclTy const * P )
1541+ switch (N-> getKind () )
15141542 {
1515- constexpr clang::Decl::Kind kind =
1516- DeclToKind<DeclTy>();
1517-
1518- if constexpr (kind == clang::Decl::TemplateTypeParm )
1543+ case clang::Decl::TemplateTypeParm:
1544+ {
1545+ auto * P = llvm::cast<clang::TemplateTypeParmDecl>(N);
1546+ if (I-> Kind != TParamKind::Type )
15191547 {
1520- if (I->Kind != TParamKind::Type)
1521- {
1522- I = Polymorphic<TParam>(std::in_place_type<TypeTParam>);
1523- }
1524- auto * R = (I.operator ->())->asTypePtr ();
1525- if (P->wasDeclaredWithTypename ())
1526- {
1527- R->KeyKind = TParamKeyKind::Typename;
1528- }
1529- if (P->hasDefaultArgument () && !R->Default )
1530- {
1531- R->Default = toTArg (
1532- P->getDefaultArgument ().getArgument ());
1533- }
1534- if (clang::TypeConstraint const * TC = P->getTypeConstraint ())
1535- {
1536- clang::NestedNameSpecifier NNS =
1537- TC->getNestedNameSpecifierLoc ().getNestedNameSpecifier ();
1538- Optional<clang::ASTTemplateArgumentListInfo const *> TArgs;
1539- if (TC->hasExplicitTemplateArgs ())
1540- {
1541- TArgs.emplace (TC->getTemplateArgsAsWritten ());
1542- }
1543- R->Constraint = toName (TC->getNamedConcept (), TArgs, NNS);
1544- }
1545- return ;
1548+ I = Polymorphic<TParam>(std::in_place_type<TypeTParam>);
15461549 }
1547- else if constexpr (kind == clang::Decl::NonTypeTemplateParm)
1550+ auto * R = (I.operator ->())->asTypePtr ();
1551+ if (P->wasDeclaredWithTypename ())
15481552 {
1549- if (I->Kind != TParamKind::Constant)
1550- {
1551- I = Polymorphic<TParam>(std::in_place_type<ConstantTParam>);
1552- }
1553- auto * R = (I.operator ->())->asConstantPtr ();
1554- R->Type = toType (P->getType ());
1555- if (P->hasDefaultArgument () && !R->Default )
1556- {
1557- R->Default = toTArg (
1558- P->getDefaultArgument ().getArgument ());
1559- }
1560- return ;
1553+ R->KeyKind = TParamKeyKind::Typename;
15611554 }
1562- else if constexpr (kind == clang::Decl::TemplateTemplateParm )
1555+ if (P-> hasDefaultArgument () && !R-> Default )
15631556 {
1564- if (I->Kind != TParamKind::Template)
1565- {
1566- I = Polymorphic<TParam>(std::in_place_type<TemplateTParam>);
1567- }
1568- auto const * TTPD = cast<clang::TemplateTemplateParmDecl>(P);
1569- MRDOCS_CHECK_OR (TTPD);
1570- clang::TemplateParameterList const * TPL = TTPD->getTemplateParameters ();
1571- MRDOCS_CHECK_OR (TPL);
1572- auto * Result = (I.operator ->())->asTemplatePtr ();
1573- Result->Params .reserve (TPL->size ());
1574- for (std::size_t i = 0 ; i < TPL->size (); ++i)
1575- {
1576- clang::NamedDecl const * TP = TPL->getParam (i);
1577- auto & Param
1578- = i < Result->Params .size () ?
1579- Result->Params [i] :
1580- Result->Params .emplace_back (std::in_place_type<TypeTParam>);
1581- populate (Param, TP);
1582- }
1583- if (TTPD->hasDefaultArgument () && !Result->Default )
1557+ R->Default = toTArg (P->getDefaultArgument ().getArgument ());
1558+ }
1559+ if (clang::TypeConstraint const * TC = P->getTypeConstraint ())
1560+ {
1561+ clang::NestedNameSpecifier NNS = TC->getNestedNameSpecifierLoc ()
1562+ .getNestedNameSpecifier ();
1563+ Optional<clang::ASTTemplateArgumentListInfo const *> TArgs;
1564+ if (TC->hasExplicitTemplateArgs ())
15841565 {
1585- clang::TemplateArgumentLoc const & TAL = TTPD->getDefaultArgument ();
1586- clang::TemplateArgument const & TA = TAL.getArgument ();
1587- Result->Default = toTArg (TA);
1566+ TArgs.emplace (TC->getTemplateArgsAsWritten ());
15881567 }
1589- return ;
1568+ R-> Constraint = toName (TC-> getNamedConcept (), TArgs, NNS) ;
15901569 }
1570+ break ;
1571+ }
1572+ case clang::Decl::NonTypeTemplateParm:
1573+ {
1574+ auto * P = llvm::cast<clang::NonTypeTemplateParmDecl>(N);
1575+ if (I->Kind != TParamKind::Constant)
1576+ {
1577+ I = Polymorphic<TParam>(std::in_place_type<ConstantTParam>);
1578+ }
1579+ auto * R = (I.operator ->())->asConstantPtr ();
1580+ R->Type = toType (P->getType ());
1581+ if (P->hasDefaultArgument () && !R->Default )
1582+ {
1583+ R->Default = toTArg (P->getDefaultArgument ().getArgument ());
1584+ }
1585+ break ;
1586+ }
1587+ case clang::Decl::TemplateTemplateParm:
1588+ {
1589+ auto * P = llvm::cast<clang::TemplateTemplateParmDecl>(N);
1590+ if (I->Kind != TParamKind::Template)
1591+ {
1592+ I = Polymorphic<TParam>(std::in_place_type<TemplateTParam>);
1593+ }
1594+ auto const * TTPD = cast<clang::TemplateTemplateParmDecl>(P);
1595+ MRDOCS_CHECK_OR (TTPD);
1596+ clang::TemplateParameterList const * TPL = TTPD->getTemplateParameters ();
1597+ MRDOCS_CHECK_OR (TPL);
1598+ auto * Result = (I.operator ->())->asTemplatePtr ();
1599+ Result->Params .reserve (TPL->size ());
1600+ for (std::size_t i = 0 ; i < TPL->size (); ++i)
1601+ {
1602+ clang::NamedDecl const * TP = TPL->getParam (i);
1603+ auto & Param = i < Result->Params .size () ?
1604+ Result->Params [i] :
1605+ Result->Params .emplace_back (
1606+ std::in_place_type<TypeTParam>);
1607+ populate (Param, TP);
1608+ }
1609+ if (TTPD->hasDefaultArgument () && !Result->Default )
1610+ {
1611+ clang::TemplateArgumentLoc const & TAL = TTPD->getDefaultArgument ();
1612+ clang::TemplateArgument const & TA = TAL.getArgument ();
1613+ Result->Default = toTArg (TA);
1614+ }
1615+ break ;
1616+ }
1617+ default :
15911618 MRDOCS_UNREACHABLE ();
1592- });
1619+ }
15931620
15941621 MRDOCS_ASSERT (!I.valueless_after_move ());
15951622 if (I->Name .empty ())
0 commit comments