brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · a9cc22d Raw
99 lines · c
1//===-- UsedHelperDeclFinder.h - AST-based call graph for helper decls ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H11 12#include "clang/ASTMatchers/ASTMatchFinder.h"13#include "clang/Analysis/CallGraph.h"14#include "llvm/ADT/DenseSet.h"15#include <memory>16#include <vector>17 18namespace clang {19namespace move {20 21// A reference graph for finding used/unused helper declarations in a single22// translation unit (e.g. old.cc). We don't reuse CallGraph in clang/Analysis23// because that CallGraph only supports function declarations.24//25// Helper declarations include following types:26//   * function/variable/class definitions in an anonymous namespace.27//   * static function/variable definitions in a global/named namespace.28//29// The reference graph is a directed graph. Each node in the graph represents a30// helper declaration in old.cc or a non-moved/moved declaration (e.g. class,31// function) in old.h, which means each node is associated with a Decl.32//33// To construct the graph, we use AST matcher to find interesting Decls (usually34// a pair of Caller and Callee), and add an edge from the Caller node to the35// Callee node.36//37// Specially, for a class, it might have multiple declarations such methods38// and member variables. We only use a single node to present this class, and39// this node is associated with the class declaration (CXXRecordDecl).40//41// The graph has 3 types of edges:42//   1. moved_decl => helper_decl43//   2. non_moved_decl => helper_decl44//   3. helper_decl => helper_decl45class HelperDeclRefGraph {46public:47  HelperDeclRefGraph() = default;48  ~HelperDeclRefGraph() = default;49 50  // Add a directed edge from the caller node to the callee node.51  // A new node will be created if the node for Caller/Callee doesn't exist.52  //53  // Note that, all class member declarations are represented by a single node54  // in the graph. The corresponding Decl of this node is the class declaration.55  void addEdge(const Decl *Caller, const Decl *Callee);56  CallGraphNode *getNode(const Decl *D) const;57 58  // Get all reachable nodes in the graph from the given declaration D's node,59  // including D.60  llvm::DenseSet<const CallGraphNode *> getReachableNodes(const Decl *D) const;61 62  // Dump the call graph for debug purpose.63  void dump() const;64 65private:66  void print(raw_ostream &OS) const;67  // Lookup a node for the given declaration D. If not found, insert a new68  // node into the graph.69  CallGraphNode *getOrInsertNode(Decl *D);70 71  typedef llvm::DenseMap<const Decl *, std::unique_ptr<CallGraphNode>>72      DeclMapTy;73 74  // DeclMap owns all CallGraphNodes.75  DeclMapTy DeclMap;76};77 78// A builder helps to construct a call graph of helper declarations.79class HelperDeclRGBuilder : public ast_matchers::MatchFinder::MatchCallback {80public:81  HelperDeclRGBuilder() : RG(new HelperDeclRefGraph) {}82  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;83  const HelperDeclRefGraph *getGraph() const { return RG.get(); }84 85  // Find out the outmost enclosing class/function declaration of a given D.86  // For a CXXMethodDecl, get its CXXRecordDecl; For a VarDecl/FunctionDecl, get87  // its outmost enclosing FunctionDecl or CXXRecordDecl.88  // Return D if not found.89  static const Decl *getOutmostClassOrFunDecl(const Decl *D);90 91private:92  std::unique_ptr<HelperDeclRefGraph> RG;93};94 95} // namespace move96} // namespace clang97 98#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_USED_HELPER_DECL_FINDER_H99