Files
codeql/cpp/ql/lib/semmle/code/cpp/FriendDecl.qll
Andrew Eisenberg 2c5dd2dfa3 Packaging: Refactor the cpp libraries
This PR separates the core cpp packs into `codeql/cpp-queries` and
`codeql/cpp-all`.

There are very few lines of code changed. Almost all changes are moving
files around.
2021-08-17 11:22:36 -07:00

70 lines
2.4 KiB
Plaintext

/**
* 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() }
}