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> { |
27 | static void mapping(IO &io, SymbolAndSignals &Symbol) { |
28 | io.mapRequired(Key: "Name" , Val&: Symbol.Symbol.Name); |
29 | io.mapRequired(Key: "Contexts" , Val&: Symbol.Symbol.Contexts); |
30 | io.mapRequired(Key: "FilePath" , Val&: Symbol.Symbol.FilePath); |
31 | io.mapRequired(Key: "Type" , Val&: Symbol.Symbol.Type); |
32 | io.mapRequired(Key: "Seen" , Val&: Symbol.Signals.Seen); |
33 | io.mapRequired(Key: "Used" , Val&: Symbol.Signals.Used); |
34 | } |
35 | }; |
36 | |
37 | template <> struct ScalarEnumerationTraits<ContextType> { |
38 | static void enumeration(IO &io, ContextType &value) { |
39 | io.enumCase(Val&: value, Str: "Record" , ConstVal: ContextType::Record); |
40 | io.enumCase(Val&: value, Str: "Namespace" , ConstVal: ContextType::Namespace); |
41 | io.enumCase(Val&: value, Str: "EnumDecl" , ConstVal: ContextType::EnumDecl); |
42 | } |
43 | }; |
44 | |
45 | template <> struct ScalarEnumerationTraits<SymbolKind> { |
46 | static void enumeration(IO &io, SymbolKind &value) { |
47 | io.enumCase(Val&: value, Str: "Variable" , ConstVal: SymbolKind::Variable); |
48 | io.enumCase(Val&: value, Str: "Function" , ConstVal: SymbolKind::Function); |
49 | io.enumCase(Val&: value, Str: "Class" , ConstVal: SymbolKind::Class); |
50 | io.enumCase(Val&: value, Str: "TypedefName" , ConstVal: SymbolKind::TypedefName); |
51 | io.enumCase(Val&: value, Str: "EnumDecl" , ConstVal: SymbolKind::EnumDecl); |
52 | io.enumCase(Val&: value, Str: "EnumConstantDecl" , ConstVal: SymbolKind::EnumConstantDecl); |
53 | io.enumCase(Val&: value, Str: "Macro" , ConstVal: SymbolKind::Macro); |
54 | io.enumCase(Val&: value, Str: "Unknown" , ConstVal: SymbolKind::Unknown); |
55 | } |
56 | }; |
57 | |
58 | template <> struct MappingTraits<SymbolInfo::Context> { |
59 | static void mapping(IO &io, SymbolInfo::Context &Context) { |
60 | io.mapRequired(Key: "ContextType" , Val&: Context.first); |
61 | io.mapRequired(Key: "ContextName" , Val&: Context.second); |
62 | } |
63 | }; |
64 | |
65 | } // namespace yaml |
66 | } // namespace llvm |
67 | |
68 | namespace clang { |
69 | namespace find_all_symbols { |
70 | |
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 | |
76 | bool SymbolInfo::operator==(const SymbolInfo &Symbol) const { |
77 | return std::tie(args: Name, args: Type, args: FilePath, args: Contexts) == |
78 | std::tie(args: Symbol.Name, args: Symbol.Type, args: Symbol.FilePath, args: Symbol.Contexts); |
79 | } |
80 | |
81 | bool SymbolInfo::operator<(const SymbolInfo &Symbol) const { |
82 | return std::tie(args: Name, args: Type, args: FilePath, args: Contexts) < |
83 | std::tie(args: Symbol.Name, args: Symbol.Type, args: Symbol.FilePath, args: Symbol.Contexts); |
84 | } |
85 | |
86 | 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 | |
96 | SymbolInfo::Signals &SymbolInfo::Signals::operator+=(const Signals &RHS) { |
97 | Seen += RHS.Seen; |
98 | Used += RHS.Used; |
99 | return *this; |
100 | } |
101 | |
102 | SymbolInfo::Signals SymbolInfo::Signals::operator+(const Signals &RHS) const { |
103 | Signals Result = *this; |
104 | Result += RHS; |
105 | return Result; |
106 | } |
107 | |
108 | bool SymbolInfo::Signals::operator==(const Signals &RHS) const { |
109 | return std::tie(args: Seen, args: Used) == std::tie(args: RHS.Seen, args: RHS.Used); |
110 | } |
111 | |
112 | bool SymbolAndSignals::operator==(const SymbolAndSignals& RHS) const { |
113 | return std::tie(args: Symbol, args: Signals) == std::tie(args: RHS.Symbol, args: RHS.Signals); |
114 | } |
115 | |
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: Symbol.first, .Signals: Symbol.second}; |
121 | yout << S; |
122 | } |
123 | return true; |
124 | } |
125 | |
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 | |