C++: Change API for exposing template parameters.

Note that Declaration::getTemplateArgumentType() and
Declaration::getTemplateArgumentValue() need to be public so that they
can be overriden in derived classes.
This commit is contained in:
Matthew Gretton-Dann
2019-11-01 14:31:51 +00:00
parent 45ec8527c3
commit 6fe22a76da
12 changed files with 86 additions and 49 deletions

View File

@@ -610,7 +610,7 @@ class Class extends UserType {
* class template. When called on a class template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int i) {
override Type getTemplateArgumentType(int i) {
class_template_argument(underlyingElement(this), i, unresolveElement(result))
}
@@ -632,7 +632,7 @@ class Class extends UserType {
}
override predicate involvesTemplateParameter() {
getATemplateArgument().involvesTemplateParameter()
getATemplateArgument().(Type).involvesTemplateParameter()
}
/** Holds if this class, struct or union was declared 'final'. */

View File

@@ -196,33 +196,36 @@ abstract class Declaration extends Locatable, @declaration {
* When called on a template, this will return a template parameter type for
* both typed and non-typed parameters.
*/
final Type getATemplateArgument() { result = getTemplateArgument(_) }
final Locatable getATemplateArgument() { result = getTemplateArgument(_) }
/**
* Gets a template argument used to instantiate this declaration from a template.
* When called on a template, this will return a non-typed template
* parameter value.
*/
final Expr getATemplateArgumentValue() { result = getTemplateArgumentValue(_) }
final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) }
/**
* Gets the `i`th template argument used to instantiate this declaration from a
* template. When called on a template, this will return the `i`th template
* parameter's type.
* template.
*
* For example:
*
* `template<typename T, T X> class Foo;`
*
* Will have `getTemplateArgument(0)` return `T`, and
* `getTemplateArgument(1)` return `T`.
* `getTemplateArgument(1)` return `X`.
*
* `Foo<int, 1> bar;
*
* Will have `getTemplateArgument())` return `int`, and
* `getTemplateArgument(1)` return `int`.
* `getTemplateArgument(1)` return `1`.
*/
Type getTemplateArgument(int index) { none() }
final Locatable getTemplateArgument(int index) {
if exists(getTemplateArgumentValue(index))
then result = getTemplateArgumentValue(index)
else result = getTemplateArgumentType(index)
}
/**
* Gets the `i`th template argument value used to instantiate this declaration
@@ -233,20 +236,44 @@ abstract class Declaration extends Locatable, @declaration {
*
* `template<typename T, T X> class Foo;`
*
* Will have `getTemplateArgumentValue(1)` return `X`, and no result for
* `getTemplateArgumentValue(0)`.
* Will have `getTemplateArgumentKind(1)` return `T`, and no result for
* `getTemplateArgumentKind(0)`.
*
* `Foo<int, 10> bar;
*
* Will have `getTemplateArgumentValue(1)` return `10`, and no result for
* `getTemplateArgumentValue(0)`.
* Will have `getTemplateArgumentKind(1)` return `int`, and no result for
* `getTemplateArgumentKind(0)`.
*/
Expr getTemplateArgumentValue(int index) { none() }
final Locatable getTemplateArgumentKind(int index) {
if exists(getTemplateArgumentValue(index))
then result = getTemplateArgumentType(index)
else none()
}
/** Gets the number of template arguments for this declaration. */
final int getNumberOfTemplateArguments() {
result = count(int i | exists(getTemplateArgument(i)))
}
/**
* INTERNAL: Do not use.
*
* Gets a Type for a template argument. May be the template argument itself
* or the type of a non-type template argument.
*
* Use `getTemplateArgument` or `getTemplateKind` instead.
*/
Type getTemplateArgumentType(int index) { none() }
/**
* INTERNAL: Do not use.
*
* Gets an Expression representing the value of a non-type template
* argument.
*
* Use `getTemplateArgument` or `getTemplateKind` instead.
*/
Expr getTemplateArgumentValue(int index) { none() }
}
/**

View File

@@ -348,7 +348,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* function template. When called on a function template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int index) {
override Type getTemplateArgumentType(int index) {
function_template_argument(underlyingElement(this), index, unresolveElement(result))
}

View File

@@ -36,11 +36,11 @@ private string getParameterTypeString(Type parameterType) {
}
private string getTemplateArgumentString(Declaration d, int i) {
if exists(d.getTemplateArgumentValue(i))
if exists(d.getTemplateArgumentKind(i))
then
result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString() + " " + d.getTemplateArgumentValue(i)
else
result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString()
result = d.getTemplateArgumentKind(i).(DumpType).getTypeIdentityString() + " " +
d.getTemplateArgument(i)
else result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString()
}
/**

View File

@@ -210,7 +210,7 @@ class Type extends Locatable, @type {
// A function call that provides an explicit template argument that refers to T uses T.
// We exclude calls within instantiations, since they do not appear directly in the source.
exists(FunctionCall c |
c.getAnExplicitTemplateArgument().refersTo(this) and
c.getAnExplicitTemplateArgument().(Type).refersTo(this) and
result = c and
not c.getEnclosingFunction().isConstructedFrom(_)
)

View File

@@ -160,7 +160,7 @@ class Variable extends Declaration, @variable {
* variable template. When called on a variable template, this will return the
* `i`th template parameter.
*/
override Type getTemplateArgument(int index) {
override Type getTemplateArgumentType(int index) {
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
}

View File

@@ -139,27 +139,27 @@ class FunctionCall extends Call, @funbindexpr {
override string getCanonicalQLClass() { result = "FunctionCall" }
/** Gets an explicit template argument for this call. */
Type getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
/** Gets an explicit template argument value for this call. */
Expr getAnExplicitTemplateArgumentValue() { result = getExplicitTemplateArgumentValue(_) }
Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) }
/** Gets a template argument for this call. */
Type getATemplateArgument() { result = getTarget().getATemplateArgument() }
Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() }
/** Gets a template argument value for this call. */
Expr getATemplateArgumentValue() { result = getTarget().getATemplateArgumentValue() }
Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() }
/** Gets the nth explicit template argument for this call. */
Type getExplicitTemplateArgument(int n) {
Locatable getExplicitTemplateArgument(int n) {
n < getNumberOfExplicitTemplateArguments() and
result = getTemplateArgument(n)
}
/** Gets the nth explicit template argument value for this call. */
Expr getExplicitTemplateArgumentValue(int n) {
Locatable getExplicitTemplateArgumentKind(int n) {
n < getNumberOfExplicitTemplateArguments() and
result = getTemplateArgumentValue(n)
result = getTemplateArgumentKind(n)
}
/** Gets the number of explicit template arguments for this call. */
@@ -172,14 +172,11 @@ class FunctionCall extends Call, @funbindexpr {
/** Gets the number of template arguments for this call. */
int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) }
/** Gets the number of template argument which are values for this call. */
int getNumberOfTemplateArgumentValues() { result = count(int i | exists(getTemplateArgumentValue(i))) }
/** Gets the nth template argument for this call (indexed from 0). */
Type getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
/** Gets the nth template argument value for this call (indexed from 0). */
Expr getTemplateArgumentValue(int n) { result = getTarget().getTemplateArgumentValue(n) }
Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) }
/** Holds if any template arguments for this call are implicit / deduced. */
predicate hasImplicitTemplateArguments() {

View File

@@ -1,6 +1,6 @@
| file://:0:0:0:0 | __va_list_tag | <none> |
| test.cpp:3:8:3:9 | s1<<expression>> | bool |
| test.cpp:3:8:3:9 | s1<<unnamed>> | bool |
| test.cpp:3:8:3:9 | s1<<expression>> | {...} |
| test.cpp:3:8:3:9 | s1<<unnamed>> | (null) |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:5:8:5:9 | s2<T> | T |
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed) |

View File

@@ -1,4 +1,4 @@
import cpp
from Class c
select c, c.getATemplateArgument(), c.getATemplateArgumentValue()
select c, c.getATemplateArgumentKind(), c.getATemplateArgument()

View File

@@ -1,4 +1,4 @@
import cpp
from Function f
select f, f.getATemplateArgument(), f.getATemplateArgumentValue()
select f, f.getATemplateArgumentKind(), f.getATemplateArgument()

View File

@@ -1,10 +1,13 @@
| test.cpp:3:8:3:8 | C<1> | file://:0:0:0:0 | int | test.cpp:5:25:5:25 | 1 |
| test.cpp:3:8:3:8 | C<2> | file://:0:0:0:0 | int | file://:0:0:0:0 | 2 |
| test.cpp:3:8:3:8 | C<x> | file://:0:0:0:0 | int | file://:0:0:0:0 | x |
| test.cpp:10:8:10:8 | D<T, X> | test.cpp:9:19:9:19 | T | file://:0:0:0:0 | X |
| test.cpp:10:8:10:8 | D<int, 2> | file://:0:0:0:0 | int | test.cpp:12:8:12:8 | 2 |
| test.cpp:10:8:10:8 | D<long, 2L> | file://:0:0:0:0 | long | file://:0:0:0:0 | 2 |
| test.cpp:16:8:16:8 | E<T, X> | file://:0:0:0:0 | T * | file://:0:0:0:0 | X |
| test.cpp:16:8:16:8 | E<T, X> | test.cpp:15:19:15:19 | T | file://:0:0:0:0 | X |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | file://:0:0:0:0 | int | file://:0:0:0:0 | 0 |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | file://:0:0:0:0 | int * | file://:0:0:0:0 | 0 |
| test.cpp:3:8:3:8 | C<1> | 0 | int | test.cpp:5:25:5:25 | 1 |
| test.cpp:3:8:3:8 | C<2> | 0 | int | file://:0:0:0:0 | 2 |
| test.cpp:3:8:3:8 | C<x> | 0 | int | file://:0:0:0:0 | x |
| test.cpp:10:8:10:8 | D<T, X> | 0 | <none> | test.cpp:9:19:9:19 | T |
| test.cpp:10:8:10:8 | D<T, X> | 1 | T | file://:0:0:0:0 | X |
| test.cpp:10:8:10:8 | D<int, 2> | 0 | <none> | file://:0:0:0:0 | int |
| test.cpp:10:8:10:8 | D<int, 2> | 1 | int | test.cpp:12:8:12:8 | 2 |
| test.cpp:10:8:10:8 | D<long, 2L> | 0 | <none> | file://:0:0:0:0 | long |
| test.cpp:10:8:10:8 | D<long, 2L> | 1 | long | file://:0:0:0:0 | 2 |
| test.cpp:16:8:16:8 | E<T, X> | 0 | <none> | test.cpp:15:19:15:19 | T |
| test.cpp:16:8:16:8 | E<T, X> | 1 | T * | file://:0:0:0:0 | X |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 0 | <none> | file://:0:0:0:0 | int |
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 1 | int * | file://:0:0:0:0 | 0 |

View File

@@ -1,4 +1,14 @@
import cpp
from Declaration d
select d, d.getATemplateArgument(), d.getATemplateArgumentValue()
string maybeGetTemplateArgumentKind(Declaration d, int i) {
(
if exists(d.getTemplateArgumentKind(i))
then result = d.getTemplateArgumentKind(i).toString()
else result = "<none>"
) and
i = [0 .. d.getNumberOfTemplateArguments()]
}
from Declaration d, int i
where i >= 0 and i < d.getNumberOfTemplateArguments()
select d, i, maybeGetTemplateArgumentKind(d, i), d.getTemplateArgument(i)