1fe013be4SDimitry Andric //===-- SymbolFileCTF.cpp ----------------------------------------------===//
2fe013be4SDimitry Andric //
3fe013be4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe013be4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe013be4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe013be4SDimitry Andric //
7fe013be4SDimitry Andric //===----------------------------------------------------------------------===//
8fe013be4SDimitry Andric 
9fe013be4SDimitry Andric #include "SymbolFileCTF.h"
10fe013be4SDimitry Andric 
11fe013be4SDimitry Andric #include "lldb/Core/Module.h"
12fe013be4SDimitry Andric #include "lldb/Core/PluginManager.h"
13fe013be4SDimitry Andric #include "lldb/Host/Config.h"
14fe013be4SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
15fe013be4SDimitry Andric #include "lldb/Symbol/Function.h"
16fe013be4SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
17fe013be4SDimitry Andric #include "lldb/Symbol/Symbol.h"
18fe013be4SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
19fe013be4SDimitry Andric #include "lldb/Symbol/Symtab.h"
20fe013be4SDimitry Andric #include "lldb/Symbol/TypeList.h"
21fe013be4SDimitry Andric #include "lldb/Symbol/TypeMap.h"
22fe013be4SDimitry Andric #include "lldb/Symbol/Variable.h"
23fe013be4SDimitry Andric #include "lldb/Symbol/VariableList.h"
24fe013be4SDimitry Andric #include "lldb/Utility/DataExtractor.h"
25fe013be4SDimitry Andric #include "lldb/Utility/LLDBLog.h"
26fe013be4SDimitry Andric #include "lldb/Utility/Log.h"
27fe013be4SDimitry Andric #include "lldb/Utility/RegularExpression.h"
28*c9157d92SDimitry Andric #include "lldb/Utility/StreamBuffer.h"
29fe013be4SDimitry Andric #include "lldb/Utility/StreamString.h"
30fe013be4SDimitry Andric #include "lldb/Utility/Timer.h"
31fe013be4SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
32fe013be4SDimitry Andric 
33fe013be4SDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
34fe013be4SDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
35fe013be4SDimitry Andric 
36fe013be4SDimitry Andric #include <memory>
37fe013be4SDimitry Andric #include <optional>
38fe013be4SDimitry Andric 
39fe013be4SDimitry Andric #if LLVM_ENABLE_ZLIB
40fe013be4SDimitry Andric #include <zlib.h>
41fe013be4SDimitry Andric #endif
42fe013be4SDimitry Andric 
43fe013be4SDimitry Andric using namespace llvm;
44fe013be4SDimitry Andric using namespace lldb;
45fe013be4SDimitry Andric using namespace lldb_private;
46fe013be4SDimitry Andric 
47fe013be4SDimitry Andric LLDB_PLUGIN_DEFINE(SymbolFileCTF)
48fe013be4SDimitry Andric 
49fe013be4SDimitry Andric char SymbolFileCTF::ID;
50fe013be4SDimitry Andric 
51fe013be4SDimitry Andric SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
52fe013be4SDimitry Andric     : SymbolFileCommon(std::move(objfile_sp)) {}
53fe013be4SDimitry Andric 
54fe013be4SDimitry Andric void SymbolFileCTF::Initialize() {
55fe013be4SDimitry Andric   PluginManager::RegisterPlugin(GetPluginNameStatic(),
56fe013be4SDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance);
57fe013be4SDimitry Andric }
58fe013be4SDimitry Andric 
59fe013be4SDimitry Andric void SymbolFileCTF::Terminate() {
60fe013be4SDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
61fe013be4SDimitry Andric }
62fe013be4SDimitry Andric 
63fe013be4SDimitry Andric llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() {
64fe013be4SDimitry Andric   return "Compact C Type Format Symbol Reader";
65fe013be4SDimitry Andric }
66fe013be4SDimitry Andric 
67fe013be4SDimitry Andric SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) {
68fe013be4SDimitry Andric   return new SymbolFileCTF(std::move(objfile_sp));
69fe013be4SDimitry Andric }
70fe013be4SDimitry Andric 
71fe013be4SDimitry Andric bool SymbolFileCTF::ParseHeader() {
72fe013be4SDimitry Andric   if (m_header)
73fe013be4SDimitry Andric     return true;
74fe013be4SDimitry Andric 
75fe013be4SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
76fe013be4SDimitry Andric 
77fe013be4SDimitry Andric   ModuleSP module_sp(m_objfile_sp->GetModule());
78fe013be4SDimitry Andric   const SectionList *section_list = module_sp->GetSectionList();
79fe013be4SDimitry Andric   if (!section_list)
80fe013be4SDimitry Andric     return false;
81fe013be4SDimitry Andric 
82fe013be4SDimitry Andric   SectionSP section_sp(
83fe013be4SDimitry Andric       section_list->FindSectionByType(lldb::eSectionTypeCTF, true));
84fe013be4SDimitry Andric   if (!section_sp)
85fe013be4SDimitry Andric     return false;
86fe013be4SDimitry Andric 
87fe013be4SDimitry Andric   m_objfile_sp->ReadSectionData(section_sp.get(), m_data);
88fe013be4SDimitry Andric 
89fe013be4SDimitry Andric   if (m_data.GetByteSize() == 0)
90fe013be4SDimitry Andric     return false;
91fe013be4SDimitry Andric 
92fe013be4SDimitry Andric   StreamString module_desc;
93fe013be4SDimitry Andric   GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
94fe013be4SDimitry Andric                                                lldb::eDescriptionLevelBrief);
95fe013be4SDimitry Andric   LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData());
96fe013be4SDimitry Andric 
97fe013be4SDimitry Andric   lldb::offset_t offset = 0;
98fe013be4SDimitry Andric 
99fe013be4SDimitry Andric   // Parse CTF header.
100fe013be4SDimitry Andric   constexpr size_t ctf_header_size = sizeof(ctf_header_t);
101fe013be4SDimitry Andric   if (!m_data.ValidOffsetForDataOfSize(offset, ctf_header_size)) {
102fe013be4SDimitry Andric     LLDB_LOG(log, "CTF parsing failed: insufficient data for CTF header");
103fe013be4SDimitry Andric     return false;
104fe013be4SDimitry Andric   }
105fe013be4SDimitry Andric 
106fe013be4SDimitry Andric   m_header.emplace();
107fe013be4SDimitry Andric 
108fe013be4SDimitry Andric   ctf_header_t &ctf_header = *m_header;
109fe013be4SDimitry Andric   ctf_header.preamble.magic = m_data.GetU16(&offset);
110fe013be4SDimitry Andric   ctf_header.preamble.version = m_data.GetU8(&offset);
111fe013be4SDimitry Andric   ctf_header.preamble.flags = m_data.GetU8(&offset);
112fe013be4SDimitry Andric   ctf_header.parlabel = m_data.GetU32(&offset);
113fe013be4SDimitry Andric   ctf_header.parname = m_data.GetU32(&offset);
114fe013be4SDimitry Andric   ctf_header.lbloff = m_data.GetU32(&offset);
115fe013be4SDimitry Andric   ctf_header.objtoff = m_data.GetU32(&offset);
116fe013be4SDimitry Andric   ctf_header.funcoff = m_data.GetU32(&offset);
117fe013be4SDimitry Andric   ctf_header.typeoff = m_data.GetU32(&offset);
118fe013be4SDimitry Andric   ctf_header.stroff = m_data.GetU32(&offset);
119fe013be4SDimitry Andric   ctf_header.strlen = m_data.GetU32(&offset);
120fe013be4SDimitry Andric 
121fe013be4SDimitry Andric   // Validate the preamble.
122fe013be4SDimitry Andric   if (ctf_header.preamble.magic != g_ctf_magic) {
123fe013be4SDimitry Andric     LLDB_LOG(log, "CTF parsing failed: invalid magic: {0:x}",
124fe013be4SDimitry Andric              ctf_header.preamble.magic);
125fe013be4SDimitry Andric     return false;
126fe013be4SDimitry Andric   }
127fe013be4SDimitry Andric 
128fe013be4SDimitry Andric   if (ctf_header.preamble.version != g_ctf_version) {
129fe013be4SDimitry Andric     LLDB_LOG(log, "CTF parsing failed: unsupported version: {0}",
130fe013be4SDimitry Andric              ctf_header.preamble.version);
131fe013be4SDimitry Andric     return false;
132fe013be4SDimitry Andric   }
133fe013be4SDimitry Andric 
134fe013be4SDimitry Andric   LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
135fe013be4SDimitry Andric            ctf_header.preamble.version, ctf_header.preamble.flags);
136fe013be4SDimitry Andric 
137fe013be4SDimitry Andric   m_body_offset = offset;
138fe013be4SDimitry Andric 
139fe013be4SDimitry Andric   if (ctf_header.preamble.flags & eFlagCompress) {
140fe013be4SDimitry Andric     // The body has been compressed with zlib deflate. Header offsets point into
141fe013be4SDimitry Andric     // the decompressed data.
142fe013be4SDimitry Andric #if LLVM_ENABLE_ZLIB
143fe013be4SDimitry Andric     const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen;
144fe013be4SDimitry Andric     DataBufferSP decompressed_data =
145fe013be4SDimitry Andric         std::make_shared<DataBufferHeap>(decompressed_size, 0x0);
146fe013be4SDimitry Andric 
147fe013be4SDimitry Andric     z_stream zstr;
148fe013be4SDimitry Andric     memset(&zstr, 0, sizeof(zstr));
149fe013be4SDimitry Andric     zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() +
150fe013be4SDimitry Andric                                                   sizeof(ctf_header_t));
151fe013be4SDimitry Andric     zstr.avail_in = m_data.BytesLeft(offset);
152fe013be4SDimitry Andric     zstr.next_out =
153fe013be4SDimitry Andric         (Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes());
154fe013be4SDimitry Andric     zstr.avail_out = decompressed_size;
155fe013be4SDimitry Andric 
156fe013be4SDimitry Andric     int rc = inflateInit(&zstr);
157fe013be4SDimitry Andric     if (rc != Z_OK) {
158fe013be4SDimitry Andric       LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}",
159fe013be4SDimitry Andric                zError(rc));
160fe013be4SDimitry Andric       return false;
161fe013be4SDimitry Andric     }
162fe013be4SDimitry Andric 
163fe013be4SDimitry Andric     rc = inflate(&zstr, Z_FINISH);
164fe013be4SDimitry Andric     if (rc != Z_STREAM_END) {
165fe013be4SDimitry Andric       LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc));
166fe013be4SDimitry Andric       return false;
167fe013be4SDimitry Andric     }
168fe013be4SDimitry Andric 
169fe013be4SDimitry Andric     rc = inflateEnd(&zstr);
170fe013be4SDimitry Andric     if (rc != Z_OK) {
171fe013be4SDimitry Andric       LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc));
172fe013be4SDimitry Andric       return false;
173fe013be4SDimitry Andric     }
174fe013be4SDimitry Andric 
175fe013be4SDimitry Andric     if (zstr.total_out != decompressed_size) {
176fe013be4SDimitry Andric       LLDB_LOG(log,
177fe013be4SDimitry Andric                "CTF parsing failed: decompressed size ({0}) doesn't match "
178fe013be4SDimitry Andric                "expected size ([1})",
179fe013be4SDimitry Andric                zstr.total_out, decompressed_size);
180fe013be4SDimitry Andric       return false;
181fe013be4SDimitry Andric     }
182fe013be4SDimitry Andric 
183fe013be4SDimitry Andric     m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
184fe013be4SDimitry Andric                            m_data.GetAddressByteSize());
185fe013be4SDimitry Andric     m_body_offset = 0;
186fe013be4SDimitry Andric #else
187fe013be4SDimitry Andric     LLDB_LOG(
188fe013be4SDimitry Andric         log,
189fe013be4SDimitry Andric         "CTF parsing failed: data is compressed but no zlib inflate support");
190fe013be4SDimitry Andric     return false;
191fe013be4SDimitry Andric #endif
192fe013be4SDimitry Andric   }
193fe013be4SDimitry Andric 
194fe013be4SDimitry Andric   // Validate the header.
195fe013be4SDimitry Andric   if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) {
196fe013be4SDimitry Andric     LLDB_LOG(log,
197fe013be4SDimitry Andric              "CTF parsing failed: invalid label section offset in header: {0}",
198fe013be4SDimitry Andric              ctf_header.lbloff);
199fe013be4SDimitry Andric     return false;
200fe013be4SDimitry Andric   }
201fe013be4SDimitry Andric 
202fe013be4SDimitry Andric   if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) {
203fe013be4SDimitry Andric     LLDB_LOG(log,
204fe013be4SDimitry Andric              "CTF parsing failed: invalid object section offset in header: {0}",
205fe013be4SDimitry Andric              ctf_header.objtoff);
206fe013be4SDimitry Andric     return false;
207fe013be4SDimitry Andric   }
208fe013be4SDimitry Andric 
209fe013be4SDimitry Andric   if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) {
210fe013be4SDimitry Andric     LLDB_LOG(
211fe013be4SDimitry Andric         log,
212fe013be4SDimitry Andric         "CTF parsing failed: invalid function section offset in header: {0}",
213fe013be4SDimitry Andric         ctf_header.funcoff);
214fe013be4SDimitry Andric     return false;
215fe013be4SDimitry Andric   }
216fe013be4SDimitry Andric 
217fe013be4SDimitry Andric   if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) {
218fe013be4SDimitry Andric     LLDB_LOG(log,
219fe013be4SDimitry Andric              "CTF parsing failed: invalid type section offset in header: {0}",
220fe013be4SDimitry Andric              ctf_header.typeoff);
221fe013be4SDimitry Andric     return false;
222fe013be4SDimitry Andric   }
223fe013be4SDimitry Andric 
224fe013be4SDimitry Andric   if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) {
225fe013be4SDimitry Andric     LLDB_LOG(log,
226fe013be4SDimitry Andric              "CTF parsing failed: invalid string section offset in header: {0}",
227fe013be4SDimitry Andric              ctf_header.stroff);
228fe013be4SDimitry Andric     return false;
229fe013be4SDimitry Andric   }
230fe013be4SDimitry Andric 
231fe013be4SDimitry Andric   const lldb::offset_t str_end_offset =
232fe013be4SDimitry Andric       m_body_offset + ctf_header.stroff + ctf_header.strlen;
233fe013be4SDimitry Andric   if (!m_data.ValidOffset(str_end_offset - 1)) {
234fe013be4SDimitry Andric     LLDB_LOG(log,
235fe013be4SDimitry Andric              "CTF parsing failed: invalid string section length in header: {0}",
236fe013be4SDimitry Andric              ctf_header.strlen);
237fe013be4SDimitry Andric     return false;
238fe013be4SDimitry Andric   }
239fe013be4SDimitry Andric 
240fe013be4SDimitry Andric   if (m_body_offset + ctf_header.stroff + ctf_header.parlabel >
241fe013be4SDimitry Andric       str_end_offset) {
242fe013be4SDimitry Andric     LLDB_LOG(log,
243fe013be4SDimitry Andric              "CTF parsing failed: invalid parent label offset: {0} exceeds end "
244fe013be4SDimitry Andric              "of string section ({1})",
245fe013be4SDimitry Andric              ctf_header.parlabel, str_end_offset);
246fe013be4SDimitry Andric     return false;
247fe013be4SDimitry Andric   }
248fe013be4SDimitry Andric 
249fe013be4SDimitry Andric   if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
250fe013be4SDimitry Andric     LLDB_LOG(log,
251fe013be4SDimitry Andric              "CTF parsing failed: invalid parent name offset: {0} exceeds end "
252fe013be4SDimitry Andric              "of string section ({1})",
253fe013be4SDimitry Andric              ctf_header.parname, str_end_offset);
254fe013be4SDimitry Andric     return false;
255fe013be4SDimitry Andric   }
256fe013be4SDimitry Andric 
257fe013be4SDimitry Andric   LLDB_LOG(log,
258fe013be4SDimitry Andric            "Parsed valid CTF header: lbloff  = {0}, objtoff = {1}, funcoff = "
259fe013be4SDimitry Andric            "{2}, typeoff = {3}, stroff = {4}, strlen = {5}",
260fe013be4SDimitry Andric            ctf_header.lbloff, ctf_header.objtoff, ctf_header.funcoff,
261fe013be4SDimitry Andric            ctf_header.typeoff, ctf_header.stroff, ctf_header.strlen);
262fe013be4SDimitry Andric 
263fe013be4SDimitry Andric   return true;
264fe013be4SDimitry Andric }
265fe013be4SDimitry Andric 
266fe013be4SDimitry Andric void SymbolFileCTF::InitializeObject() {
267fe013be4SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
268fe013be4SDimitry Andric 
269fe013be4SDimitry Andric   auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC);
270fe013be4SDimitry Andric   if (auto err = type_system_or_err.takeError()) {
271fe013be4SDimitry Andric     LLDB_LOG_ERROR(log, std::move(err), "Unable to get type system: {0}");
272fe013be4SDimitry Andric     return;
273fe013be4SDimitry Andric   }
274fe013be4SDimitry Andric 
275fe013be4SDimitry Andric   auto ts = *type_system_or_err;
276fe013be4SDimitry Andric   m_ast = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
277fe013be4SDimitry Andric   LazyBool optimized = eLazyBoolNo;
278fe013be4SDimitry Andric   m_comp_unit_sp = std::make_shared<CompileUnit>(
279fe013be4SDimitry Andric       m_objfile_sp->GetModule(), nullptr, "", 0, eLanguageTypeC, optimized);
280fe013be4SDimitry Andric 
281fe013be4SDimitry Andric   ParseTypes(*m_comp_unit_sp);
282fe013be4SDimitry Andric }
283fe013be4SDimitry Andric 
284fe013be4SDimitry Andric llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
285fe013be4SDimitry Andric   lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
286fe013be4SDimitry Andric   if (!m_data.ValidOffset(offset))
287fe013be4SDimitry Andric     return "(invalid)";
288fe013be4SDimitry Andric   const char *str = m_data.GetCStr(&offset);
289fe013be4SDimitry Andric   if (str && !*str)
290fe013be4SDimitry Andric     return "(anon)";
291fe013be4SDimitry Andric   return llvm::StringRef(str);
292fe013be4SDimitry Andric }
293fe013be4SDimitry Andric 
294fe013be4SDimitry Andric /// Return the integer display representation encoded in the given data.
295fe013be4SDimitry Andric static uint32_t GetEncoding(uint32_t data) {
296fe013be4SDimitry Andric   // Mask bits 24–31.
297fe013be4SDimitry Andric   return ((data)&0xff000000) >> 24;
298fe013be4SDimitry Andric }
299fe013be4SDimitry Andric 
300fe013be4SDimitry Andric /// Return the integral width in bits encoded in the given data.
301fe013be4SDimitry Andric static uint32_t GetBits(uint32_t data) {
302fe013be4SDimitry Andric   // Mask bits 0-15.
303fe013be4SDimitry Andric   return (data)&0x0000ffff;
304fe013be4SDimitry Andric }
305fe013be4SDimitry Andric 
306fe013be4SDimitry Andric /// Return the type kind encoded in the given data.
307fe013be4SDimitry Andric uint32_t GetKind(uint32_t data) {
308fe013be4SDimitry Andric   // Mask bits 26–31.
309fe013be4SDimitry Andric   return ((data)&0xf800) >> 11;
310fe013be4SDimitry Andric }
311fe013be4SDimitry Andric 
312fe013be4SDimitry Andric /// Return the variable length encoded in the given data.
313fe013be4SDimitry Andric uint32_t GetVLen(uint32_t data) {
314fe013be4SDimitry Andric   // Mask bits 0–24.
315fe013be4SDimitry Andric   return (data)&0x3ff;
316fe013be4SDimitry Andric }
317fe013be4SDimitry Andric 
318fe013be4SDimitry Andric static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
319fe013be4SDimitry Andric 
320*c9157d92SDimitry Andric static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
321fe013be4SDimitry Andric   switch (type) {
322*c9157d92SDimitry Andric   case CTFType::Kind::eStruct:
323*c9157d92SDimitry Andric     return clang::TagTypeKind::Struct;
324*c9157d92SDimitry Andric   case CTFType::Kind::eUnion:
325*c9157d92SDimitry Andric     return clang::TagTypeKind::Union;
326fe013be4SDimitry Andric   default:
327fe013be4SDimitry Andric     lldbassert(false && "Invalid record kind!");
328*c9157d92SDimitry Andric     return clang::TagTypeKind::Struct;
329fe013be4SDimitry Andric   }
330fe013be4SDimitry Andric }
331fe013be4SDimitry Andric 
332*c9157d92SDimitry Andric llvm::Expected<TypeSP>
333*c9157d92SDimitry Andric SymbolFileCTF::CreateInteger(const CTFInteger &ctf_integer) {
334*c9157d92SDimitry Andric   lldb::BasicType basic_type =
335*c9157d92SDimitry Andric       TypeSystemClang::GetBasicTypeEnumeration(ctf_integer.name);
336fe013be4SDimitry Andric   if (basic_type == eBasicTypeInvalid)
337fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
338fe013be4SDimitry Andric         llvm::formatv("unsupported integer type: no corresponding basic clang "
339fe013be4SDimitry Andric                       "type for '{0}'",
340*c9157d92SDimitry Andric                       ctf_integer.name),
341fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
342fe013be4SDimitry Andric 
343fe013be4SDimitry Andric   CompilerType compiler_type = m_ast->GetBasicType(basic_type);
344fe013be4SDimitry Andric 
345fe013be4SDimitry Andric   if (basic_type != eBasicTypeVoid) {
346fe013be4SDimitry Andric     // Make sure the type we got is an integer type.
347fe013be4SDimitry Andric     bool compiler_type_is_signed = false;
348fe013be4SDimitry Andric     if (!compiler_type.IsIntegerType(compiler_type_is_signed))
349fe013be4SDimitry Andric       return llvm::make_error<llvm::StringError>(
350fe013be4SDimitry Andric           llvm::formatv(
351fe013be4SDimitry Andric               "Found compiler type for '{0}' but it's not an integer type: {1}",
352*c9157d92SDimitry Andric               ctf_integer.name,
353*c9157d92SDimitry Andric               compiler_type.GetDisplayTypeName().GetStringRef()),
354fe013be4SDimitry Andric           llvm::inconvertibleErrorCode());
355fe013be4SDimitry Andric 
356fe013be4SDimitry Andric     // Make sure the signing matches between the CTF and the compiler type.
357*c9157d92SDimitry Andric     const bool type_is_signed = (ctf_integer.encoding & IntEncoding::eSigned);
358fe013be4SDimitry Andric     if (compiler_type_is_signed != type_is_signed)
359fe013be4SDimitry Andric       return llvm::make_error<llvm::StringError>(
360fe013be4SDimitry Andric           llvm::formatv("Found integer compiler type for {0} but compiler type "
361fe013be4SDimitry Andric                         "is {1} and {0} is {2}",
362*c9157d92SDimitry Andric                         ctf_integer.name,
363*c9157d92SDimitry Andric                         compiler_type_is_signed ? "signed" : "unsigned",
364fe013be4SDimitry Andric                         type_is_signed ? "signed" : "unsigned"),
365fe013be4SDimitry Andric           llvm::inconvertibleErrorCode());
366fe013be4SDimitry Andric   }
367fe013be4SDimitry Andric 
368fe013be4SDimitry Andric   Declaration decl;
369*c9157d92SDimitry Andric   return MakeType(ctf_integer.uid, ConstString(ctf_integer.name),
370*c9157d92SDimitry Andric                   GetBytes(ctf_integer.bits), nullptr, LLDB_INVALID_UID,
371*c9157d92SDimitry Andric                   lldb_private::Type::eEncodingIsUID, decl, compiler_type,
372*c9157d92SDimitry Andric                   lldb_private::Type::ResolveState::Full);
373fe013be4SDimitry Andric }
374fe013be4SDimitry Andric 
375fe013be4SDimitry Andric llvm::Expected<lldb::TypeSP>
376*c9157d92SDimitry Andric SymbolFileCTF::CreateModifier(const CTFModifier &ctf_modifier) {
377*c9157d92SDimitry Andric   Type *ref_type = ResolveTypeUID(ctf_modifier.type);
378fe013be4SDimitry Andric   if (!ref_type)
379fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
380*c9157d92SDimitry Andric         llvm::formatv("Could not find modified type: {0}", ctf_modifier.type),
381fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
382fe013be4SDimitry Andric 
383fe013be4SDimitry Andric   CompilerType compiler_type;
384fe013be4SDimitry Andric 
385*c9157d92SDimitry Andric   switch (ctf_modifier.kind) {
386*c9157d92SDimitry Andric   case CTFType::ePointer:
387fe013be4SDimitry Andric     compiler_type = ref_type->GetFullCompilerType().GetPointerType();
388fe013be4SDimitry Andric     break;
389*c9157d92SDimitry Andric   case CTFType::eConst:
390fe013be4SDimitry Andric     compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
391fe013be4SDimitry Andric     break;
392*c9157d92SDimitry Andric   case CTFType::eVolatile:
393fe013be4SDimitry Andric     compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
394fe013be4SDimitry Andric     break;
395*c9157d92SDimitry Andric   case CTFType::eRestrict:
396fe013be4SDimitry Andric     compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
397fe013be4SDimitry Andric     break;
398fe013be4SDimitry Andric   default:
399fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
400*c9157d92SDimitry Andric         llvm::formatv("ParseModifier called with unsupported kind: {0}",
401*c9157d92SDimitry Andric                       ctf_modifier.kind),
402fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
403fe013be4SDimitry Andric   }
404fe013be4SDimitry Andric 
405fe013be4SDimitry Andric   Declaration decl;
406*c9157d92SDimitry Andric   return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
407fe013be4SDimitry Andric                   Type::eEncodingIsUID, decl, compiler_type,
408fe013be4SDimitry Andric                   lldb_private::Type::ResolveState::Full);
409fe013be4SDimitry Andric }
410fe013be4SDimitry Andric 
411*c9157d92SDimitry Andric llvm::Expected<lldb::TypeSP>
412*c9157d92SDimitry Andric SymbolFileCTF::CreateTypedef(const CTFTypedef &ctf_typedef) {
413*c9157d92SDimitry Andric   Type *underlying_type = ResolveTypeUID(ctf_typedef.type);
414fe013be4SDimitry Andric   if (!underlying_type)
415fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
416*c9157d92SDimitry Andric         llvm::formatv("Could not find typedef underlying type: {0}",
417*c9157d92SDimitry Andric                       ctf_typedef.type),
418fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
419fe013be4SDimitry Andric 
420fe013be4SDimitry Andric   CompilerType target_ast_type = underlying_type->GetFullCompilerType();
421fe013be4SDimitry Andric   clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
422fe013be4SDimitry Andric   CompilerType ast_typedef = target_ast_type.CreateTypedef(
423*c9157d92SDimitry Andric       ctf_typedef.name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
424fe013be4SDimitry Andric 
425fe013be4SDimitry Andric   Declaration decl;
426*c9157d92SDimitry Andric   return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
427*c9157d92SDimitry Andric                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
428*c9157d92SDimitry Andric                   ast_typedef, lldb_private::Type::ResolveState::Full);
429fe013be4SDimitry Andric }
430fe013be4SDimitry Andric 
431*c9157d92SDimitry Andric llvm::Expected<lldb::TypeSP>
432*c9157d92SDimitry Andric SymbolFileCTF::CreateArray(const CTFArray &ctf_array) {
433*c9157d92SDimitry Andric   Type *element_type = ResolveTypeUID(ctf_array.type);
434fe013be4SDimitry Andric   if (!element_type)
435fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
436*c9157d92SDimitry Andric         llvm::formatv("Could not find array element type: {0}", ctf_array.type),
437fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
438fe013be4SDimitry Andric 
439fe013be4SDimitry Andric   std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr);
440fe013be4SDimitry Andric   if (!element_size)
441fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
442fe013be4SDimitry Andric         llvm::formatv("could not get element size of type: {0}",
443*c9157d92SDimitry Andric                       ctf_array.type),
444fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
445fe013be4SDimitry Andric 
446fe013be4SDimitry Andric   uint64_t size = ctf_array.nelems * *element_size;
447fe013be4SDimitry Andric 
448fe013be4SDimitry Andric   CompilerType compiler_type = m_ast->CreateArrayType(
449fe013be4SDimitry Andric       element_type->GetFullCompilerType(), ctf_array.nelems,
450fe013be4SDimitry Andric       /*is_gnu_vector*/ false);
451fe013be4SDimitry Andric 
452fe013be4SDimitry Andric   Declaration decl;
453*c9157d92SDimitry Andric   return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
454fe013be4SDimitry Andric                   Type::eEncodingIsUID, decl, compiler_type,
455fe013be4SDimitry Andric                   lldb_private::Type::ResolveState::Full);
456fe013be4SDimitry Andric }
457fe013be4SDimitry Andric 
458*c9157d92SDimitry Andric llvm::Expected<lldb::TypeSP>
459*c9157d92SDimitry Andric SymbolFileCTF::CreateEnum(const CTFEnum &ctf_enum) {
460fe013be4SDimitry Andric   Declaration decl;
461fe013be4SDimitry Andric   CompilerType enum_type = m_ast->CreateEnumerationType(
462*c9157d92SDimitry Andric       ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
463*c9157d92SDimitry Andric       decl, m_ast->GetBasicType(eBasicTypeInt),
464fe013be4SDimitry Andric       /*is_scoped=*/false);
465fe013be4SDimitry Andric 
466*c9157d92SDimitry Andric   for (const CTFEnum::Value &value : ctf_enum.values) {
467fe013be4SDimitry Andric     Declaration value_decl;
468*c9157d92SDimitry Andric     m_ast->AddEnumerationValueToEnumerationType(
469*c9157d92SDimitry Andric         enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
470fe013be4SDimitry Andric   }
471*c9157d92SDimitry Andric   TypeSystemClang::CompleteTagDeclarationDefinition(enum_type);
472fe013be4SDimitry Andric 
473*c9157d92SDimitry Andric   return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
474fe013be4SDimitry Andric                   Type::eEncodingIsUID, decl, enum_type,
475fe013be4SDimitry Andric                   lldb_private::Type::ResolveState::Full);
476fe013be4SDimitry Andric }
477fe013be4SDimitry Andric 
478fe013be4SDimitry Andric llvm::Expected<lldb::TypeSP>
479*c9157d92SDimitry Andric SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
480fe013be4SDimitry Andric   std::vector<CompilerType> arg_types;
481*c9157d92SDimitry Andric   for (uint32_t arg : ctf_function.args) {
482*c9157d92SDimitry Andric     if (Type *arg_type = ResolveTypeUID(arg))
483fe013be4SDimitry Andric       arg_types.push_back(arg_type->GetFullCompilerType());
484fe013be4SDimitry Andric   }
485fe013be4SDimitry Andric 
486*c9157d92SDimitry Andric   Type *ret_type = ResolveTypeUID(ctf_function.return_type);
487fe013be4SDimitry Andric   if (!ret_type)
488fe013be4SDimitry Andric     return llvm::make_error<llvm::StringError>(
489*c9157d92SDimitry Andric         llvm::formatv("Could not find function return type: {0}",
490*c9157d92SDimitry Andric                       ctf_function.return_type),
491fe013be4SDimitry Andric         llvm::inconvertibleErrorCode());
492fe013be4SDimitry Andric 
493fe013be4SDimitry Andric   CompilerType func_type = m_ast->CreateFunctionType(
494fe013be4SDimitry Andric       ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
495*c9157d92SDimitry Andric       ctf_function.variadic, 0, clang::CallingConv::CC_C);
496fe013be4SDimitry Andric 
497fe013be4SDimitry Andric   Declaration decl;
498*c9157d92SDimitry Andric   return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
499*c9157d92SDimitry Andric                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
500fe013be4SDimitry Andric                   lldb_private::Type::ResolveState::Full);
501fe013be4SDimitry Andric }
502fe013be4SDimitry Andric 
503fe013be4SDimitry Andric llvm::Expected<lldb::TypeSP>
504*c9157d92SDimitry Andric SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
505*c9157d92SDimitry Andric   const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
506*c9157d92SDimitry Andric   CompilerType record_type = m_ast->CreateRecordType(
507*c9157d92SDimitry Andric       nullptr, OptionalClangModuleID(), eAccessPublic, ctf_record.name.data(),
508*c9157d92SDimitry Andric       llvm::to_underlying(tag_kind), eLanguageTypeC);
509*c9157d92SDimitry Andric   m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
510fe013be4SDimitry Andric   Declaration decl;
511*c9157d92SDimitry Andric   return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
512*c9157d92SDimitry Andric                   nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
513*c9157d92SDimitry Andric                   decl, record_type, lldb_private::Type::ResolveState::Forward);
514fe013be4SDimitry Andric }
515fe013be4SDimitry Andric 
516*c9157d92SDimitry Andric bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
517*c9157d92SDimitry Andric   // Check if we have a CTF type for the given incomplete compiler type.
518*c9157d92SDimitry Andric   auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
519*c9157d92SDimitry Andric   if (it == m_compiler_types.end())
520*c9157d92SDimitry Andric     return false;
521*c9157d92SDimitry Andric 
522*c9157d92SDimitry Andric   const CTFType *ctf_type = it->second;
523*c9157d92SDimitry Andric   assert(ctf_type && "m_compiler_types should only contain valid CTF types");
524*c9157d92SDimitry Andric 
525*c9157d92SDimitry Andric   // We only support resolving record types.
526*c9157d92SDimitry Andric   assert(llvm::isa<CTFRecord>(ctf_type));
527*c9157d92SDimitry Andric 
528*c9157d92SDimitry Andric   // Cast to the appropriate CTF type.
529*c9157d92SDimitry Andric   const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
530*c9157d92SDimitry Andric 
531*c9157d92SDimitry Andric   // If any of the fields are incomplete, we cannot complete the type.
532*c9157d92SDimitry Andric   for (const CTFRecord::Field &field : ctf_record->fields) {
533*c9157d92SDimitry Andric     if (!ResolveTypeUID(field.type)) {
534*c9157d92SDimitry Andric       LLDB_LOG(GetLog(LLDBLog::Symbols),
535*c9157d92SDimitry Andric                "Cannot complete type {0} because field {1} is incomplete",
536*c9157d92SDimitry Andric                ctf_type->uid, field.type);
537*c9157d92SDimitry Andric       return false;
538*c9157d92SDimitry Andric     }
539*c9157d92SDimitry Andric   }
540*c9157d92SDimitry Andric 
541*c9157d92SDimitry Andric   // Complete the record type.
542*c9157d92SDimitry Andric   m_ast->StartTagDeclarationDefinition(compiler_type);
543*c9157d92SDimitry Andric   for (const CTFRecord::Field &field : ctf_record->fields) {
544*c9157d92SDimitry Andric     Type *field_type = ResolveTypeUID(field.type);
545*c9157d92SDimitry Andric     assert(field_type && "field must be complete");
546*c9157d92SDimitry Andric     const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
547*c9157d92SDimitry Andric     TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
548*c9157d92SDimitry Andric                                           field_type->GetFullCompilerType(),
549*c9157d92SDimitry Andric                                           eAccessPublic, field_size);
550*c9157d92SDimitry Andric   }
551*c9157d92SDimitry Andric   m_ast->CompleteTagDeclarationDefinition(compiler_type);
552*c9157d92SDimitry Andric 
553*c9157d92SDimitry Andric   // Now that the compiler type is complete, we don't need to remember it
554*c9157d92SDimitry Andric   // anymore and can remove the CTF record type.
555*c9157d92SDimitry Andric   m_compiler_types.erase(compiler_type.GetOpaqueQualType());
556*c9157d92SDimitry Andric   m_ctf_types.erase(ctf_type->uid);
557*c9157d92SDimitry Andric 
558*c9157d92SDimitry Andric   return true;
559*c9157d92SDimitry Andric }
560*c9157d92SDimitry Andric 
561*c9157d92SDimitry Andric llvm::Expected<lldb::TypeSP>
562*c9157d92SDimitry Andric SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
563*c9157d92SDimitry Andric   CompilerType forward_compiler_type = m_ast->CreateRecordType(
564*c9157d92SDimitry Andric       nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
565*c9157d92SDimitry Andric       llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
566*c9157d92SDimitry Andric   Declaration decl;
567*c9157d92SDimitry Andric   return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
568*c9157d92SDimitry Andric                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
569*c9157d92SDimitry Andric                   forward_compiler_type, Type::ResolveState::Forward);
570*c9157d92SDimitry Andric }
571*c9157d92SDimitry Andric 
572*c9157d92SDimitry Andric llvm::Expected<TypeSP> SymbolFileCTF::CreateType(CTFType *ctf_type) {
573*c9157d92SDimitry Andric   if (!ctf_type)
574*c9157d92SDimitry Andric     return llvm::make_error<llvm::StringError>(
575*c9157d92SDimitry Andric         "cannot create type for unparsed type", llvm::inconvertibleErrorCode());
576*c9157d92SDimitry Andric 
577*c9157d92SDimitry Andric   switch (ctf_type->kind) {
578*c9157d92SDimitry Andric   case CTFType::Kind::eInteger:
579*c9157d92SDimitry Andric     return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
580*c9157d92SDimitry Andric   case CTFType::Kind::eConst:
581*c9157d92SDimitry Andric   case CTFType::Kind::ePointer:
582*c9157d92SDimitry Andric   case CTFType::Kind::eRestrict:
583*c9157d92SDimitry Andric   case CTFType::Kind::eVolatile:
584*c9157d92SDimitry Andric     return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
585*c9157d92SDimitry Andric   case CTFType::Kind::eTypedef:
586*c9157d92SDimitry Andric     return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
587*c9157d92SDimitry Andric   case CTFType::Kind::eArray:
588*c9157d92SDimitry Andric     return CreateArray(*static_cast<CTFArray *>(ctf_type));
589*c9157d92SDimitry Andric   case CTFType::Kind::eEnum:
590*c9157d92SDimitry Andric     return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
591*c9157d92SDimitry Andric   case CTFType::Kind::eFunction:
592*c9157d92SDimitry Andric     return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
593*c9157d92SDimitry Andric   case CTFType::Kind::eStruct:
594*c9157d92SDimitry Andric   case CTFType::Kind::eUnion:
595*c9157d92SDimitry Andric     return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
596*c9157d92SDimitry Andric   case CTFType::Kind::eForward:
597*c9157d92SDimitry Andric     return CreateForward(*static_cast<CTFForward *>(ctf_type));
598*c9157d92SDimitry Andric   case CTFType::Kind::eUnknown:
599*c9157d92SDimitry Andric   case CTFType::Kind::eFloat:
600*c9157d92SDimitry Andric   case CTFType::Kind::eSlice:
601*c9157d92SDimitry Andric     return llvm::make_error<llvm::StringError>(
602*c9157d92SDimitry Andric         llvm::formatv("unsupported type (uid = {0}, name = {1}, kind = {2})",
603*c9157d92SDimitry Andric                       ctf_type->uid, ctf_type->name, ctf_type->kind),
604*c9157d92SDimitry Andric         llvm::inconvertibleErrorCode());
605*c9157d92SDimitry Andric   }
606*c9157d92SDimitry Andric }
607*c9157d92SDimitry Andric 
608*c9157d92SDimitry Andric llvm::Expected<std::unique_ptr<CTFType>>
609*c9157d92SDimitry Andric SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
610*c9157d92SDimitry Andric   ctf_stype_t ctf_stype;
611*c9157d92SDimitry Andric   ctf_stype.name = m_data.GetU32(&offset);
612*c9157d92SDimitry Andric   ctf_stype.info = m_data.GetU32(&offset);
613*c9157d92SDimitry Andric   ctf_stype.size = m_data.GetU32(&offset);
614*c9157d92SDimitry Andric 
615*c9157d92SDimitry Andric   llvm::StringRef name = ReadString(ctf_stype.name);
616*c9157d92SDimitry Andric   const uint32_t kind = GetKind(ctf_stype.info);
617*c9157d92SDimitry Andric   const uint32_t variable_length = GetVLen(ctf_stype.info);
618*c9157d92SDimitry Andric   const uint32_t type = ctf_stype.GetType();
619*c9157d92SDimitry Andric   const uint32_t size = ctf_stype.GetSize();
620*c9157d92SDimitry Andric 
621fe013be4SDimitry Andric   switch (kind) {
622*c9157d92SDimitry Andric   case TypeKind::eInteger: {
623*c9157d92SDimitry Andric     const uint32_t vdata = m_data.GetU32(&offset);
624*c9157d92SDimitry Andric     const uint32_t bits = GetBits(vdata);
625*c9157d92SDimitry Andric     const uint32_t encoding = GetEncoding(vdata);
626*c9157d92SDimitry Andric     return std::make_unique<CTFInteger>(uid, name, bits, encoding);
627*c9157d92SDimitry Andric   }
628fe013be4SDimitry Andric   case TypeKind::eConst:
629*c9157d92SDimitry Andric     return std::make_unique<CTFConst>(uid, type);
630fe013be4SDimitry Andric   case TypeKind::ePointer:
631*c9157d92SDimitry Andric     return std::make_unique<CTFPointer>(uid, type);
632fe013be4SDimitry Andric   case TypeKind::eRestrict:
633*c9157d92SDimitry Andric     return std::make_unique<CTFRestrict>(uid, type);
634fe013be4SDimitry Andric   case TypeKind::eVolatile:
635*c9157d92SDimitry Andric     return std::make_unique<CTFVolatile>(uid, type);
636fe013be4SDimitry Andric   case TypeKind::eTypedef:
637*c9157d92SDimitry Andric     return std::make_unique<CTFTypedef>(uid, name, type);
638*c9157d92SDimitry Andric   case TypeKind::eArray: {
639*c9157d92SDimitry Andric     const uint32_t type = m_data.GetU32(&offset);
640*c9157d92SDimitry Andric     const uint32_t index = m_data.GetU32(&offset);
641*c9157d92SDimitry Andric     const uint32_t nelems = m_data.GetU32(&offset);
642*c9157d92SDimitry Andric     return std::make_unique<CTFArray>(uid, name, type, index, nelems);
643*c9157d92SDimitry Andric   }
644*c9157d92SDimitry Andric   case TypeKind::eEnum: {
645*c9157d92SDimitry Andric     std::vector<CTFEnum::Value> values;
646*c9157d92SDimitry Andric     for (uint32_t i = 0; i < variable_length; ++i) {
647*c9157d92SDimitry Andric       const uint32_t value_name = m_data.GetU32(&offset);
648*c9157d92SDimitry Andric       const uint32_t value = m_data.GetU32(&offset);
649*c9157d92SDimitry Andric       values.emplace_back(ReadString(value_name), value);
650*c9157d92SDimitry Andric     }
651*c9157d92SDimitry Andric     return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
652*c9157d92SDimitry Andric   }
653*c9157d92SDimitry Andric   case TypeKind::eFunction: {
654*c9157d92SDimitry Andric     std::vector<uint32_t> args;
655*c9157d92SDimitry Andric     bool variadic = false;
656*c9157d92SDimitry Andric     for (uint32_t i = 0; i < variable_length; ++i) {
657*c9157d92SDimitry Andric       const uint32_t arg_uid = m_data.GetU32(&offset);
658*c9157d92SDimitry Andric       // If the last argument is 0, this is a variadic function.
659*c9157d92SDimitry Andric       if (arg_uid == 0) {
660*c9157d92SDimitry Andric         variadic = true;
661*c9157d92SDimitry Andric         break;
662*c9157d92SDimitry Andric       }
663*c9157d92SDimitry Andric       args.push_back(arg_uid);
664*c9157d92SDimitry Andric     }
665*c9157d92SDimitry Andric     // If the number of arguments is odd, a single uint32_t of padding is
666*c9157d92SDimitry Andric     // inserted to maintain alignment.
667*c9157d92SDimitry Andric     if (variable_length % 2 == 1)
668*c9157d92SDimitry Andric       m_data.GetU32(&offset);
669*c9157d92SDimitry Andric     return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
670*c9157d92SDimitry Andric                                          variadic);
671*c9157d92SDimitry Andric   }
672fe013be4SDimitry Andric   case TypeKind::eStruct:
673*c9157d92SDimitry Andric   case TypeKind::eUnion: {
674*c9157d92SDimitry Andric     std::vector<CTFRecord::Field> fields;
675*c9157d92SDimitry Andric     for (uint32_t i = 0; i < variable_length; ++i) {
676*c9157d92SDimitry Andric       const uint32_t field_name = m_data.GetU32(&offset);
677*c9157d92SDimitry Andric       const uint32_t type = m_data.GetU32(&offset);
678*c9157d92SDimitry Andric       uint64_t field_offset = 0;
679*c9157d92SDimitry Andric       if (size < g_ctf_field_threshold) {
680*c9157d92SDimitry Andric         field_offset = m_data.GetU16(&offset);
681*c9157d92SDimitry Andric         m_data.GetU16(&offset); // Padding
682*c9157d92SDimitry Andric       } else {
683*c9157d92SDimitry Andric         const uint32_t offset_hi = m_data.GetU32(&offset);
684*c9157d92SDimitry Andric         const uint32_t offset_lo = m_data.GetU32(&offset);
685*c9157d92SDimitry Andric         field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
686*c9157d92SDimitry Andric       }
687*c9157d92SDimitry Andric       fields.emplace_back(ReadString(field_name), type, field_offset);
688*c9157d92SDimitry Andric     }
689*c9157d92SDimitry Andric     return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
690*c9157d92SDimitry Andric                                        name, variable_length, size, fields);
691*c9157d92SDimitry Andric   }
692fe013be4SDimitry Andric   case TypeKind::eForward:
693*c9157d92SDimitry Andric     return std::make_unique<CTFForward>(uid, name);
694fe013be4SDimitry Andric   case TypeKind::eUnknown:
695*c9157d92SDimitry Andric     return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
696*c9157d92SDimitry Andric                                      name);
697*c9157d92SDimitry Andric   case TypeKind::eFloat:
698*c9157d92SDimitry Andric   case TypeKind::eSlice:
699fe013be4SDimitry Andric     offset += (variable_length * sizeof(uint32_t));
700fe013be4SDimitry Andric     break;
701fe013be4SDimitry Andric   }
702*c9157d92SDimitry Andric 
703fe013be4SDimitry Andric   return llvm::make_error<llvm::StringError>(
704fe013be4SDimitry Andric       llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
705fe013be4SDimitry Andric                     name, kind, variable_length),
706fe013be4SDimitry Andric       llvm::inconvertibleErrorCode());
707fe013be4SDimitry Andric }
708fe013be4SDimitry Andric 
709fe013be4SDimitry Andric size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
710fe013be4SDimitry Andric   if (!ParseHeader())
711fe013be4SDimitry Andric     return 0;
712fe013be4SDimitry Andric 
713fe013be4SDimitry Andric   if (!m_types.empty())
714fe013be4SDimitry Andric     return 0;
715fe013be4SDimitry Andric 
716fe013be4SDimitry Andric   if (!m_ast)
717fe013be4SDimitry Andric     return 0;
718fe013be4SDimitry Andric 
719fe013be4SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
720fe013be4SDimitry Andric   LLDB_LOG(log, "Parsing CTF types");
721fe013be4SDimitry Andric 
722fe013be4SDimitry Andric   lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
723fe013be4SDimitry Andric   const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
724fe013be4SDimitry Andric 
725fe013be4SDimitry Andric   lldb::user_id_t type_uid = 1;
726fe013be4SDimitry Andric   while (type_offset < type_offset_end) {
727*c9157d92SDimitry Andric     llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
728*c9157d92SDimitry Andric         ParseType(type_offset, type_uid);
729*c9157d92SDimitry Andric     if (type_or_error) {
730*c9157d92SDimitry Andric       m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
731*c9157d92SDimitry Andric     } else {
732fe013be4SDimitry Andric       LLDB_LOG_ERROR(log, type_or_error.takeError(),
733fe013be4SDimitry Andric                      "Failed to parse type {1} at offset {2}: {0}", type_uid,
734fe013be4SDimitry Andric                      type_offset);
735fe013be4SDimitry Andric     }
736*c9157d92SDimitry Andric     type_uid++;
737fe013be4SDimitry Andric   }
738fe013be4SDimitry Andric 
739*c9157d92SDimitry Andric   LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
740fe013be4SDimitry Andric 
741*c9157d92SDimitry Andric   for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
742*c9157d92SDimitry Andric     ResolveTypeUID(uid);
743*c9157d92SDimitry Andric 
744*c9157d92SDimitry Andric   LLDB_LOG(log, "Created {0} CTF types", m_types.size());
745fe013be4SDimitry Andric 
746fe013be4SDimitry Andric   return m_types.size();
747fe013be4SDimitry Andric }
748fe013be4SDimitry Andric 
749fe013be4SDimitry Andric size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
750fe013be4SDimitry Andric   if (!ParseHeader())
751fe013be4SDimitry Andric     return 0;
752fe013be4SDimitry Andric 
753fe013be4SDimitry Andric   if (!m_functions.empty())
754fe013be4SDimitry Andric     return 0;
755fe013be4SDimitry Andric 
756fe013be4SDimitry Andric   if (!m_ast)
757fe013be4SDimitry Andric     return 0;
758fe013be4SDimitry Andric 
759fe013be4SDimitry Andric   Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
760fe013be4SDimitry Andric   if (!symtab)
761fe013be4SDimitry Andric     return 0;
762fe013be4SDimitry Andric 
763fe013be4SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
764fe013be4SDimitry Andric   LLDB_LOG(log, "Parsing CTF functions");
765fe013be4SDimitry Andric 
766fe013be4SDimitry Andric   lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
767fe013be4SDimitry Andric   const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
768fe013be4SDimitry Andric 
769fe013be4SDimitry Andric   uint32_t symbol_idx = 0;
770fe013be4SDimitry Andric   Declaration decl;
771fe013be4SDimitry Andric   while (function_offset < function_offset_end) {
772fe013be4SDimitry Andric     const uint32_t info = m_data.GetU32(&function_offset);
773fe013be4SDimitry Andric     const uint16_t kind = GetKind(info);
774fe013be4SDimitry Andric     const uint16_t variable_length = GetVLen(info);
775fe013be4SDimitry Andric 
776fe013be4SDimitry Andric     Symbol *symbol = symtab->FindSymbolWithType(
777fe013be4SDimitry Andric         eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx);
778fe013be4SDimitry Andric 
779fe013be4SDimitry Andric     // Skip padding.
780fe013be4SDimitry Andric     if (kind == TypeKind::eUnknown && variable_length == 0)
781fe013be4SDimitry Andric       continue;
782fe013be4SDimitry Andric 
783fe013be4SDimitry Andric     // Skip unexpected kinds.
784fe013be4SDimitry Andric     if (kind != TypeKind::eFunction)
785fe013be4SDimitry Andric       continue;
786fe013be4SDimitry Andric 
787fe013be4SDimitry Andric     const uint32_t ret_uid = m_data.GetU32(&function_offset);
788fe013be4SDimitry Andric     const uint32_t num_args = variable_length;
789fe013be4SDimitry Andric 
790fe013be4SDimitry Andric     std::vector<CompilerType> arg_types;
791fe013be4SDimitry Andric     arg_types.reserve(num_args);
792fe013be4SDimitry Andric 
793fe013be4SDimitry Andric     bool is_variadic = false;
794fe013be4SDimitry Andric     for (uint32_t i = 0; i < variable_length; i++) {
795fe013be4SDimitry Andric       const uint32_t arg_uid = m_data.GetU32(&function_offset);
796fe013be4SDimitry Andric 
797fe013be4SDimitry Andric       // If the last argument is 0, this is a variadic function.
798fe013be4SDimitry Andric       if (arg_uid == 0) {
799fe013be4SDimitry Andric         is_variadic = true;
800fe013be4SDimitry Andric         break;
801fe013be4SDimitry Andric       }
802fe013be4SDimitry Andric 
803*c9157d92SDimitry Andric       Type *arg_type = ResolveTypeUID(arg_uid);
804fe013be4SDimitry Andric       arg_types.push_back(arg_type->GetFullCompilerType());
805fe013be4SDimitry Andric     }
806fe013be4SDimitry Andric 
807fe013be4SDimitry Andric     if (symbol) {
808*c9157d92SDimitry Andric       Type *ret_type = ResolveTypeUID(ret_uid);
809fe013be4SDimitry Andric       AddressRange func_range =
810fe013be4SDimitry Andric           AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
811fe013be4SDimitry Andric                        GetObjectFile()->GetModule()->GetSectionList());
812fe013be4SDimitry Andric 
813fe013be4SDimitry Andric       // Create function type.
814fe013be4SDimitry Andric       CompilerType func_type = m_ast->CreateFunctionType(
815fe013be4SDimitry Andric           ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
816fe013be4SDimitry Andric           is_variadic, 0, clang::CallingConv::CC_C);
817fe013be4SDimitry Andric       lldb::user_id_t function_type_uid = m_types.size() + 1;
818fe013be4SDimitry Andric       TypeSP type_sp =
819fe013be4SDimitry Andric           MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
820fe013be4SDimitry Andric                    LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
821fe013be4SDimitry Andric                    lldb_private::Type::ResolveState::Full);
822*c9157d92SDimitry Andric       m_types[function_type_uid] = type_sp;
823fe013be4SDimitry Andric 
824fe013be4SDimitry Andric       // Create function.
825fe013be4SDimitry Andric       lldb::user_id_t func_uid = m_functions.size();
826fe013be4SDimitry Andric       FunctionSP function_sp = std::make_shared<Function>(
827fe013be4SDimitry Andric           &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
828fe013be4SDimitry Andric           func_range);
829fe013be4SDimitry Andric       m_functions.emplace_back(function_sp);
830fe013be4SDimitry Andric       cu.AddFunction(function_sp);
831fe013be4SDimitry Andric     }
832fe013be4SDimitry Andric   }
833fe013be4SDimitry Andric 
834fe013be4SDimitry Andric   LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
835fe013be4SDimitry Andric 
836fe013be4SDimitry Andric   return m_functions.size();
837fe013be4SDimitry Andric }
838fe013be4SDimitry Andric 
839fe013be4SDimitry Andric static DWARFExpression CreateDWARFExpression(ModuleSP module_sp,
840fe013be4SDimitry Andric                                              const Symbol &symbol) {
841fe013be4SDimitry Andric   if (!module_sp)
842fe013be4SDimitry Andric     return DWARFExpression();
843fe013be4SDimitry Andric 
844fe013be4SDimitry Andric   const ArchSpec &architecture = module_sp->GetArchitecture();
845fe013be4SDimitry Andric   ByteOrder byte_order = architecture.GetByteOrder();
846fe013be4SDimitry Andric   uint32_t address_size = architecture.GetAddressByteSize();
847fe013be4SDimitry Andric   uint32_t byte_size = architecture.GetDataByteSize();
848fe013be4SDimitry Andric 
849fe013be4SDimitry Andric   StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
850fe013be4SDimitry Andric   stream.PutHex8(lldb_private::dwarf::DW_OP_addr);
851fe013be4SDimitry Andric   stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
852fe013be4SDimitry Andric 
853fe013be4SDimitry Andric   DataBufferSP buffer =
854fe013be4SDimitry Andric       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
855fe013be4SDimitry Andric   lldb_private::DataExtractor extractor(buffer, byte_order, address_size,
856fe013be4SDimitry Andric                                         byte_size);
857fe013be4SDimitry Andric   DWARFExpression result(extractor);
858fe013be4SDimitry Andric   result.SetRegisterKind(eRegisterKindDWARF);
859fe013be4SDimitry Andric 
860fe013be4SDimitry Andric   return result;
861fe013be4SDimitry Andric }
862fe013be4SDimitry Andric 
863fe013be4SDimitry Andric size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
864fe013be4SDimitry Andric   if (!ParseHeader())
865fe013be4SDimitry Andric     return 0;
866fe013be4SDimitry Andric 
867fe013be4SDimitry Andric   if (!m_variables.empty())
868fe013be4SDimitry Andric     return 0;
869fe013be4SDimitry Andric 
870fe013be4SDimitry Andric   if (!m_ast)
871fe013be4SDimitry Andric     return 0;
872fe013be4SDimitry Andric 
873fe013be4SDimitry Andric   ModuleSP module_sp = GetObjectFile()->GetModule();
874fe013be4SDimitry Andric   Symtab *symtab = module_sp->GetSymtab();
875fe013be4SDimitry Andric   if (!symtab)
876fe013be4SDimitry Andric     return 0;
877fe013be4SDimitry Andric 
878fe013be4SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
879fe013be4SDimitry Andric   LLDB_LOG(log, "Parsing CTF objects");
880fe013be4SDimitry Andric 
881fe013be4SDimitry Andric   lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
882fe013be4SDimitry Andric   const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
883fe013be4SDimitry Andric 
884fe013be4SDimitry Andric   uint32_t symbol_idx = 0;
885fe013be4SDimitry Andric   Declaration decl;
886fe013be4SDimitry Andric   while (object_offset < object_offset_end) {
887fe013be4SDimitry Andric     const uint32_t type_uid = m_data.GetU32(&object_offset);
888fe013be4SDimitry Andric 
889fe013be4SDimitry Andric     if (Symbol *symbol =
890fe013be4SDimitry Andric             symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
891fe013be4SDimitry Andric                                        Symtab::eVisibilityAny, symbol_idx)) {
892fe013be4SDimitry Andric       Variable::RangeList ranges;
893fe013be4SDimitry Andric       ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
894fe013be4SDimitry Andric 
895fe013be4SDimitry Andric       auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
896fe013be4SDimitry Andric 
897fe013be4SDimitry Andric       DWARFExpressionList location(
898fe013be4SDimitry Andric           module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
899fe013be4SDimitry Andric 
900fe013be4SDimitry Andric       lldb::user_id_t variable_type_uid = m_variables.size();
901fe013be4SDimitry Andric       m_variables.emplace_back(std::make_shared<Variable>(
902fe013be4SDimitry Andric           variable_type_uid, symbol->GetName().AsCString(),
903fe013be4SDimitry Andric           symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
904fe013be4SDimitry Andric           m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
905fe013be4SDimitry Andric           /*artificial=*/false,
906fe013be4SDimitry Andric           /*location_is_constant_data*/ false));
907fe013be4SDimitry Andric     }
908fe013be4SDimitry Andric   }
909fe013be4SDimitry Andric 
910fe013be4SDimitry Andric   LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
911fe013be4SDimitry Andric 
912fe013be4SDimitry Andric   return m_variables.size();
913fe013be4SDimitry Andric }
914fe013be4SDimitry Andric 
915fe013be4SDimitry Andric uint32_t SymbolFileCTF::CalculateAbilities() {
916fe013be4SDimitry Andric   if (!m_objfile_sp)
917fe013be4SDimitry Andric     return 0;
918fe013be4SDimitry Andric 
919fe013be4SDimitry Andric   if (!ParseHeader())
920fe013be4SDimitry Andric     return 0;
921fe013be4SDimitry Andric 
922fe013be4SDimitry Andric   return VariableTypes | Functions | GlobalVariables;
923fe013be4SDimitry Andric }
924fe013be4SDimitry Andric 
925fe013be4SDimitry Andric uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr,
926fe013be4SDimitry Andric                                              SymbolContextItem resolve_scope,
927fe013be4SDimitry Andric                                              SymbolContext &sc) {
928fe013be4SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
929fe013be4SDimitry Andric   if (m_objfile_sp->GetSymtab() == nullptr)
930fe013be4SDimitry Andric     return 0;
931fe013be4SDimitry Andric 
932fe013be4SDimitry Andric   uint32_t resolved_flags = 0;
933fe013be4SDimitry Andric 
934fe013be4SDimitry Andric   // Resolve symbols.
935fe013be4SDimitry Andric   if (resolve_scope & eSymbolContextSymbol) {
936fe013be4SDimitry Andric     sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
937fe013be4SDimitry Andric         so_addr.GetFileAddress());
938fe013be4SDimitry Andric     if (sc.symbol)
939fe013be4SDimitry Andric       resolved_flags |= eSymbolContextSymbol;
940fe013be4SDimitry Andric   }
941fe013be4SDimitry Andric 
942fe013be4SDimitry Andric   // Resolve functions.
943fe013be4SDimitry Andric   if (resolve_scope & eSymbolContextFunction) {
944fe013be4SDimitry Andric     for (FunctionSP function_sp : m_functions) {
945fe013be4SDimitry Andric       if (function_sp->GetAddressRange().ContainsFileAddress(
946fe013be4SDimitry Andric               so_addr.GetFileAddress())) {
947fe013be4SDimitry Andric         sc.function = function_sp.get();
948fe013be4SDimitry Andric         resolved_flags |= eSymbolContextFunction;
949fe013be4SDimitry Andric         break;
950fe013be4SDimitry Andric       }
951fe013be4SDimitry Andric     }
952fe013be4SDimitry Andric   }
953fe013be4SDimitry Andric 
954fe013be4SDimitry Andric   // Resolve variables.
955fe013be4SDimitry Andric   if (resolve_scope & eSymbolContextVariable) {
956fe013be4SDimitry Andric     for (VariableSP variable_sp : m_variables) {
957fe013be4SDimitry Andric       if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
958fe013be4SDimitry Andric         sc.variable = variable_sp.get();
959fe013be4SDimitry Andric         break;
960fe013be4SDimitry Andric       }
961fe013be4SDimitry Andric     }
962fe013be4SDimitry Andric   }
963fe013be4SDimitry Andric 
964fe013be4SDimitry Andric   return resolved_flags;
965fe013be4SDimitry Andric }
966fe013be4SDimitry Andric 
967fe013be4SDimitry Andric CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) {
968fe013be4SDimitry Andric   if (idx == 0)
969fe013be4SDimitry Andric     return m_comp_unit_sp;
970fe013be4SDimitry Andric   return {};
971fe013be4SDimitry Andric }
972fe013be4SDimitry Andric 
973fe013be4SDimitry Andric size_t
974fe013be4SDimitry Andric SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
975fe013be4SDimitry Andric   return ParseObjects(*m_comp_unit_sp);
976fe013be4SDimitry Andric }
977fe013be4SDimitry Andric 
978fe013be4SDimitry Andric void SymbolFileCTF::AddSymbols(Symtab &symtab) {
979fe013be4SDimitry Andric   // CTF does not encode symbols.
980fe013be4SDimitry Andric   // We rely on the existing symbol table to map symbols to type.
981fe013be4SDimitry Andric }
982fe013be4SDimitry Andric 
983fe013be4SDimitry Andric lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
984*c9157d92SDimitry Andric   auto type_it = m_types.find(type_uid);
985*c9157d92SDimitry Andric   if (type_it != m_types.end())
986*c9157d92SDimitry Andric     return type_it->second.get();
987*c9157d92SDimitry Andric 
988*c9157d92SDimitry Andric   auto ctf_type_it = m_ctf_types.find(type_uid);
989*c9157d92SDimitry Andric   if (ctf_type_it == m_ctf_types.end())
990*c9157d92SDimitry Andric     return nullptr;
991*c9157d92SDimitry Andric 
992*c9157d92SDimitry Andric   CTFType *ctf_type = ctf_type_it->second.get();
993*c9157d92SDimitry Andric   assert(ctf_type && "m_ctf_types should only contain valid CTF types");
994*c9157d92SDimitry Andric 
995*c9157d92SDimitry Andric   Log *log = GetLog(LLDBLog::Symbols);
996*c9157d92SDimitry Andric 
997*c9157d92SDimitry Andric   llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
998*c9157d92SDimitry Andric   if (!type_or_error) {
999*c9157d92SDimitry Andric     LLDB_LOG_ERROR(log, type_or_error.takeError(),
1000*c9157d92SDimitry Andric                    "Failed to create type for {1}: {0}", ctf_type->uid);
1001*c9157d92SDimitry Andric     return {};
1002fe013be4SDimitry Andric   }
1003fe013be4SDimitry Andric 
1004*c9157d92SDimitry Andric   TypeSP type_sp = *type_or_error;
1005fe013be4SDimitry Andric 
1006*c9157d92SDimitry Andric   if (log) {
1007*c9157d92SDimitry Andric     StreamString ss;
1008*c9157d92SDimitry Andric     type_sp->Dump(&ss, true);
1009*c9157d92SDimitry Andric     LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
1010*c9157d92SDimitry Andric               llvm::StringRef(ss.GetString()).rtrim());
1011*c9157d92SDimitry Andric   }
1012fe013be4SDimitry Andric 
1013*c9157d92SDimitry Andric   m_types[type_uid] = type_sp;
1014*c9157d92SDimitry Andric 
1015*c9157d92SDimitry Andric   // Except for record types which we'll need to complete later, we don't need
1016*c9157d92SDimitry Andric   // the CTF type anymore.
1017*c9157d92SDimitry Andric   if (!isa<CTFRecord>(ctf_type))
1018*c9157d92SDimitry Andric     m_ctf_types.erase(type_uid);
1019*c9157d92SDimitry Andric 
1020*c9157d92SDimitry Andric   return type_sp.get();
1021*c9157d92SDimitry Andric }
1022*c9157d92SDimitry Andric 
1023*c9157d92SDimitry Andric void SymbolFileCTF::FindTypes(const lldb_private::TypeQuery &match,
1024*c9157d92SDimitry Andric                               lldb_private::TypeResults &results) {
1025*c9157d92SDimitry Andric   // Make sure we haven't already searched this SymbolFile before.
1026*c9157d92SDimitry Andric   if (results.AlreadySearched(this))
1027*c9157d92SDimitry Andric     return;
1028*c9157d92SDimitry Andric 
1029*c9157d92SDimitry Andric   ConstString name = match.GetTypeBasename();
1030*c9157d92SDimitry Andric   for (TypeSP type_sp : GetTypeList().Types()) {
1031fe013be4SDimitry Andric     if (type_sp && type_sp->GetName() == name) {
1032*c9157d92SDimitry Andric       results.InsertUnique(type_sp);
1033*c9157d92SDimitry Andric       if (results.Done(match))
1034*c9157d92SDimitry Andric         return;
1035fe013be4SDimitry Andric     }
1036fe013be4SDimitry Andric   }
1037fe013be4SDimitry Andric }
1038fe013be4SDimitry Andric 
1039fe013be4SDimitry Andric void SymbolFileCTF::FindTypesByRegex(
1040fe013be4SDimitry Andric     const lldb_private::RegularExpression &regex, uint32_t max_matches,
1041fe013be4SDimitry Andric     lldb_private::TypeMap &types) {
1042fe013be4SDimitry Andric   ParseTypes(*m_comp_unit_sp);
1043fe013be4SDimitry Andric 
1044fe013be4SDimitry Andric   size_t matches = 0;
1045*c9157d92SDimitry Andric   for (TypeSP type_sp : GetTypeList().Types()) {
1046fe013be4SDimitry Andric     if (matches == max_matches)
1047fe013be4SDimitry Andric       break;
1048fe013be4SDimitry Andric     if (type_sp && regex.Execute(type_sp->GetName()))
1049fe013be4SDimitry Andric       types.Insert(type_sp);
1050fe013be4SDimitry Andric     matches++;
1051fe013be4SDimitry Andric   }
1052fe013be4SDimitry Andric }
1053fe013be4SDimitry Andric 
1054fe013be4SDimitry Andric void SymbolFileCTF::FindFunctions(
1055fe013be4SDimitry Andric     const lldb_private::Module::LookupInfo &lookup_info,
1056fe013be4SDimitry Andric     const lldb_private::CompilerDeclContext &parent_decl_ctx,
1057fe013be4SDimitry Andric     bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1058fe013be4SDimitry Andric   ParseFunctions(*m_comp_unit_sp);
1059fe013be4SDimitry Andric 
1060fe013be4SDimitry Andric   ConstString name = lookup_info.GetLookupName();
1061fe013be4SDimitry Andric   for (FunctionSP function_sp : m_functions) {
1062fe013be4SDimitry Andric     if (function_sp && function_sp->GetName() == name) {
1063fe013be4SDimitry Andric       lldb_private::SymbolContext sc;
1064fe013be4SDimitry Andric       sc.comp_unit = m_comp_unit_sp.get();
1065fe013be4SDimitry Andric       sc.function = function_sp.get();
1066fe013be4SDimitry Andric       sc_list.Append(sc);
1067fe013be4SDimitry Andric     }
1068fe013be4SDimitry Andric   }
1069fe013be4SDimitry Andric }
1070fe013be4SDimitry Andric 
1071fe013be4SDimitry Andric void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression &regex,
1072fe013be4SDimitry Andric                                   bool include_inlines,
1073fe013be4SDimitry Andric                                   lldb_private::SymbolContextList &sc_list) {
1074fe013be4SDimitry Andric   for (FunctionSP function_sp : m_functions) {
1075fe013be4SDimitry Andric     if (function_sp && regex.Execute(function_sp->GetName())) {
1076fe013be4SDimitry Andric       lldb_private::SymbolContext sc;
1077fe013be4SDimitry Andric       sc.comp_unit = m_comp_unit_sp.get();
1078fe013be4SDimitry Andric       sc.function = function_sp.get();
1079fe013be4SDimitry Andric       sc_list.Append(sc);
1080fe013be4SDimitry Andric     }
1081fe013be4SDimitry Andric   }
1082fe013be4SDimitry Andric }
1083fe013be4SDimitry Andric 
1084fe013be4SDimitry Andric void SymbolFileCTF::FindGlobalVariables(
1085fe013be4SDimitry Andric     lldb_private::ConstString name,
1086fe013be4SDimitry Andric     const lldb_private::CompilerDeclContext &parent_decl_ctx,
1087fe013be4SDimitry Andric     uint32_t max_matches, lldb_private::VariableList &variables) {
1088fe013be4SDimitry Andric   ParseObjects(*m_comp_unit_sp);
1089fe013be4SDimitry Andric 
1090fe013be4SDimitry Andric   size_t matches = 0;
1091fe013be4SDimitry Andric   for (VariableSP variable_sp : m_variables) {
1092fe013be4SDimitry Andric     if (matches == max_matches)
1093fe013be4SDimitry Andric       break;
1094fe013be4SDimitry Andric     if (variable_sp && variable_sp->GetName() == name) {
1095fe013be4SDimitry Andric       variables.AddVariable(variable_sp);
1096fe013be4SDimitry Andric       matches++;
1097fe013be4SDimitry Andric     }
1098fe013be4SDimitry Andric   }
1099fe013be4SDimitry Andric }
1100fe013be4SDimitry Andric 
1101fe013be4SDimitry Andric void SymbolFileCTF::FindGlobalVariables(
1102fe013be4SDimitry Andric     const lldb_private::RegularExpression &regex, uint32_t max_matches,
1103fe013be4SDimitry Andric     lldb_private::VariableList &variables) {
1104fe013be4SDimitry Andric   ParseObjects(*m_comp_unit_sp);
1105fe013be4SDimitry Andric 
1106fe013be4SDimitry Andric   size_t matches = 0;
1107fe013be4SDimitry Andric   for (VariableSP variable_sp : m_variables) {
1108fe013be4SDimitry Andric     if (matches == max_matches)
1109fe013be4SDimitry Andric       break;
1110fe013be4SDimitry Andric     if (variable_sp && regex.Execute(variable_sp->GetName())) {
1111fe013be4SDimitry Andric       variables.AddVariable(variable_sp);
1112fe013be4SDimitry Andric       matches++;
1113fe013be4SDimitry Andric     }
1114fe013be4SDimitry Andric   }
1115fe013be4SDimitry Andric }
1116