xref: /llvm-project/clang-tools-extra/clang-include-fixer/find-all-symbols/SymbolInfo.h (revision a996cc217cefb9071888de38c6f05e5742d0106f)
1 //===-- SymbolInfo.h - Symbol Info ------------------------------*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_FIND_ALL_SYMBOLS_SYMBOLINFO_H
10 #define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_FIND_ALL_SYMBOLS_SYMBOLINFO_H
11 
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/YAMLTraits.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include <set>
16 #include <string>
17 #include <vector>
18 
19 namespace clang {
20 namespace find_all_symbols {
21 /// Describes a named symbol from a header.
22 /// Symbols with the same qualified name and type (e.g. function overloads)
23 /// that appear in the same header are represented by a single SymbolInfo.
24 ///
25 /// TODO: keep track of instances, e.g. overload locations and signatures.
26 class SymbolInfo {
27 public:
28   /// The SymbolInfo Type.
29   enum class SymbolKind {
30     Function,
31     Class,
32     Variable,
33     TypedefName,
34     EnumDecl,
35     EnumConstantDecl,
36     Macro,
37     Unknown,
38   };
39 
40   /// The Context Type.
41   enum class ContextType {
42     Namespace, // Symbols declared in a namespace.
43     Record,    // Symbols declared in a class.
44     EnumDecl,  // Enum constants declared in a enum declaration.
45   };
46 
47   /// A pair of <ContextType, ContextName>.
48   typedef std::pair<ContextType, std::string> Context;
49 
50   // Signals are signals gathered by observing how a symbol is used.
51   // These are used to rank results.
52   struct Signals {
SignalsSignals53     Signals() {}
SignalsSignals54     Signals(unsigned Seen, unsigned Used) : Seen(Seen), Used(Used) {}
55 
56     // Number of times this symbol was visible to a TU.
57     unsigned Seen = 0;
58 
59     // Number of times this symbol was referenced a TU's main file.
60     unsigned Used = 0;
61 
62     Signals &operator+=(const Signals &RHS);
63     Signals operator+(const Signals &RHS) const;
64     bool operator==(const Signals &RHS) const;
65   };
66 
67   using SignalMap = std::map<SymbolInfo, Signals>;
68 
69   // The default constructor is required by YAML traits in
70   // LLVM_YAML_IS_DOCUMENT_LIST_VECTOR.
SymbolInfo()71   SymbolInfo() : Type(SymbolKind::Unknown) {}
72 
73   SymbolInfo(llvm::StringRef Name, SymbolKind Type, llvm::StringRef FilePath,
74              const std::vector<Context> &Contexts);
75 
SetFilePath(llvm::StringRef Path)76   void SetFilePath(llvm::StringRef Path) { FilePath = std::string(Path); }
77 
78   /// Get symbol name.
getName()79   llvm::StringRef getName() const { return Name; }
80 
81   /// Get the fully-qualified symbol name.
82   std::string getQualifiedName() const;
83 
84   /// Get symbol type.
getSymbolKind()85   SymbolKind getSymbolKind() const { return Type; }
86 
87   /// Get a relative file path where symbol comes from.
getFilePath()88   llvm::StringRef getFilePath() const { return FilePath; }
89 
90   /// Get symbol contexts.
getContexts()91   const std::vector<SymbolInfo::Context> &getContexts() const {
92     return Contexts;
93   }
94 
95   bool operator<(const SymbolInfo &Symbol) const;
96 
97   bool operator==(const SymbolInfo &Symbol) const;
98 
99 private:
100   friend struct llvm::yaml::MappingTraits<struct SymbolAndSignals>;
101 
102   /// Identifier name.
103   std::string Name;
104 
105   /// Symbol type.
106   SymbolKind Type;
107 
108   /// The file path where the symbol comes from. It's a relative file
109   /// path based on the build directory.
110   std::string FilePath;
111 
112   /// Contains information about symbol contexts. Context information is
113   /// stored from the inner-most level to outer-most level.
114   ///
115   /// For example, if a symbol 'x' is declared as:
116   ///     namespace na { namespace nb { class A { int x; } } }
117   /// The contexts would be { {RECORD, "A"}, {NAMESPACE, "nb"}, {NAMESPACE,
118   /// "na"} }.
119   /// The name of an anonymous namespace is "".
120   ///
121   /// If the symbol is declared in `TranslationUnitDecl`, it has no context.
122   std::vector<Context> Contexts;
123 };
124 
125 struct SymbolAndSignals {
126   SymbolInfo Symbol;
127   SymbolInfo::Signals Signals;
128   bool operator==(const SymbolAndSignals& RHS) const;
129 };
130 
131 /// Write SymbolInfos to a stream (YAML format).
132 bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
133                               const SymbolInfo::SignalMap &Symbols);
134 
135 /// Read SymbolInfos from a YAML document.
136 std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml);
137 
138 } // namespace find_all_symbols
139 } // namespace clang
140 
141 #endif // LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_FIND_ALL_SYMBOLS_SYMBOLINFO_H
142