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 |
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 { |
53 | Signals() {} |
54 | 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. |
71 | SymbolInfo() : Type(SymbolKind::Unknown) {} |
72 | |
73 | SymbolInfo(llvm::StringRef Name, SymbolKind Type, llvm::StringRef FilePath, |
74 | const std::vector<Context> &Contexts); |
75 | |
76 | void SetFilePath(llvm::StringRef Path) { FilePath = std::string(Path); } |
77 | |
78 | /// Get symbol name. |
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. |
85 | SymbolKind getSymbolKind() const { return Type; } |
86 | |
87 | /// Get a relative file path where symbol comes from. |
88 | llvm::StringRef getFilePath() const { return FilePath; } |
89 | |
90 | /// Get symbol contexts. |
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 | |