xref: /llvm-project/clang-tools-extra/clang-include-fixer/find-all-symbols/SymbolInfo.cpp (revision 255ee643a8c559375a9c9787ef7d121790040818)
1 //===-- SymbolInfo.cpp - 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 #include "SymbolInfo.h"
10 #include "llvm/Support/CommandLine.h"
11 #include "llvm/Support/FileSystem.h"
12 #include "llvm/Support/YAMLTraits.h"
13 #include "llvm/Support/raw_ostream.h"
14 
15 using llvm::yaml::MappingTraits;
16 using ContextType = clang::find_all_symbols::SymbolInfo::ContextType;
17 using clang::find_all_symbols::SymbolInfo;
18 using clang::find_all_symbols::SymbolAndSignals;
19 using SymbolKind = clang::find_all_symbols::SymbolInfo::SymbolKind;
20 
21 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(SymbolAndSignals)
22 LLVM_YAML_IS_SEQUENCE_VECTOR(SymbolInfo::Context)
23 
24 namespace llvm {
25 namespace yaml {
26 template <> struct MappingTraits<SymbolAndSignals> {
mappingllvm::yaml::MappingTraits27   static void mapping(IO &io, SymbolAndSignals &Symbol) {
28     io.mapRequired("Name", Symbol.Symbol.Name);
29     io.mapRequired("Contexts", Symbol.Symbol.Contexts);
30     io.mapRequired("FilePath", Symbol.Symbol.FilePath);
31     io.mapRequired("Type", Symbol.Symbol.Type);
32     io.mapRequired("Seen", Symbol.Signals.Seen);
33     io.mapRequired("Used", Symbol.Signals.Used);
34   }
35 };
36 
37 template <> struct ScalarEnumerationTraits<ContextType> {
enumerationllvm::yaml::ScalarEnumerationTraits38   static void enumeration(IO &io, ContextType &value) {
39     io.enumCase(value, "Record", ContextType::Record);
40     io.enumCase(value, "Namespace", ContextType::Namespace);
41     io.enumCase(value, "EnumDecl", ContextType::EnumDecl);
42   }
43 };
44 
45 template <> struct ScalarEnumerationTraits<SymbolKind> {
enumerationllvm::yaml::ScalarEnumerationTraits46   static void enumeration(IO &io, SymbolKind &value) {
47     io.enumCase(value, "Variable", SymbolKind::Variable);
48     io.enumCase(value, "Function", SymbolKind::Function);
49     io.enumCase(value, "Class", SymbolKind::Class);
50     io.enumCase(value, "TypedefName", SymbolKind::TypedefName);
51     io.enumCase(value, "EnumDecl", SymbolKind::EnumDecl);
52     io.enumCase(value, "EnumConstantDecl", SymbolKind::EnumConstantDecl);
53     io.enumCase(value, "Macro", SymbolKind::Macro);
54     io.enumCase(value, "Unknown", SymbolKind::Unknown);
55   }
56 };
57 
58 template <> struct MappingTraits<SymbolInfo::Context> {
mappingllvm::yaml::MappingTraits59   static void mapping(IO &io, SymbolInfo::Context &Context) {
60     io.mapRequired("ContextType", Context.first);
61     io.mapRequired("ContextName", Context.second);
62   }
63 };
64 
65 } // namespace yaml
66 } // namespace llvm
67 
68 namespace clang {
69 namespace find_all_symbols {
70 
SymbolInfo(llvm::StringRef Name,SymbolKind Type,llvm::StringRef FilePath,const std::vector<Context> & Contexts)71 SymbolInfo::SymbolInfo(llvm::StringRef Name, SymbolKind Type,
72                        llvm::StringRef FilePath,
73                        const std::vector<Context> &Contexts)
74     : Name(Name), Type(Type), FilePath(FilePath), Contexts(Contexts) {}
75 
operator ==(const SymbolInfo & Symbol) const76 bool SymbolInfo::operator==(const SymbolInfo &Symbol) const {
77   return std::tie(Name, Type, FilePath, Contexts) ==
78          std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
79 }
80 
operator <(const SymbolInfo & Symbol) const81 bool SymbolInfo::operator<(const SymbolInfo &Symbol) const {
82   return std::tie(Name, Type, FilePath, Contexts) <
83          std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
84 }
85 
getQualifiedName() const86 std::string SymbolInfo::getQualifiedName() const {
87   std::string QualifiedName = Name;
88   for (const auto &Context : Contexts) {
89     if (Context.first == ContextType::EnumDecl)
90       continue;
91     QualifiedName = Context.second + "::" + QualifiedName;
92   }
93   return QualifiedName;
94 }
95 
operator +=(const Signals & RHS)96 SymbolInfo::Signals &SymbolInfo::Signals::operator+=(const Signals &RHS) {
97   Seen += RHS.Seen;
98   Used += RHS.Used;
99   return *this;
100 }
101 
operator +(const Signals & RHS) const102 SymbolInfo::Signals SymbolInfo::Signals::operator+(const Signals &RHS) const {
103   Signals Result = *this;
104   Result += RHS;
105   return Result;
106 }
107 
operator ==(const Signals & RHS) const108 bool SymbolInfo::Signals::operator==(const Signals &RHS) const {
109   return std::tie(Seen, Used) == std::tie(RHS.Seen, RHS.Used);
110 }
111 
operator ==(const SymbolAndSignals & RHS) const112 bool SymbolAndSignals::operator==(const SymbolAndSignals& RHS) const {
113   return std::tie(Symbol, Signals) == std::tie(RHS.Symbol, RHS.Signals);
114 }
115 
WriteSymbolInfosToStream(llvm::raw_ostream & OS,const SymbolInfo::SignalMap & Symbols)116 bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
117                               const SymbolInfo::SignalMap &Symbols) {
118   llvm::yaml::Output yout(OS);
119   for (const auto &Symbol : Symbols) {
120     SymbolAndSignals S{Symbol.first, Symbol.second};
121     yout << S;
122   }
123   return true;
124 }
125 
ReadSymbolInfosFromYAML(llvm::StringRef Yaml)126 std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml) {
127   std::vector<SymbolAndSignals> Symbols;
128   llvm::yaml::Input yin(Yaml);
129   yin >> Symbols;
130   return Symbols;
131 }
132 
133 } // namespace find_all_symbols
134 } // namespace clang
135