@@ -193,20 +193,83 @@ abstract class Declaration extends Locatable, @declaration {
193193
194194 /**
195195 * Gets a template argument used to instantiate this declaration from a template.
196- * When called on a template, this will return a template parameter.
196+ * When called on a template, this will return a template parameter type for
197+ * both typed and non-typed parameters.
197198 */
198- final Type getATemplateArgument ( ) { result = getTemplateArgument ( _) }
199+ final Locatable getATemplateArgument ( ) { result = getTemplateArgument ( _) }
200+
201+ /**
202+ * Gets a template argument used to instantiate this declaration from a template.
203+ * When called on a template, this will return a non-typed template
204+ * parameter value.
205+ */
206+ final Locatable getATemplateArgumentKind ( ) { result = getTemplateArgumentKind ( _) }
199207
200208 /**
201209 * Gets the `i`th template argument used to instantiate this declaration from a
202- * template. When called on a template, this will return the `i`th template parameter.
210+ * template.
211+ *
212+ * For example:
213+ *
214+ * `template<typename T, T X> class Foo;`
215+ *
216+ * Will have `getTemplateArgument(0)` return `T`, and
217+ * `getTemplateArgument(1)` return `X`.
218+ *
219+ * `Foo<int, 1> bar;
220+ *
221+ * Will have `getTemplateArgument())` return `int`, and
222+ * `getTemplateArgument(1)` return `1`.
203223 */
204- Type getTemplateArgument ( int index ) { none ( ) }
224+ final Locatable getTemplateArgument ( int index ) {
225+ if exists ( getTemplateArgumentValue ( index ) )
226+ then result = getTemplateArgumentValue ( index )
227+ else result = getTemplateArgumentType ( index )
228+ }
229+
230+ /**
231+ * Gets the `i`th template argument value used to instantiate this declaration
232+ * from a template. When called on a template, this will return the `i`th template
233+ * parameter value if it exists.
234+ *
235+ * For example:
236+ *
237+ * `template<typename T, T X> class Foo;`
238+ *
239+ * Will have `getTemplateArgumentKind(1)` return `T`, and no result for
240+ * `getTemplateArgumentKind(0)`.
241+ *
242+ * `Foo<int, 10> bar;
243+ *
244+ * Will have `getTemplateArgumentKind(1)` return `int`, and no result for
245+ * `getTemplateArgumentKind(0)`.
246+ */
247+ final Locatable getTemplateArgumentKind ( int index ) {
248+ if exists ( getTemplateArgumentValue ( index ) )
249+ then result = getTemplateArgumentType ( index )
250+ else none ( )
251+ }
205252
206253 /** Gets the number of template arguments for this declaration. */
207254 final int getNumberOfTemplateArguments ( ) {
208255 result = count ( int i | exists ( getTemplateArgument ( i ) ) )
209256 }
257+
258+ private Type getTemplateArgumentType ( int index ) {
259+ class_template_argument ( underlyingElement ( this ) , index , unresolveElement ( result ) )
260+ or
261+ function_template_argument ( underlyingElement ( this ) , index , unresolveElement ( result ) )
262+ or
263+ variable_template_argument ( underlyingElement ( this ) , index , unresolveElement ( result ) )
264+ }
265+
266+ private Expr getTemplateArgumentValue ( int index ) {
267+ class_template_argument_value ( underlyingElement ( this ) , index , unresolveElement ( result ) )
268+ or
269+ function_template_argument_value ( underlyingElement ( this ) , index , unresolveElement ( result ) )
270+ or
271+ variable_template_argument_value ( underlyingElement ( this ) , index , unresolveElement ( result ) )
272+ }
210273}
211274
212275/**
0 commit comments