-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathFriendDecl.qll
69 lines (59 loc) · 2.38 KB
/
FriendDecl.qll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* Provides a class representing C++ `friend` declarations.
*/
import semmle.code.cpp.Declaration
private import semmle.code.cpp.internal.ResolveClass
/**
* A C++ friend declaration [N4140 11.3]. For example the two friend
* declarations in class `A` of the following code:
* ```
* class A {
* friend void f(int);
* friend class X;
* };
*
* void f(int x) { ... }
* class X { ... };
* ```
*/
class FriendDecl extends Declaration, @frienddecl {
/**
* Gets the location of this friend declaration. The result is the
* location of the friend declaration itself, not the class or function
* that it refers to. Note: to get the target of the friend declaration,
* use `getFriend`.
*/
override Location getADeclarationLocation() { result = this.getLocation() }
override string getAPrimaryQlClass() { result = "FriendDecl" }
/**
* Implements the abstract method `Declaration.getDefinitionLocation`. A
* friend declaration cannot be a definition because it is only a link to
* another class or function. But we have to provide an implementation of
* this method, so we use the location of the declaration as the location
* of the definition. Note: to get the target of the friend declaration,
* use `getFriend`.
*/
override Location getDefinitionLocation() { result = this.getLocation() }
/** Gets the location of this friend declaration. */
override Location getLocation() { frienddecls(underlyingElement(this), _, _, result) }
/** Gets a descriptive string for this friend declaration. */
override string getName() { result = this.getDeclaringClass().getName() + "'s friend" }
/**
* Friend declarations do not have specifiers. It makes no difference
* whether they are declared in a public, protected or private section of
* the class.
*/
override Specifier getASpecifier() { none() }
/**
* Gets the target of this friend declaration.
* For example: `X` in `class A { friend class X }`.
*/
AccessHolder getFriend() { frienddecls(underlyingElement(this), _, unresolveElement(result), _) }
/**
* Gets the declaring class (also known as the befriending class).
* For example: `A` in `class A { friend class X }`.
*/
Class getDeclaringClass() { frienddecls(underlyingElement(this), unresolveElement(result), _, _) }
/* Holds if this declaration is a top-level declaration. */
override predicate isTopLevel() { none() }
}