Skip to content

Commit b97ff1a

Browse files
committed
C++: Take QualifiedName.qll from Ian's branch
This imports `QualifiedName.qll` from 2f74a456290b9e0850b7308582e07f5d68de3a36 and makes minimal changes so it compiles. Original author: Ian Lynagh <ian@semmle.com>
1 parent 82a6629 commit b97ff1a

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
private import semmle.code.cpp.internal.ResolveClass as ResolveClass
2+
3+
class Namespace extends @namespace {
4+
string toString() { result = "QualifiedName Namespace" }
5+
6+
string getName() { namespaces(this, result) }
7+
8+
string getQualifiedName() {
9+
if namespacembrs(_, this)
10+
then exists(Namespace ns |
11+
namespacembrs(ns, this) and
12+
result = ns.getQualifiedName() + "::" + this.getName())
13+
else result = this.getName()
14+
}
15+
16+
Declaration getADeclaration() {
17+
if this.getName() = ""
18+
then result.isTopLevel() and not namespacembrs(_, result)
19+
else namespacembrs(this, result)
20+
}
21+
}
22+
23+
abstract class Declaration extends @declaration {
24+
string toString() { result = "QualifiedName Declaration" }
25+
26+
/** Gets the name of this declaration. */
27+
abstract string getName();
28+
29+
// Note: This is not as full featured as the getNamespace in the AST,
30+
// but it covers the cases we need here.
31+
Namespace getNamespace() {
32+
// Top level declaration in a namespace ...
33+
result.getADeclaration() = this
34+
// ... or nested in another structure.
35+
or
36+
exists (Declaration m
37+
| m = this and result = m.getDeclaringType().getNamespace())
38+
}
39+
40+
string getQualifiedName() {
41+
// MemberFunction, MemberVariable, MemberType
42+
exists (Declaration m
43+
| m = this and
44+
result = m.getDeclaringType().getQualifiedName() + "::" + m.getName())
45+
or
46+
exists (EnumConstant c
47+
| c = this and
48+
result = c.getDeclaringEnum().getQualifiedName() + "::" + c.getName())
49+
or
50+
exists (GlobalOrNamespaceVariable v, string s1, string s2
51+
| v = this and
52+
s2 = v.getNamespace().getQualifiedName() and
53+
s1 = v.getName()
54+
| (s2 != "" and result = s2 + "::" + s1) or (s2 = "" and result = s1))
55+
or
56+
exists (Function f, string s1, string s2
57+
| f = this and f.isTopLevel() and
58+
s2 = f.getNamespace().getQualifiedName() and
59+
s1 = f.getName()
60+
| (s2 != "" and result = s2 + "::" + s1) or (s2 = "" and result = s1))
61+
or
62+
exists (UserType t, string s1, string s2
63+
| t = this and t.isTopLevel() and
64+
s2 = t.getNamespace().getQualifiedName() and
65+
s1 = t.getName()
66+
| (s2 != "" and result = s2 + "::" + s1) or (s2 = "" and result = s1))
67+
}
68+
69+
predicate isTopLevel() {
70+
not (this.isMember() or
71+
this instanceof FriendDecl or
72+
this instanceof EnumConstant or
73+
this instanceof Parameter or
74+
this instanceof ProxyClass or
75+
this instanceof LocalVariable or
76+
this instanceof TemplateParameter or
77+
this.(UserType).isLocal())
78+
}
79+
80+
/** Holds if this declaration is a member of a class/struct/union. */
81+
predicate isMember() { this.hasDeclaringType() }
82+
83+
/** Holds if this declaration is a member of a class/struct/union. */
84+
predicate hasDeclaringType() {
85+
exists(this.getDeclaringType())
86+
}
87+
88+
/**
89+
* Gets the class where this member is declared, if it is a member.
90+
* For templates, both the template itself and all instantiations of
91+
* the template are considered to have the same declaring class.
92+
*/
93+
Class getDeclaringType() {
94+
this = result.getAMember()
95+
}
96+
}
97+
98+
class Variable extends Declaration, @variable {
99+
override string getName() { none() }
100+
}
101+
102+
class TemplateVariable extends Variable {
103+
TemplateVariable() { is_variable_template(this) }
104+
105+
Variable getAnInstantiation() { variable_instantiation(result, this) }
106+
}
107+
108+
class LocalScopeVariable extends Variable, @localscopevariable {}
109+
110+
class LocalVariable extends LocalScopeVariable, @localvariable {
111+
override string getName() { localvariables(this, _, result) }
112+
}
113+
114+
class Parameter extends LocalScopeVariable, @parameter {
115+
override string getName() {
116+
exists(int i | params(this, _, i, _) and result = "p#" + i.toString())
117+
}
118+
}
119+
120+
class GlobalOrNamespaceVariable extends Variable, @globalvariable {
121+
override string getName() { globalvariables(this, _, result) }
122+
}
123+
124+
class MemberVariable extends Variable, @membervariable {
125+
MemberVariable() {
126+
this.isMember()
127+
}
128+
129+
override string getName() { membervariables(this, _, result) }
130+
}
131+
132+
class EnumConstant extends Declaration, @enumconstant {
133+
override string getName() { enumconstants(this, _, _, _, result,_) }
134+
135+
UserType getDeclaringEnum() { enumconstants(this, result, _, _, _, _) }
136+
}
137+
138+
class Function extends Declaration, @function {
139+
override string getName() { functions(this, result, _) }
140+
}
141+
142+
class TemplateFunction extends Function {
143+
TemplateFunction() {
144+
is_function_template(this) and function_template_argument(this, _, _)
145+
}
146+
147+
Function getAnInstantiation() {
148+
function_instantiation(result, this)
149+
and not exists(@fun_decl fd |
150+
fun_decls(fd, this, _, _, _) and fun_specialized(fd))
151+
}
152+
}
153+
154+
class UserType extends Declaration, @usertype {
155+
override string getName() { usertypes(this, result, _) }
156+
157+
predicate isLocal() {
158+
enclosingfunction(this, _)
159+
}
160+
}
161+
162+
class ProxyClass extends UserType {
163+
ProxyClass() { usertypes(this, _, 9) }
164+
}
165+
166+
class TemplateParameter extends UserType {
167+
TemplateParameter() { usertypes(this, _, 7) or usertypes(this, _, 8) }
168+
}
169+
170+
class Class extends UserType {
171+
Class() { ResolveClass::isClass(this) }
172+
173+
Declaration getAMember() {
174+
exists(Declaration d | member(this, _ ,d) |
175+
result = d or
176+
result = d.(TemplateClass).getAnInstantiation() or
177+
result = d.(TemplateFunction).getAnInstantiation() or
178+
result = d.(TemplateVariable).getAnInstantiation())
179+
}
180+
}
181+
182+
class TemplateClass extends Class {
183+
TemplateClass() { usertypes(this, _, 6) }
184+
185+
Class getAnInstantiation() {
186+
class_instantiation(result, this) and
187+
class_template_argument(result, _, _)
188+
}
189+
}
190+
191+
deprecated class Property extends Declaration {
192+
Property() { none() }
193+
194+
override string getName() { none() }
195+
}
196+
197+
class FriendDecl extends Declaration, @frienddecl {
198+
override string getName() {
199+
result = this.getDeclaringClass().getName() + "'s friend"
200+
}
201+
202+
Class getDeclaringClass() { frienddecls(this, result, _, _) }
203+
}

0 commit comments

Comments
 (0)