/src/solidity/libsolidity/analysis/FunctionCallGraph.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | |
19 | | #pragma once |
20 | | |
21 | | #include <libsolidity/ast/ASTForward.h> |
22 | | #include <libsolidity/ast/ASTVisitor.h> |
23 | | #include <libsolidity/ast/CallGraph.h> |
24 | | |
25 | | #include <deque> |
26 | | #include <ostream> |
27 | | |
28 | | namespace solidity::frontend |
29 | | { |
30 | | |
31 | | /** |
32 | | * Creates a function call graph for a contract at the granularity of Solidity functions and modifiers. |
33 | | * or after deployment. The graph does not preserve temporal relations between calls - edges |
34 | | * coming out of the same node show which calls were performed but not in what order. |
35 | | * |
36 | | * Includes the following special nodes: |
37 | | * - Entry: represents a call from the outside of the contract. |
38 | | * After deployment this is the node that connects to all the functions exposed through the |
39 | | * external interface. At contract creation it connects to the constructors and variable |
40 | | * initializers, which are not explicitly called from within another function. |
41 | | * - InternalDispatch: Represents the internal dispatch function, which calls internal functions |
42 | | * determined at runtime by values of variables and expressions. Functions that are not called |
43 | | * right away get an edge from this node. |
44 | | * |
45 | | * Nodes are a variant of either the enum SpecialNode or a CallableDeclaration which currently |
46 | | * can be a function or a modifier. There are no nodes representing event calls. Instead all |
47 | | * emitted events and created contracts are gathered in separate sets included in the graph just |
48 | | * for that purpose. |
49 | | * |
50 | | * Auto-generated getter functions for public state variables are ignored, but function calls |
51 | | * inside initial assignments are included in the creation graph. |
52 | | * |
53 | | * Only calls reachable from an Entry node are included in the graph. The map representing edges |
54 | | * is also guaranteed to contain keys representing all the reachable functions and modifiers, even |
55 | | * if they have no outgoing edges. |
56 | | */ |
57 | | class FunctionCallGraphBuilder: private ASTConstVisitor |
58 | | { |
59 | | public: |
60 | | static CallGraph buildCreationGraph(ContractDefinition const& _contract); |
61 | | static CallGraph buildDeployedGraph( |
62 | | ContractDefinition const& _contract, |
63 | | CallGraph const& _creationGraph |
64 | | ); |
65 | | |
66 | | private: |
67 | | FunctionCallGraphBuilder(ContractDefinition const& _contract): |
68 | | m_contract(_contract) |
69 | 0 | {} |
70 | | |
71 | | bool visit(FunctionCall const& _functionCall) override; |
72 | | bool visit(EmitStatement const& _emitStatement) override; |
73 | | bool visit(Identifier const& _identifier) override; |
74 | | bool visit(MemberAccess const& _memberAccess) override; |
75 | | bool visit(ModifierInvocation const& _modifierInvocation) override; |
76 | | bool visit(NewExpression const& _newExpression) override; |
77 | | |
78 | | void enqueueCallable(CallableDeclaration const& _callable); |
79 | | void processQueue(); |
80 | | |
81 | | void add(CallGraph::Node _caller, CallGraph::Node _callee); |
82 | | void functionReferenced(CallableDeclaration const& _callable, bool _calledDirectly = true); |
83 | | |
84 | | CallGraph::Node m_currentNode = CallGraph::SpecialNode::Entry; |
85 | | ContractDefinition const& m_contract; |
86 | | CallGraph m_graph; |
87 | | std::deque<CallableDeclaration const*> m_visitQueue; |
88 | | }; |
89 | | |
90 | | std::ostream& operator<<(std::ostream& _out, CallGraph::Node const& _node); |
91 | | |
92 | | } |