Symbol Resolution¶
This pages describes the main functionality behind symbol resolution in the CPG library. This is mostly done by the SymbolResolver
pass, in combination with the symbol lookup API (see Scopes and Symbols). In addition to the lookup of a symbol, the resolution takes the input of the lookup and provides a "definite" decision which symbol is used. This mostly referred to symbols / names used in a Reference
or a CallExpression
(which also has a reference as its CallExpression::callee
).
The SymbolResolver
Pass¶
The SymbolResolver
pass takes care of the heavy lifting of symbol (or rather reference) resolving:
- It sets the
Reference::refersTo
property, - and sets the
CallExpression::invokes
property, - and finally takes cares of operator overloading (if the language supports it).
In a way, it can be compared to a linker step in a compiler. The pass operates on a single Component
and starts by identifying EOG starter nodes within the component. These node "start" an EOG sub-graph, i.e., they do not have any previous EOG edges. The symbol resolver uses the ScopedWalker
with a special set-up that traverses the EOG starting with each EOG starter node until it reaches the end. This ensures that symbols are resolved in the correct order of "evaluation", e.g., that a base of a member expression is resolved before the expression itself. This ensures that necessary type information on the base are available in order to resolve appropriate fields of the member expression.
The symbol resolver itself has gone through many re-writes over the years and there is still some code left that we consider legacy. These functions are marked as such, and we aim to remove them slowly.
Resolving References¶
The main functionality lies in ScopeManager::handleReference
. For all Reference
nodes (that are not MemberExpression
nodes) we use the symbol lookup API to find declaration candidates for the name the reference is referring to. This candidate list is then stored in Reference::candidates
. If the reference is the CallExpression::callee
property of a call, we abort here and jump to Resolve Calls.
Otherwise, we currently take the first entry of the candidate list and set the Reference::refersTo
property to it.
Resolve Calls¶
Prequisite: The CallExpression::callee
reference must have been resolved (see Resolving References).