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 llvm::yaml::IO;
17 using llvm::yaml::Input;
18 using ContextType = clang::find_all_symbols::SymbolInfo::ContextType;
19 using clang::find_all_symbols::SymbolInfo;
20 using clang::find_all_symbols::SymbolAndSignals;
21 using SymbolKind = clang::find_all_symbols::SymbolInfo::SymbolKind;
22
23 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(SymbolAndSignals)
24 LLVM_YAML_IS_SEQUENCE_VECTOR(SymbolInfo::Context)
25
26 namespace llvm {
27 namespace yaml {
28 template <> struct MappingTraits<SymbolAndSignals> {
mappingllvm::yaml::MappingTraits29 static void mapping(IO &io, SymbolAndSignals &Symbol) {
30 io.mapRequired("Name", Symbol.Symbol.Name);
31 io.mapRequired("Contexts", Symbol.Symbol.Contexts);
32 io.mapRequired("FilePath", Symbol.Symbol.FilePath);
33 io.mapRequired("Type", Symbol.Symbol.Type);
34 io.mapRequired("Seen", Symbol.Signals.Seen);
35 io.mapRequired("Used", Symbol.Signals.Used);
36 }
37 };
38
39 template <> struct ScalarEnumerationTraits<ContextType> {
enumerationllvm::yaml::ScalarEnumerationTraits40 static void enumeration(IO &io, ContextType &value) {
41 io.enumCase(value, "Record", ContextType::Record);
42 io.enumCase(value, "Namespace", ContextType::Namespace);
43 io.enumCase(value, "EnumDecl", ContextType::EnumDecl);
44 }
45 };
46
47 template <> struct ScalarEnumerationTraits<SymbolKind> {
enumerationllvm::yaml::ScalarEnumerationTraits48 static void enumeration(IO &io, SymbolKind &value) {
49 io.enumCase(value, "Variable", SymbolKind::Variable);
50 io.enumCase(value, "Function", SymbolKind::Function);
51 io.enumCase(value, "Class", SymbolKind::Class);
52 io.enumCase(value, "TypedefName", SymbolKind::TypedefName);
53 io.enumCase(value, "EnumDecl", SymbolKind::EnumDecl);
54 io.enumCase(value, "EnumConstantDecl", SymbolKind::EnumConstantDecl);
55 io.enumCase(value, "Macro", SymbolKind::Macro);
56 io.enumCase(value, "Unknown", SymbolKind::Unknown);
57 }
58 };
59
60 template <> struct MappingTraits<SymbolInfo::Context> {
mappingllvm::yaml::MappingTraits61 static void mapping(IO &io, SymbolInfo::Context &Context) {
62 io.mapRequired("ContextType", Context.first);
63 io.mapRequired("ContextName", Context.second);
64 }
65 };
66
67 } // namespace yaml
68 } // namespace llvm
69
70 namespace clang {
71 namespace find_all_symbols {
72
SymbolInfo(llvm::StringRef Name,SymbolKind Type,llvm::StringRef FilePath,const std::vector<Context> & Contexts)73 SymbolInfo::SymbolInfo(llvm::StringRef Name, SymbolKind Type,
74 llvm::StringRef FilePath,
75 const std::vector<Context> &Contexts)
76 : Name(Name), Type(Type), FilePath(FilePath), Contexts(Contexts) {}
77
operator ==(const SymbolInfo & Symbol) const78 bool SymbolInfo::operator==(const SymbolInfo &Symbol) const {
79 return std::tie(Name, Type, FilePath, Contexts) ==
80 std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
81 }
82
operator <(const SymbolInfo & Symbol) const83 bool SymbolInfo::operator<(const SymbolInfo &Symbol) const {
84 return std::tie(Name, Type, FilePath, Contexts) <
85 std::tie(Symbol.Name, Symbol.Type, Symbol.FilePath, Symbol.Contexts);
86 }
87
getQualifiedName() const88 std::string SymbolInfo::getQualifiedName() const {
89 std::string QualifiedName = Name;
90 for (const auto &Context : Contexts) {
91 if (Context.first == ContextType::EnumDecl)
92 continue;
93 QualifiedName = Context.second + "::" + QualifiedName;
94 }
95 return QualifiedName;
96 }
97
operator +=(const Signals & RHS)98 SymbolInfo::Signals &SymbolInfo::Signals::operator+=(const Signals &RHS) {
99 Seen += RHS.Seen;
100 Used += RHS.Used;
101 return *this;
102 }
103
operator +(const Signals & RHS) const104 SymbolInfo::Signals SymbolInfo::Signals::operator+(const Signals &RHS) const {
105 Signals Result = *this;
106 Result += RHS;
107 return Result;
108 }
109
operator ==(const Signals & RHS) const110 bool SymbolInfo::Signals::operator==(const Signals &RHS) const {
111 return std::tie(Seen, Used) == std::tie(RHS.Seen, RHS.Used);
112 }
113
operator ==(const SymbolAndSignals & RHS) const114 bool SymbolAndSignals::operator==(const SymbolAndSignals& RHS) const {
115 return std::tie(Symbol, Signals) == std::tie(RHS.Symbol, RHS.Signals);
116 }
117
WriteSymbolInfosToStream(llvm::raw_ostream & OS,const SymbolInfo::SignalMap & Symbols)118 bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
119 const SymbolInfo::SignalMap &Symbols) {
120 llvm::yaml::Output yout(OS);
121 for (const auto &Symbol : Symbols) {
122 SymbolAndSignals S{Symbol.first, Symbol.second};
123 yout << S;
124 }
125 return true;
126 }
127
ReadSymbolInfosFromYAML(llvm::StringRef Yaml)128 std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml) {
129 std::vector<SymbolAndSignals> Symbols;
130 llvm::yaml::Input yin(Yaml);
131 yin >> Symbols;
132 return Symbols;
133 }
134
135 } // namespace find_all_symbols
136 } // namespace clang
137