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