Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bd4ecc3

Browse files
C++: Declaration.getIdentityString and Type.getTypeIdentityString
This PR adds new predicates to `Declaration` and `Type` to get a fully-qualified canonical name for the element, suitable for debugging and dumps. It includes template parameters, cv qualifiers, function parameter and return types, and fully-qualified names for all symbols. These strings are too large to compute in productions queries, so they should be used only for dumps and debugging. Feel free to suggest better names for these predicates. I've updated PrintAST and PrintIR to use these instead of `Function.getFullSignature()`. The biggest advantage of the new predicates is that they handle lambdas and local classes, which `getQualifiedName` and `getFullSignature` do not. This makes IR and AST dumps much more usable for real-world snapshots. Along the way, I cleaned up some of our handling of `IntegralType` to use a single table for tracking the signed, unsigned, and canonical versions of each type. The canonical part is new, and was necessary for `getTypeIdentityString` so that `signed int` and `int` both appear as `int`.
1 parent 87c5872 commit bd4ecc3

17 files changed

Lines changed: 1461 additions & 717 deletions

File tree

cpp/ql/src/semmle/code/cpp/Declaration.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import semmle.code.cpp.Element
22
import semmle.code.cpp.Specifier
33
import semmle.code.cpp.Namespace
4+
private import semmle.code.cpp.internal.IdentityString
45

56
/**
67
* A C/C++ declaration: for example, a variable declaration, a type
@@ -88,6 +89,17 @@ abstract class Declaration extends Locatable, @declaration {
8889

8990
override string toString() { result = this.getName() }
9091

92+
/**
93+
* Gets a string that uniquely identifies this declaration, suitable for use when debugging queries. Only holds for
94+
* functions, user-defined types, global and namespace-scope variables, and member variables.
95+
*
96+
* This operation is very expensive, and should not be used in production queries. Consider using `hasName()` or
97+
* `hasQualifiedName()` for identifying known declarations in production queries.
98+
*/
99+
string getIdentityString() {
100+
none()
101+
}
102+
91103
/**
92104
* Gets the name of this declaration.
93105
*

cpp/ql/src/semmle/code/cpp/Function.qll

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import semmle.code.cpp.Parameter
55
import semmle.code.cpp.exprs.Call
66
import semmle.code.cpp.metrics.MetricFunction
77
import semmle.code.cpp.Linkage
8+
private import semmle.code.cpp.internal.IdentityString
89
private import semmle.code.cpp.internal.ResolveClass
910

1011
/**
@@ -55,6 +56,48 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
5556
)
5657
}
5758

59+
override string getIdentityString() {
60+
result = getType().getTypeSpecifier() + getType().getDeclaratorPrefix() + " " + getScopePrefix(this) + getName() + getTemplateArgumentsString() + getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
61+
}
62+
63+
language[monotonicAggregates]
64+
private string getTemplateArgumentsString() {
65+
if exists(getATemplateArgument()) then (
66+
result = "<" +
67+
concat(int i |
68+
exists(getTemplateArgument(i)) |
69+
getTemplateArgument(i).getTypeIdentityString(), ", " order by i
70+
) + ">"
71+
)
72+
else
73+
result = ""
74+
}
75+
76+
language[monotonicAggregates]
77+
private string getDeclaratorSuffixBeforeQualifiers() {
78+
result = "(" +
79+
concat(int i |
80+
exists(getParameter(i).getType()) |
81+
getParameterTypeString(getParameter(i).getType()), ", " order by i
82+
) + ")" + getQualifierString()
83+
}
84+
85+
private string getQualifierString() {
86+
if exists(getACVQualifier()) then
87+
result = " " + concat(string qualifier | qualifier = getACVQualifier() | qualifier, " ")
88+
else
89+
result = ""
90+
}
91+
92+
private string getACVQualifier() {
93+
result = getASpecifier().getName() and
94+
(result = "const" or result = "volatile")
95+
}
96+
97+
private string getDeclaratorSuffix() {
98+
result = getType().getDeclaratorSuffixBeforeQualifiers() + getType().getDeclaratorSuffix()
99+
}
100+
58101
/** Gets a specifier of this function. */
59102
override Specifier getASpecifier() {
60103
funspecifiers(underlyingElement(this),unresolveElement(result))
@@ -1088,8 +1131,14 @@ class TemplateFunction extends Function {
10881131
* A function that is an instantiation of a template.
10891132
*/
10901133
class FunctionTemplateInstantiation extends Function {
1134+
TemplateFunction tf;
1135+
10911136
FunctionTemplateInstantiation() {
1092-
exists(TemplateFunction tf | tf.getAnInstantiation() = this)
1137+
tf.getAnInstantiation() = this
1138+
}
1139+
1140+
TemplateFunction getTemplate() {
1141+
result = tf
10931142
}
10941143
}
10951144

cpp/ql/src/semmle/code/cpp/PrintAST.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ class FunctionNode extends ASTNode {
490490
}
491491

492492
override string toString() {
493-
result = func.getFullSignature()
493+
result = func.getIdentityString()
494494
}
495495

496496
override PrintASTNode getChild(int childIndex) {
@@ -528,7 +528,7 @@ class FunctionNode extends ASTNode {
528528
file,
529529
line,
530530
column,
531-
function.getFullSignature()
531+
function.getIdentityString()
532532
)
533533
}
534534

0 commit comments

Comments
 (0)