1
// This file is part of the AspectC++ compiler 'ac++'.
2
// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org)
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program 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.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
#include "IncludeGraph.h"
21
#include "Puma/PreTreeNodes.h"
22
#include "Puma/PreSonIterator.h"
23
#include "Puma/CTranslationUnit.h"
25
void IncludeGraph::init (CTranslationUnit &tunit) {
27
// search for #includes
28
iterateNodes (tunit.cpp_tree ());
31
// Go through the nodes.
32
void IncludeGraph::iterateNodes (PreTree* node) {
33
PreSonIterator i (node); // the order is important!
35
for (i.first (); ! i.isDone (); i.next ())
36
i.currentItem ()->accept (*this);
39
// handle include directive node
40
void IncludeGraph::visitPreIncludeDirective_Pre (PreIncludeDirective* node) {
42
// this_unit is the unit where the include directive is located
43
Token *this_token = node->startToken ();
44
Unit *this_unit = (Unit*)this_token->belonging_to ();
46
// cout << "in " << this_unit->name () << " " << this_token->location () << " "
47
// << _project.isBelow (this_unit) << endl;
49
// include if expanded by preprocessor
50
if (node->daughters () == 1) {
52
Unit *included_unit = ((PreInclSemNode*)node->daughter (0))->unit ();
54
// cout << " included: " << included_unit->name () << " " <<
55
// _project.isBelow (included_unit) << endl;
57
add_edge (this_unit, included_unit);
61
// Add an edge to the include graph from 'a' to 'b'
62
void IncludeGraph::add_edge (const Unit *a, const Unit *b) {
63
Node &this_node = find (a);
64
Node &included_node = find (b);
65
this_node._includes.insert (&included_node);
68
// find/create an entry in '_nodes'
69
IncludeGraph::Node &IncludeGraph::find (const Unit *unit) {
70
std::pair<Map::iterator,bool> p =
71
_nodes.insert (Map::value_type (unit, Node (unit)));
72
return p.first->second;
75
// Checks whether on unit 'a' directly or indirecly includes another unit 'b'
76
bool IncludeGraph::includes (const Unit *a, const Unit *b) const {
77
Map::const_iterator a_iter = _nodes.find (a);
78
Map::const_iterator b_iter = _nodes.find (b);
79
if (a_iter == _nodes.end () || b_iter == _nodes.end ())
81
bool result = includes (a_iter->second, b_iter->second);
83
// reset 'visited' flags
89
void IncludeGraph::reset_visited () const {
90
// reset 'visited' flags
91
Map::const_iterator iter = _nodes.begin ();
92
while (iter != _nodes.end ()) {
93
const IncludeGraph::Node &node = iter->second;
94
node._visited = false;
99
// Checks whether there is a path from node 'a' to 'b' in the include graph
100
bool IncludeGraph::includes (const Node &a, const Node &b) const {
105
set<Node*>::iterator iter = a._includes.begin ();
108
while (iter != a._includes.end ()) {
109
if (*iter == &b || includes (**iter, b)) {
118
void IncludeGraph::included_files (const Node &node,
119
set<const Unit*> &units, bool only_project) const {
125
set<Node*>::iterator iter = node._includes.begin ();
126
node._visited = true;
127
while (iter != node._includes.end ()) {
128
Unit *unit = (Unit*)(*iter)->_unit;
129
if (!only_project || _project.isBelow (unit))
131
included_files (**iter, units);
136
// Get all files the are directly or indirectly included
137
bool IncludeGraph::included_files (const Unit *unit,
138
set<const Unit*> &units, bool only_project) const {
139
Map::const_iterator iter = _nodes.find (unit);
140
if (iter == _nodes.end ())
143
// collect the included file for this node
144
included_files (iter->second, units, only_project);
146
// reset 'visited' flags
152
void IncludeGraph::Node::dump () const {
153
cout << "unit " << _unit << " '" << _unit->name () << "' includes:" << endl;
154
set<Node*>::iterator iter = _includes.begin ();
155
while (iter != _includes.end ()) {
156
cout << " " << (*iter)->_unit->name () << endl;
161
void IncludeGraph::dump () const {
162
Map::const_iterator iter = _nodes.begin ();
163
while (iter != _nodes.end ()) {
164
const IncludeGraph::Node &node = iter->second;