clang-tools  8.0.0
HelperDeclRefGraph.h
Go to the documentation of this file.
1 //===-- UsedHelperDeclFinder.h - AST-based call graph for helper decls ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H
11 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H
12 
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "clang/Analysis/CallGraph.h"
15 #include "llvm/ADT/DenseSet.h"
16 #include <memory>
17 #include <vector>
18 
19 namespace clang {
20 namespace move {
21 
22 // A reference graph for finding used/unused helper declarations in a single
23 // translation unit (e.g. old.cc). We don't reuse CallGraph in clang/Analysis
24 // because that CallGraph only supports function declarations.
25 //
26 // Helper declarations include following types:
27 // * function/variable/class definitions in an anonymous namespace.
28 // * static function/variable definitions in a global/named namespace.
29 //
30 // The reference graph is a directed graph. Each node in the graph represents a
31 // helper declaration in old.cc or a non-moved/moved declaration (e.g. class,
32 // function) in old.h, which means each node is associated with a Decl.
33 //
34 // To construct the graph, we use AST matcher to find interesting Decls (usually
35 // a pair of Caller and Callee), and add an edge from the Caller node to the
36 // Callee node.
37 //
38 // Specially, for a class, it might have multiple declarations such methods
39 // and member variables. We only use a single node to present this class, and
40 // this node is associated with the class declaration (CXXRecordDecl).
41 //
42 // The graph has 3 types of edges:
43 // 1. moved_decl => helper_decl
44 // 2. non_moved_decl => helper_decl
45 // 3. helper_decl => helper_decl
47 public:
48  HelperDeclRefGraph() = default;
49  ~HelperDeclRefGraph() = default;
50 
51  // Add a directed edge from the caller node to the callee node.
52  // A new node will be created if the node for Caller/Callee doesn't exist.
53  //
54  // Note that, all class member declarations are represented by a single node
55  // in the graph. The corresponding Decl of this node is the class declaration.
56  void addEdge(const Decl *Caller, const Decl *Callee);
57  CallGraphNode *getNode(const Decl *D) const;
58 
59  // Get all reachable nodes in the graph from the given declaration D's node,
60  // including D.
61  llvm::DenseSet<const CallGraphNode *> getReachableNodes(const Decl *D) const;
62 
63  // Dump the call graph for debug purpose.
64  void dump() const;
65 
66 private:
67  void print(raw_ostream &OS) const;
68  // Lookup a node for the given declaration D. If not found, insert a new
69  // node into the graph.
70  CallGraphNode *getOrInsertNode(Decl *D);
71 
72  typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>
73  DeclMapTy;
74 
75  // DeclMap owns all CallGraphNodes.
76  DeclMapTy DeclMap;
77 };
78 
79 // A builder helps to construct a call graph of helper declarations.
80 class HelperDeclRGBuilder : public ast_matchers::MatchFinder::MatchCallback {
81 public:
83  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
84  const HelperDeclRefGraph *getGraph() const { return RG.get(); }
85 
86  // Find out the outmost enclosing class/function declaration of a given D.
87  // For a CXXMethodDecl, get its CXXRecordDecl; For a VarDecl/FunctionDecl, get
88  // its outmost enclosing FunctionDecl or CXXRecordDecl.
89  // Return D if not found.
90  static const Decl *getOutmostClassOrFunDecl(const Decl *D);
91 
92 private:
93  std::unique_ptr<HelperDeclRefGraph> RG;
94 };
95 
96 } // namespace move
97 } // namespace clang
98 
99 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H
llvm::DenseSet< const CallGraphNode * > getReachableNodes(const Decl *D) const
void addEdge(const Decl *Caller, const Decl *Callee)
const Decl * D
Definition: XRefs.cpp:79
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
const HelperDeclRefGraph * getGraph() const
CallGraphNode * getNode(const Decl *D) const
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//