@@ -201,6 +201,68 @@ auto ASTRewriter::instantiateTypeAliasTemplate(
201201 return instance->symbol ;
202202}
203203
204+ auto ASTRewriter::instantiateVariableTemplate (
205+ TranslationUnit* unit, List<TemplateArgumentAST*>* templateArgumentList,
206+ VariableSymbol* variableSymbol) -> VariableSymbol* {
207+ auto templateDecl = variableSymbol->templateDeclaration ();
208+
209+ if (!templateDecl) {
210+ unit->error (variableSymbol->location (), " not a template" );
211+ return nullptr ;
212+ }
213+
214+ auto variableDeclaration =
215+ ast_cast<SimpleDeclarationAST>(templateDecl->declaration );
216+
217+ if (!variableDeclaration) return nullptr ;
218+
219+ auto templateArguments =
220+ make_substitution (unit, templateDecl, templateArgumentList);
221+
222+ auto is_primary_template = [&]() -> bool {
223+ int expected = 0 ;
224+ for (const auto & arg : templateArguments) {
225+ if (!std::holds_alternative<Symbol*>(arg)) return false ;
226+
227+ auto ty = type_cast<TypeParameterType>(std::get<Symbol*>(arg)->type ());
228+ if (!ty) return false ;
229+
230+ if (ty->index () != expected) return false ;
231+ ++expected;
232+ }
233+ return true ;
234+ };
235+
236+ if (is_primary_template ()) {
237+ // if this is a primary template, we can just return the class symbol
238+ return variableSymbol;
239+ }
240+
241+ auto subst = variableSymbol->findSpecialization (templateArguments);
242+ if (subst) {
243+ return subst;
244+ }
245+
246+ auto parentScope = variableSymbol->parent ();
247+ while (parentScope->isTemplateParameters ()) {
248+ parentScope = parentScope->parent ();
249+ }
250+
251+ auto rewriter = ASTRewriter{unit, parentScope, templateArguments};
252+
253+ rewriter.binder ().setInstantiatingSymbol (variableSymbol);
254+
255+ auto instance =
256+ ast_cast<SimpleDeclarationAST>(rewriter.declaration (variableDeclaration));
257+
258+ if (!instance) return nullptr ;
259+
260+ auto instantiatedSymbol = instance->initDeclaratorList ->value ->symbol ;
261+ auto instantiatedVariable = symbol_cast<VariableSymbol>(instantiatedSymbol);
262+
263+ return instantiatedVariable;
264+ }
265+
204266auto ASTRewriter::make_substitution (
205267 TranslationUnit* unit, TemplateDeclarationAST* templateDecl,
206268 List<TemplateArgumentAST*>* templateArgumentList)
0 commit comments