1*9e3b08aeSAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2*9e3b08aeSAndroid Build Coastguard Worker // -*- mode: C++ -*-
3*9e3b08aeSAndroid Build Coastguard Worker //
4*9e3b08aeSAndroid Build Coastguard Worker // Copyright 2020-2024 Google LLC
5*9e3b08aeSAndroid Build Coastguard Worker //
6*9e3b08aeSAndroid Build Coastguard Worker // Licensed under the Apache License v2.0 with LLVM Exceptions (the
7*9e3b08aeSAndroid Build Coastguard Worker // "License"); you may not use this file except in compliance with the
8*9e3b08aeSAndroid Build Coastguard Worker // License. You may obtain a copy of the License at
9*9e3b08aeSAndroid Build Coastguard Worker //
10*9e3b08aeSAndroid Build Coastguard Worker // https://llvm.org/LICENSE.txt
11*9e3b08aeSAndroid Build Coastguard Worker //
12*9e3b08aeSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
13*9e3b08aeSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
14*9e3b08aeSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*9e3b08aeSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
16*9e3b08aeSAndroid Build Coastguard Worker // limitations under the License.
17*9e3b08aeSAndroid Build Coastguard Worker //
18*9e3b08aeSAndroid Build Coastguard Worker // Author: Giuliano Procida
19*9e3b08aeSAndroid Build Coastguard Worker // Author: Ignes Simeonova
20*9e3b08aeSAndroid Build Coastguard Worker
21*9e3b08aeSAndroid Build Coastguard Worker #include "naming.h"
22*9e3b08aeSAndroid Build Coastguard Worker
23*9e3b08aeSAndroid Build Coastguard Worker #include <ostream>
24*9e3b08aeSAndroid Build Coastguard Worker #include <sstream>
25*9e3b08aeSAndroid Build Coastguard Worker #include <string>
26*9e3b08aeSAndroid Build Coastguard Worker
27*9e3b08aeSAndroid Build Coastguard Worker #include "graph.h"
28*9e3b08aeSAndroid Build Coastguard Worker
29*9e3b08aeSAndroid Build Coastguard Worker namespace stg {
30*9e3b08aeSAndroid Build Coastguard Worker
Add(Side side,Precedence precedence,const std::string & text) const31*9e3b08aeSAndroid Build Coastguard Worker Name Name::Add(Side side, Precedence precedence,
32*9e3b08aeSAndroid Build Coastguard Worker const std::string& text) const {
33*9e3b08aeSAndroid Build Coastguard Worker const bool bracket = precedence < precedence_;
34*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream left;
35*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream right;
36*9e3b08aeSAndroid Build Coastguard Worker
37*9e3b08aeSAndroid Build Coastguard Worker // Bits on the left require whitespace separation when an identifier is being
38*9e3b08aeSAndroid Build Coastguard Worker // added. While it would be simpler to unconditionally add a space, we choose
39*9e3b08aeSAndroid Build Coastguard Worker // to only do this for identifiers and not for pointer and reference tokens,
40*9e3b08aeSAndroid Build Coastguard Worker // except for the longer pointer-to-member syntax.
41*9e3b08aeSAndroid Build Coastguard Worker //
42*9e3b08aeSAndroid Build Coastguard Worker // For illegal types containing && & or & && this could result in &&&.
43*9e3b08aeSAndroid Build Coastguard Worker left << left_;
44*9e3b08aeSAndroid Build Coastguard Worker if (bracket) {
45*9e3b08aeSAndroid Build Coastguard Worker left << '(';
46*9e3b08aeSAndroid Build Coastguard Worker } else if (side == Side::LEFT
47*9e3b08aeSAndroid Build Coastguard Worker && (precedence == Precedence::ATOMIC || text.size() > 2)) {
48*9e3b08aeSAndroid Build Coastguard Worker left << ' ';
49*9e3b08aeSAndroid Build Coastguard Worker }
50*9e3b08aeSAndroid Build Coastguard Worker
51*9e3b08aeSAndroid Build Coastguard Worker (side == Side::LEFT ? left : right) << text;
52*9e3b08aeSAndroid Build Coastguard Worker
53*9e3b08aeSAndroid Build Coastguard Worker // Bits on the right are arrays [] and functions () and need no whitespace.
54*9e3b08aeSAndroid Build Coastguard Worker if (bracket) {
55*9e3b08aeSAndroid Build Coastguard Worker right << ')';
56*9e3b08aeSAndroid Build Coastguard Worker }
57*9e3b08aeSAndroid Build Coastguard Worker right << right_;
58*9e3b08aeSAndroid Build Coastguard Worker
59*9e3b08aeSAndroid Build Coastguard Worker return Name{left.str(), precedence, right.str()};
60*9e3b08aeSAndroid Build Coastguard Worker }
61*9e3b08aeSAndroid Build Coastguard Worker
Qualify(Qualifier qualifier) const62*9e3b08aeSAndroid Build Coastguard Worker Name Name::Qualify(Qualifier qualifier) const {
63*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
64*9e3b08aeSAndroid Build Coastguard Worker // Qualifiers attach without affecting precedence but the precedence
65*9e3b08aeSAndroid Build Coastguard Worker // determines the relative position of the qualifier.
66*9e3b08aeSAndroid Build Coastguard Worker switch (precedence_) {
67*9e3b08aeSAndroid Build Coastguard Worker case Precedence::NIL: {
68*9e3b08aeSAndroid Build Coastguard Worker // Add qualifier to the left of the type stem.
69*9e3b08aeSAndroid Build Coastguard Worker //
70*9e3b08aeSAndroid Build Coastguard Worker // This gives the more popular format (const int rather than int const)
71*9e3b08aeSAndroid Build Coastguard Worker // and is safe because NIL precedence types are always leaf syntax.
72*9e3b08aeSAndroid Build Coastguard Worker os << qualifier << ' ' << left_;
73*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str(), precedence_, right_};
74*9e3b08aeSAndroid Build Coastguard Worker }
75*9e3b08aeSAndroid Build Coastguard Worker case Precedence::POINTER: {
76*9e3b08aeSAndroid Build Coastguard Worker // Add qualifier to the right of the sigil.
77*9e3b08aeSAndroid Build Coastguard Worker //
78*9e3b08aeSAndroid Build Coastguard Worker // TODO: consider dropping ' ' here.
79*9e3b08aeSAndroid Build Coastguard Worker os << left_ << ' ' << qualifier;
80*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str(), precedence_, right_};
81*9e3b08aeSAndroid Build Coastguard Worker }
82*9e3b08aeSAndroid Build Coastguard Worker case Precedence::ARRAY_FUNCTION: {
83*9e3b08aeSAndroid Build Coastguard Worker // Qualifiers should not normally apply to arrays or functions.
84*9e3b08aeSAndroid Build Coastguard Worker os << '{' << qualifier << ">}" << right_;
85*9e3b08aeSAndroid Build Coastguard Worker return Name{left_, precedence_, os.str()};
86*9e3b08aeSAndroid Build Coastguard Worker }
87*9e3b08aeSAndroid Build Coastguard Worker case Precedence::ATOMIC: {
88*9e3b08aeSAndroid Build Coastguard Worker // Qualifiers should not normally apply to names.
89*9e3b08aeSAndroid Build Coastguard Worker os << left_ << "{<" << qualifier << '}';
90*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str(), precedence_, right_};
91*9e3b08aeSAndroid Build Coastguard Worker }
92*9e3b08aeSAndroid Build Coastguard Worker }
93*9e3b08aeSAndroid Build Coastguard Worker }
94*9e3b08aeSAndroid Build Coastguard Worker
Print(std::ostream & os) const95*9e3b08aeSAndroid Build Coastguard Worker std::ostream& Name::Print(std::ostream& os) const {
96*9e3b08aeSAndroid Build Coastguard Worker return os << left_ << right_;
97*9e3b08aeSAndroid Build Coastguard Worker }
98*9e3b08aeSAndroid Build Coastguard Worker
ToString() const99*9e3b08aeSAndroid Build Coastguard Worker std::string Name::ToString() const {
100*9e3b08aeSAndroid Build Coastguard Worker return left_ + right_;
101*9e3b08aeSAndroid Build Coastguard Worker }
102*9e3b08aeSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const Name & name)103*9e3b08aeSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Name& name) {
104*9e3b08aeSAndroid Build Coastguard Worker return name.Print(os);
105*9e3b08aeSAndroid Build Coastguard Worker }
106*9e3b08aeSAndroid Build Coastguard Worker
107*9e3b08aeSAndroid Build Coastguard Worker namespace {
108*9e3b08aeSAndroid Build Coastguard Worker
109*9e3b08aeSAndroid Build Coastguard Worker struct DescribeWorker {
DescribeWorkerstg::__anona1af26720111::DescribeWorker110*9e3b08aeSAndroid Build Coastguard Worker DescribeWorker(const Graph& graph, NameCache& names)
111*9e3b08aeSAndroid Build Coastguard Worker : graph(graph), names(names) {}
112*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker113*9e3b08aeSAndroid Build Coastguard Worker Name operator()(Id id) {
114*9e3b08aeSAndroid Build Coastguard Worker // infinite recursion prevention - insert at most once
115*9e3b08aeSAndroid Build Coastguard Worker static const Name black_hole{"#"};
116*9e3b08aeSAndroid Build Coastguard Worker auto insertion = names.insert({id, black_hole});
117*9e3b08aeSAndroid Build Coastguard Worker Name& cached = insertion.first->second;
118*9e3b08aeSAndroid Build Coastguard Worker if (insertion.second) {
119*9e3b08aeSAndroid Build Coastguard Worker cached = graph.Apply(*this, id);
120*9e3b08aeSAndroid Build Coastguard Worker }
121*9e3b08aeSAndroid Build Coastguard Worker return cached;
122*9e3b08aeSAndroid Build Coastguard Worker }
123*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker124*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Special& x) {
125*9e3b08aeSAndroid Build Coastguard Worker switch (x.kind) {
126*9e3b08aeSAndroid Build Coastguard Worker case Special::Kind::VOID:
127*9e3b08aeSAndroid Build Coastguard Worker return Name{"void"};
128*9e3b08aeSAndroid Build Coastguard Worker case Special::Kind::VARIADIC:
129*9e3b08aeSAndroid Build Coastguard Worker return Name{"..."};
130*9e3b08aeSAndroid Build Coastguard Worker case Special::Kind::NULLPTR:
131*9e3b08aeSAndroid Build Coastguard Worker return Name{"decltype(nullptr)"};
132*9e3b08aeSAndroid Build Coastguard Worker }
133*9e3b08aeSAndroid Build Coastguard Worker }
134*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker135*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const PointerReference& x) {
136*9e3b08aeSAndroid Build Coastguard Worker std::string sign;
137*9e3b08aeSAndroid Build Coastguard Worker switch (x.kind) {
138*9e3b08aeSAndroid Build Coastguard Worker case PointerReference::Kind::POINTER:
139*9e3b08aeSAndroid Build Coastguard Worker sign = "*";
140*9e3b08aeSAndroid Build Coastguard Worker break;
141*9e3b08aeSAndroid Build Coastguard Worker case PointerReference::Kind::LVALUE_REFERENCE:
142*9e3b08aeSAndroid Build Coastguard Worker sign = "&";
143*9e3b08aeSAndroid Build Coastguard Worker break;
144*9e3b08aeSAndroid Build Coastguard Worker case PointerReference::Kind::RVALUE_REFERENCE:
145*9e3b08aeSAndroid Build Coastguard Worker sign = "&&";
146*9e3b08aeSAndroid Build Coastguard Worker break;
147*9e3b08aeSAndroid Build Coastguard Worker }
148*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.pointee_type_id)
149*9e3b08aeSAndroid Build Coastguard Worker .Add(Side::LEFT, Precedence::POINTER, sign);
150*9e3b08aeSAndroid Build Coastguard Worker }
151*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker152*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const PointerToMember& x) {
153*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
154*9e3b08aeSAndroid Build Coastguard Worker os << (*this)(x.containing_type_id) << "::*";
155*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.pointee_type_id).Add(Side::LEFT, Precedence::POINTER,
156*9e3b08aeSAndroid Build Coastguard Worker os.str());
157*9e3b08aeSAndroid Build Coastguard Worker }
158*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker159*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Typedef& x) {
160*9e3b08aeSAndroid Build Coastguard Worker return Name{x.name};
161*9e3b08aeSAndroid Build Coastguard Worker }
162*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker163*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Qualified& x) {
164*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.qualified_type_id).Qualify(x.qualifier);
165*9e3b08aeSAndroid Build Coastguard Worker }
166*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker167*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Primitive& x) {
168*9e3b08aeSAndroid Build Coastguard Worker return Name{x.name};
169*9e3b08aeSAndroid Build Coastguard Worker }
170*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker171*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Array& x) {
172*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
173*9e3b08aeSAndroid Build Coastguard Worker os << '[' << x.number_of_elements << ']';
174*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.element_type_id)
175*9e3b08aeSAndroid Build Coastguard Worker .Add(Side::RIGHT, Precedence::ARRAY_FUNCTION, os.str());
176*9e3b08aeSAndroid Build Coastguard Worker }
177*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker178*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const BaseClass& x) {
179*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.type_id);
180*9e3b08aeSAndroid Build Coastguard Worker }
181*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker182*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Method& x) {
183*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.type_id).Add(Side::LEFT, Precedence::ATOMIC, x.name);
184*9e3b08aeSAndroid Build Coastguard Worker }
185*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker186*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Member& x) {
187*9e3b08aeSAndroid Build Coastguard Worker auto description = (*this)(x.type_id);
188*9e3b08aeSAndroid Build Coastguard Worker if (!x.name.empty()) {
189*9e3b08aeSAndroid Build Coastguard Worker description = description.Add(Side::LEFT, Precedence::ATOMIC, x.name);
190*9e3b08aeSAndroid Build Coastguard Worker }
191*9e3b08aeSAndroid Build Coastguard Worker if (x.bitsize) {
192*9e3b08aeSAndroid Build Coastguard Worker description = description.Add(
193*9e3b08aeSAndroid Build Coastguard Worker Side::RIGHT, Precedence::ATOMIC, ':' + std::to_string(x.bitsize));
194*9e3b08aeSAndroid Build Coastguard Worker }
195*9e3b08aeSAndroid Build Coastguard Worker return description;
196*9e3b08aeSAndroid Build Coastguard Worker }
197*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker198*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const VariantMember& x) {
199*9e3b08aeSAndroid Build Coastguard Worker auto description = (*this)(x.type_id);
200*9e3b08aeSAndroid Build Coastguard Worker description = description.Add(Side::LEFT, Precedence::ATOMIC, x.name);
201*9e3b08aeSAndroid Build Coastguard Worker return description;
202*9e3b08aeSAndroid Build Coastguard Worker }
203*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker204*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const StructUnion& x) {
205*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
206*9e3b08aeSAndroid Build Coastguard Worker os << x.kind;
207*9e3b08aeSAndroid Build Coastguard Worker if (!x.name.empty()) {
208*9e3b08aeSAndroid Build Coastguard Worker os << ' ' << x.name;
209*9e3b08aeSAndroid Build Coastguard Worker } else if (x.definition) {
210*9e3b08aeSAndroid Build Coastguard Worker os << " { ";
211*9e3b08aeSAndroid Build Coastguard Worker for (const auto& member : x.definition->members) {
212*9e3b08aeSAndroid Build Coastguard Worker os << (*this)(member) << "; ";
213*9e3b08aeSAndroid Build Coastguard Worker }
214*9e3b08aeSAndroid Build Coastguard Worker os << '}';
215*9e3b08aeSAndroid Build Coastguard Worker }
216*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str()};
217*9e3b08aeSAndroid Build Coastguard Worker }
218*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker219*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Enumeration& x) {
220*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
221*9e3b08aeSAndroid Build Coastguard Worker os << "enum";
222*9e3b08aeSAndroid Build Coastguard Worker if (!x.name.empty()) {
223*9e3b08aeSAndroid Build Coastguard Worker os << ' ' << x.name;
224*9e3b08aeSAndroid Build Coastguard Worker } else if (x.definition) {
225*9e3b08aeSAndroid Build Coastguard Worker os << " { ";
226*9e3b08aeSAndroid Build Coastguard Worker for (const auto& e : x.definition->enumerators) {
227*9e3b08aeSAndroid Build Coastguard Worker os << e.first << " = " << e.second << ", ";
228*9e3b08aeSAndroid Build Coastguard Worker }
229*9e3b08aeSAndroid Build Coastguard Worker os << '}';
230*9e3b08aeSAndroid Build Coastguard Worker }
231*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str()};
232*9e3b08aeSAndroid Build Coastguard Worker }
233*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker234*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Variant& x) {
235*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
236*9e3b08aeSAndroid Build Coastguard Worker os << "variant " << x.name;
237*9e3b08aeSAndroid Build Coastguard Worker return Name{os.str()};
238*9e3b08aeSAndroid Build Coastguard Worker }
239*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker240*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Function& x) {
241*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
242*9e3b08aeSAndroid Build Coastguard Worker os << '(';
243*9e3b08aeSAndroid Build Coastguard Worker bool sep = false;
244*9e3b08aeSAndroid Build Coastguard Worker for (const Id p : x.parameters) {
245*9e3b08aeSAndroid Build Coastguard Worker if (sep) {
246*9e3b08aeSAndroid Build Coastguard Worker os << ", ";
247*9e3b08aeSAndroid Build Coastguard Worker } else {
248*9e3b08aeSAndroid Build Coastguard Worker sep = true;
249*9e3b08aeSAndroid Build Coastguard Worker }
250*9e3b08aeSAndroid Build Coastguard Worker os << (*this)(p);
251*9e3b08aeSAndroid Build Coastguard Worker }
252*9e3b08aeSAndroid Build Coastguard Worker os << ')';
253*9e3b08aeSAndroid Build Coastguard Worker return (*this)(x.return_type_id)
254*9e3b08aeSAndroid Build Coastguard Worker .Add(Side::RIGHT, Precedence::ARRAY_FUNCTION, os.str());
255*9e3b08aeSAndroid Build Coastguard Worker }
256*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker257*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const ElfSymbol& x) {
258*9e3b08aeSAndroid Build Coastguard Worker const auto& name = x.full_name ? *x.full_name : x.symbol_name;
259*9e3b08aeSAndroid Build Coastguard Worker return x.type_id
260*9e3b08aeSAndroid Build Coastguard Worker ? (*this)(*x.type_id).Add(Side::LEFT, Precedence::ATOMIC, name)
261*9e3b08aeSAndroid Build Coastguard Worker : Name{name};
262*9e3b08aeSAndroid Build Coastguard Worker }
263*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeWorker264*9e3b08aeSAndroid Build Coastguard Worker Name operator()(const Interface&) {
265*9e3b08aeSAndroid Build Coastguard Worker return Name{"interface"};
266*9e3b08aeSAndroid Build Coastguard Worker }
267*9e3b08aeSAndroid Build Coastguard Worker
268*9e3b08aeSAndroid Build Coastguard Worker const Graph& graph;
269*9e3b08aeSAndroid Build Coastguard Worker NameCache& names;
270*9e3b08aeSAndroid Build Coastguard Worker };
271*9e3b08aeSAndroid Build Coastguard Worker
272*9e3b08aeSAndroid Build Coastguard Worker struct DescribeKindWorker {
DescribeKindWorkerstg::__anona1af26720111::DescribeKindWorker273*9e3b08aeSAndroid Build Coastguard Worker explicit DescribeKindWorker(const Graph& graph) : graph(graph) {}
274*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker275*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(Id id) {
276*9e3b08aeSAndroid Build Coastguard Worker return graph.Apply(*this, id);
277*9e3b08aeSAndroid Build Coastguard Worker }
278*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker279*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const BaseClass&) {
280*9e3b08aeSAndroid Build Coastguard Worker return "base class";
281*9e3b08aeSAndroid Build Coastguard Worker }
282*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker283*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const Method&) {
284*9e3b08aeSAndroid Build Coastguard Worker return "method";
285*9e3b08aeSAndroid Build Coastguard Worker }
286*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker287*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const Member&) {
288*9e3b08aeSAndroid Build Coastguard Worker return "member";
289*9e3b08aeSAndroid Build Coastguard Worker }
290*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker291*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const ElfSymbol& x) {
292*9e3b08aeSAndroid Build Coastguard Worker std::ostringstream os;
293*9e3b08aeSAndroid Build Coastguard Worker os << x.symbol_type << " symbol";
294*9e3b08aeSAndroid Build Coastguard Worker return os.str();
295*9e3b08aeSAndroid Build Coastguard Worker }
296*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeKindWorker297*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const Interface&) {
298*9e3b08aeSAndroid Build Coastguard Worker return "interface";
299*9e3b08aeSAndroid Build Coastguard Worker }
300*9e3b08aeSAndroid Build Coastguard Worker
301*9e3b08aeSAndroid Build Coastguard Worker template <typename Node>
operator ()stg::__anona1af26720111::DescribeKindWorker302*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const Node&) {
303*9e3b08aeSAndroid Build Coastguard Worker return "type";
304*9e3b08aeSAndroid Build Coastguard Worker }
305*9e3b08aeSAndroid Build Coastguard Worker
306*9e3b08aeSAndroid Build Coastguard Worker const Graph& graph;
307*9e3b08aeSAndroid Build Coastguard Worker };
308*9e3b08aeSAndroid Build Coastguard Worker
309*9e3b08aeSAndroid Build Coastguard Worker struct DescribeExtraWorker {
DescribeExtraWorkerstg::__anona1af26720111::DescribeExtraWorker310*9e3b08aeSAndroid Build Coastguard Worker explicit DescribeExtraWorker(const Graph& graph) : graph(graph) {}
311*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeExtraWorker312*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(Id id) {
313*9e3b08aeSAndroid Build Coastguard Worker return graph.Apply(*this, id);
314*9e3b08aeSAndroid Build Coastguard Worker }
315*9e3b08aeSAndroid Build Coastguard Worker
operator ()stg::__anona1af26720111::DescribeExtraWorker316*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const ElfSymbol& x) {
317*9e3b08aeSAndroid Build Coastguard Worker const auto& name = x.full_name ? *x.full_name : x.symbol_name;
318*9e3b08aeSAndroid Build Coastguard Worker auto versioned = VersionedSymbolName(x);
319*9e3b08aeSAndroid Build Coastguard Worker return name == versioned ? std::string() : " {" + versioned + '}';
320*9e3b08aeSAndroid Build Coastguard Worker }
321*9e3b08aeSAndroid Build Coastguard Worker
322*9e3b08aeSAndroid Build Coastguard Worker template <typename Node>
operator ()stg::__anona1af26720111::DescribeExtraWorker323*9e3b08aeSAndroid Build Coastguard Worker std::string operator()(const Node&) {
324*9e3b08aeSAndroid Build Coastguard Worker return {};
325*9e3b08aeSAndroid Build Coastguard Worker }
326*9e3b08aeSAndroid Build Coastguard Worker
327*9e3b08aeSAndroid Build Coastguard Worker const Graph& graph;
328*9e3b08aeSAndroid Build Coastguard Worker };
329*9e3b08aeSAndroid Build Coastguard Worker
330*9e3b08aeSAndroid Build Coastguard Worker } // namespace
331*9e3b08aeSAndroid Build Coastguard Worker
operator ()(Id id)332*9e3b08aeSAndroid Build Coastguard Worker Name Describe::operator()(Id id) {
333*9e3b08aeSAndroid Build Coastguard Worker return DescribeWorker(graph, names)(id);
334*9e3b08aeSAndroid Build Coastguard Worker }
335*9e3b08aeSAndroid Build Coastguard Worker
operator ()(Id id)336*9e3b08aeSAndroid Build Coastguard Worker std::string DescribeKind::operator()(Id id) {
337*9e3b08aeSAndroid Build Coastguard Worker return DescribeKindWorker(graph)(id);
338*9e3b08aeSAndroid Build Coastguard Worker }
339*9e3b08aeSAndroid Build Coastguard Worker
operator ()(Id id)340*9e3b08aeSAndroid Build Coastguard Worker std::string DescribeExtra::operator()(Id id) {
341*9e3b08aeSAndroid Build Coastguard Worker return DescribeExtraWorker(graph)(id);
342*9e3b08aeSAndroid Build Coastguard Worker }
343*9e3b08aeSAndroid Build Coastguard Worker
344*9e3b08aeSAndroid Build Coastguard Worker } // namespace stg
345