File: IncludeGraph.h

package info (click to toggle)
aspectc%2B%2B 1%3A2.2%2Bgit20181008-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 18,704 kB
  • sloc: cpp: 110,629; ansic: 7,644; sh: 2,192; makefile: 1,317; pascal: 634; python: 402; xml: 349
file content (134 lines) | stat: -rw-r--r-- 4,433 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// This file is part of the AspectC++ compiler 'ac++'.
// Copyright (C) 1999-2003  The 'ac++' developers (see aspectc.org)
//                                                                
// This program is free software;  you can redistribute it and/or 
// modify it under the terms of the GNU General Public License as 
// published by the Free Software Foundation; either version 2 of 
// the License, or (at your option) any later version.            
//                                                                
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
// GNU General Public License for more details.                   
//                                                                
// You should have received a copy of the GNU General Public      
// License along with this program; if not, write to the Free     
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
// MA  02111-1307  USA                                            

#ifndef __include_graph_h__
#define __include_graph_h__

// Visitor, which expands all project-local includes 

#ifdef FRONTEND_PUMA
#include "Puma/PreVisitor.h"
namespace Puma {
  class CTranslationUnit;
  class Unit;
  class CProject;
}
#else
#include "clang/Lex/PPCallbacks.h"
#endif

#include <map>
using std::map;
#include <set>
using std::set;
#include <iostream>
using std::ostream;
using std::endl;

#include "ACFileID.h"
#include "ACProject.h"

class IncludeGraph
#ifdef FRONTEND_PUMA
: public Puma::PreVisitor
#endif
{

  struct Node {
    ACFileID _unit;
    mutable bool _visited; // for cycle detection
    set<Node*> _includes;
    Node (ACFileID u) : _unit (u), _visited (false) {}
    void dump () const;
  };
  
  // associates a node object to each unit
  typedef map<ACFileID, Node> Map;
  Map _nodes;
  
  // the project to which all this belongs
  ACProject &_project;
  
#ifdef FRONTEND_PUMA
  // Go through the nodes of the syntax tree.
  void iterateNodes (Puma::PreTree*);

  // Visiting the parts of the preprocessor syntax tree.
  void visitPreIncludeDirective_Pre (Puma::PreIncludeDirective*);
#endif

  // find/create an entry in '_nodes'
  Node &find (ACFileID);
  
  // Checks whether there is a path from node 'a' to 'b' in the include graph
  bool includes (const Node &a, const Node &b) const;

  // collect all units included by some node  
  void included_files (const Node &node, set<ACFileID> &units,
    bool only_project = true) const;
  
  // Reset the 'visited' flag of all nodes in the DAG
  void reset_visited () const;
  
public:
  IncludeGraph (ACProject &p) : _project (p) {}
#ifdef FRONTEND_PUMA
  IncludeGraph (ACProject &p, Puma::CTranslationUnit &tunit) : _project (p) {
    init (tunit);
  }
  virtual ~IncludeGraph () {}

  // Fills the include graph
  void init (Puma::CTranslationUnit &tunit);
  void init (Puma::PreTree *tree) { iterateNodes (tree); } // for new phase 1
#else
  // Callback object to add includes to the graph during a preprocessor run.
  class IncludeGraphCallback : public clang::PPCallbacks {
    IncludeGraph &_ig;

    // Callback from clang when it sees an inclusion directive.
    virtual void InclusionDirective (clang::SourceLocation HashLoc,
                                     const clang::Token &IncludeTok,
                                     llvm::StringRef FileName,
                                     bool IsAngled,
                                     clang::CharSourceRange FilenameRange,
                                     const clang::FileEntry *File,
                                     llvm::StringRef SearchPath,
                                     llvm::StringRef RelativePath,
                                     const clang::Module *Imported);

  public:
    IncludeGraphCallback (IncludeGraph &ig) : _ig(ig) {}
  };
#endif

  // Checks whether on unit 'a' directly or indirecly includes another unit 'b'
  bool includes (ACFileID a, ACFileID b) const;
  
  // Get all files the are directly or indirectly included
  bool included_files (ACFileID unit, set<ACFileID> &units,
    bool only_project = true) const;

  // Add an edge to the include graph from 'a' to 'b'
  void add_edge (ACFileID a, ACFileID b);
  
  // print all nodes
  void dump () const;
};  	    

#endif // __include_graph_h__