MCPcopy Create free account
hub / github.com/andreasfertig/cppinsights / GetTemplateParameterPackArgumentName

Function GetTemplateParameterPackArgumentName

InsightsHelpers.cpp:1103–1139  ·  view source on GitHub ↗

* \brief Get a usable name from a template parameter pack. * * A template parameter pack, args, as in: * \code template auto forward(F f, Types &&...args) { f(args...); } forward(f,1, 2,3); * \endcode * * gets expanded by clang as * \code f(args, args, args); * \endcode * * which would obviously not compile. For clang AST dump it is the right thing. For

Source from the content-addressed store, hash-verified

1101 * The expected type for \c T currently is \c ValueDecl or \c VarDecl.
1102 */
1103static std::string GetTemplateParameterPackArgumentName(std::string_view name, const Decl* decl)
1104{
1105 if(const auto* parmVarDecl = dyn_cast_or_null<ParmVarDecl>(decl)) {
1106 if(const auto& originalType = parmVarDecl->getOriginalType(); not originalType.isNull()) {
1107 if(const auto* substTemplateTypeParmType = GetSubstTemplateTypeParmType(originalType.getTypePtrOrNull());
1108 substTemplateTypeParmType and substTemplateTypeParmType->getReplacedParameter()->isParameterPack()) {
1109 return StrCat(BuildInternalVarName(name), parmVarDecl->getFunctionScopeIndex());
1110
1111 } else if(const auto* fd = parmVarDecl->getParentFunctionOrMethod()) {
1112 // Get the primary template, if possible and check whether its parameters contain a parameter pack
1113 if(const auto* primTmpl = dyn_cast_or_null<FunctionDecl>(fd)->getPrimaryTemplate();
1114 primTmpl and primTmpl->getTemplateParameters()->hasParameterPack()) {
1115 // if so, then search for the matching parameter name.
1116 for(const auto* pa : primTmpl->getTemplatedDecl()->parameters()) {
1117 // if one is found we suffix it with its function scope index
1118 if(pa->isParameterPack() and (parmVarDecl->getNameAsString() == pa->getNameAsString())) {
1119 return StrCat(BuildInternalVarName(name), parmVarDecl->getFunctionScopeIndex());
1120 }
1121 }
1122 }
1123 }
1124 }
1125 } else if(const auto* varDecl = dyn_cast_or_null<VarDecl>(decl)) {
1126 // If it is an init-capture in C++2a p0780 brings "Allow pack expansion in lambda init-capture". We
1127 // need to figure out, whether the initializer for this \c VarDecl comes from a parameter pack. If
1128 // so, then we use this ParmVarDecl to get the index.
1129 if(varDecl->isInitCapture()) {
1130 if(const auto* drefExpr = FindVarDeclRef(varDecl->getInit())) {
1131 if(const auto* parmVarDecl = dyn_cast_or_null<ParmVarDecl>(drefExpr->getDecl())) {
1132 return GetTemplateParameterPackArgumentName(name, parmVarDecl);
1133 }
1134 }
1135 }
1136 }
1137
1138 return std::string{name};
1139}
1140//-----------------------------------------------------------------------------
1141
1142#if IS_CLANG_NEWER_THAN(20)

Callers 1

GetNameFunction · 0.85

Calls 4

StrCatFunction · 0.85
BuildInternalVarNameFunction · 0.85
FindVarDeclRefFunction · 0.85

Tested by

no test coverage detected