File indexing completed on 2024-05-12 04:37:43

0001 /*
0002     SPDX-FileCopyrightText: 2010 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "controlflowgraph.h"
0008 #include "controlflownode.h"
0009 
0010 using namespace KDevelop;
0011 
0012 class KDevelop::ControlFlowGraphPrivate
0013 {
0014 public:
0015     QList<ControlFlowNode*> m_nodes;
0016     QMap<KDevelop::Declaration*, ControlFlowNode*> m_funcNodes;
0017     QVector<ControlFlowNode*> m_deadNodes;
0018 };
0019 
0020 ControlFlowGraph::ControlFlowGraph()
0021     : d_ptr(new ControlFlowGraphPrivate)
0022 {}
0023 
0024 ControlFlowGraph::~ControlFlowGraph()
0025 {
0026     clear();
0027 }
0028 
0029 void ControlFlowGraph::addEntry(ControlFlowNode* n)
0030 {
0031     Q_D(ControlFlowGraph);
0032 
0033     d->m_nodes += n;
0034 }
0035 
0036 void ControlFlowGraph::addEntry(Declaration* decl, ControlFlowNode* n)
0037 {
0038     Q_D(ControlFlowGraph);
0039 
0040     Q_ASSERT(d);
0041     Q_ASSERT(decl);
0042     d->m_funcNodes.insert(decl, n);
0043 }
0044 
0045 void ControlFlowGraph::addDeadNode(ControlFlowNode* n)
0046 {
0047     Q_D(ControlFlowGraph);
0048 
0049     d->m_deadNodes += n;
0050 }
0051 
0052 void clearNodeRecursively(ControlFlowNode* node, QSet<ControlFlowNode*>& deleted)
0053 {
0054     if (!node || deleted.contains(node))
0055         return;
0056 
0057     deleted += node;
0058 
0059     clearNodeRecursively(node->next(), deleted);
0060     clearNodeRecursively(node->alternative(), deleted);
0061 
0062     delete node;
0063 }
0064 
0065 void ControlFlowGraph::clear()
0066 {
0067     Q_D(ControlFlowGraph);
0068 
0069     QSet<ControlFlowNode*> deleted;
0070     for (ControlFlowNode* node : qAsConst(d->m_funcNodes)) {
0071         clearNodeRecursively(node, deleted);
0072     }
0073 
0074     for (ControlFlowNode* node : qAsConst(d->m_nodes)) {
0075         clearNodeRecursively(node, deleted);
0076     }
0077 
0078     for (ControlFlowNode* node : qAsConst(d->m_deadNodes)) {
0079         clearNodeRecursively(node, deleted);
0080     }
0081 
0082     d->m_nodes.clear();
0083     d->m_funcNodes.clear();
0084     d->m_deadNodes.clear();
0085 }
0086 
0087 QList<ControlFlowNode*> ControlFlowGraph::rootNodes() const
0088 {
0089     Q_D(const ControlFlowGraph);
0090 
0091     return d->m_funcNodes.values() + d->m_nodes;
0092 }
0093 
0094 QVector<ControlFlowNode*> ControlFlowGraph::deadNodes() const
0095 {
0096     Q_D(const ControlFlowGraph);
0097 
0098     return d->m_deadNodes;
0099 }
0100 
0101 QList<Declaration*> ControlFlowGraph::declarations() const
0102 {
0103     Q_D(const ControlFlowGraph);
0104 
0105     return d->m_funcNodes.keys();
0106 }
0107 
0108 ControlFlowNode* ControlFlowGraph::nodeForDeclaration(Declaration* decl) const
0109 {
0110     Q_D(const ControlFlowGraph);
0111 
0112     return d->m_funcNodes.value(decl);
0113 }