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