xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- DWARFASTParserClang.cpp -------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9be691f3bSpatrick #include <cstdlib>
10061da546Spatrick 
11*f6aab3d8Srobert #include "DWARFASTParser.h"
12061da546Spatrick #include "DWARFASTParserClang.h"
13061da546Spatrick #include "DWARFDebugInfo.h"
14061da546Spatrick #include "DWARFDeclContext.h"
15061da546Spatrick #include "DWARFDefines.h"
16061da546Spatrick #include "SymbolFileDWARF.h"
17061da546Spatrick #include "SymbolFileDWARFDebugMap.h"
18dda28197Spatrick #include "SymbolFileDWARFDwo.h"
19061da546Spatrick #include "UniqueDWARFASTType.h"
20061da546Spatrick 
21dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
22dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
23dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
24061da546Spatrick #include "Plugins/Language/ObjC/ObjCLanguage.h"
25061da546Spatrick #include "lldb/Core/Module.h"
26061da546Spatrick #include "lldb/Core/Value.h"
27061da546Spatrick #include "lldb/Host/Host.h"
28061da546Spatrick #include "lldb/Symbol/CompileUnit.h"
29061da546Spatrick #include "lldb/Symbol/Function.h"
30061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
31061da546Spatrick #include "lldb/Symbol/SymbolFile.h"
32061da546Spatrick #include "lldb/Symbol/TypeList.h"
33061da546Spatrick #include "lldb/Symbol/TypeMap.h"
34061da546Spatrick #include "lldb/Target/Language.h"
35061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
36061da546Spatrick #include "lldb/Utility/Log.h"
37061da546Spatrick #include "lldb/Utility/StreamString.h"
38061da546Spatrick 
39061da546Spatrick #include "clang/AST/CXXInheritance.h"
40061da546Spatrick #include "clang/AST/DeclCXX.h"
41061da546Spatrick #include "clang/AST/DeclObjC.h"
42061da546Spatrick #include "clang/AST/DeclTemplate.h"
43*f6aab3d8Srobert #include "clang/AST/Type.h"
44*f6aab3d8Srobert #include "llvm/Demangle/Demangle.h"
45061da546Spatrick 
46061da546Spatrick #include <map>
47061da546Spatrick #include <memory>
48*f6aab3d8Srobert #include <optional>
49061da546Spatrick #include <vector>
50061da546Spatrick 
51061da546Spatrick //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
52061da546Spatrick 
53061da546Spatrick #ifdef ENABLE_DEBUG_PRINTF
54be691f3bSpatrick #include <cstdio>
55061da546Spatrick #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
56061da546Spatrick #else
57061da546Spatrick #define DEBUG_PRINTF(fmt, ...)
58061da546Spatrick #endif
59061da546Spatrick 
60061da546Spatrick using namespace lldb;
61061da546Spatrick using namespace lldb_private;
62*f6aab3d8Srobert using namespace lldb_private::dwarf;
DWARFASTParserClang(TypeSystemClang & ast)63dda28197Spatrick DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
64061da546Spatrick     : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
65061da546Spatrick 
66be691f3bSpatrick DWARFASTParserClang::~DWARFASTParserClang() = default;
67061da546Spatrick 
DeclKindIsCXXClass(clang::Decl::Kind decl_kind)68061da546Spatrick static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) {
69061da546Spatrick   switch (decl_kind) {
70061da546Spatrick   case clang::Decl::CXXRecord:
71061da546Spatrick   case clang::Decl::ClassTemplateSpecialization:
72061da546Spatrick     return true;
73061da546Spatrick   default:
74061da546Spatrick     break;
75061da546Spatrick   }
76061da546Spatrick   return false;
77061da546Spatrick }
78061da546Spatrick 
79061da546Spatrick 
GetClangASTImporter()80061da546Spatrick ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
81061da546Spatrick   if (!m_clang_ast_importer_up) {
82dda28197Spatrick     m_clang_ast_importer_up = std::make_unique<ClangASTImporter>();
83061da546Spatrick   }
84061da546Spatrick   return *m_clang_ast_importer_up;
85061da546Spatrick }
86061da546Spatrick 
87061da546Spatrick /// Detect a forward declaration that is nested in a DW_TAG_module.
IsClangModuleFwdDecl(const DWARFDIE & Die)88061da546Spatrick static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
89061da546Spatrick   if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
90061da546Spatrick     return false;
91061da546Spatrick   auto Parent = Die.GetParent();
92061da546Spatrick   while (Parent.IsValid()) {
93061da546Spatrick     if (Parent.Tag() == DW_TAG_module)
94061da546Spatrick       return true;
95061da546Spatrick     Parent = Parent.GetParent();
96061da546Spatrick   }
97061da546Spatrick   return false;
98061da546Spatrick }
99061da546Spatrick 
GetContainingClangModuleDIE(const DWARFDIE & die)100061da546Spatrick static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {
101061da546Spatrick   if (die.IsValid()) {
102061da546Spatrick     DWARFDIE top_module_die;
103061da546Spatrick     // Now make sure this DIE is scoped in a DW_TAG_module tag and return true
104061da546Spatrick     // if so
105061da546Spatrick     for (DWARFDIE parent = die.GetParent(); parent.IsValid();
106061da546Spatrick          parent = parent.GetParent()) {
107061da546Spatrick       const dw_tag_t tag = parent.Tag();
108061da546Spatrick       if (tag == DW_TAG_module)
109061da546Spatrick         top_module_die = parent;
110061da546Spatrick       else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
111061da546Spatrick         break;
112061da546Spatrick     }
113061da546Spatrick 
114061da546Spatrick     return top_module_die;
115061da546Spatrick   }
116061da546Spatrick   return DWARFDIE();
117061da546Spatrick }
118061da546Spatrick 
GetContainingClangModule(const DWARFDIE & die)119061da546Spatrick static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {
120061da546Spatrick   if (die.IsValid()) {
121061da546Spatrick     DWARFDIE clang_module_die = GetContainingClangModuleDIE(die);
122061da546Spatrick 
123061da546Spatrick     if (clang_module_die) {
124061da546Spatrick       const char *module_name = clang_module_die.GetName();
125061da546Spatrick       if (module_name)
126061da546Spatrick         return die.GetDWARF()->GetExternalModule(
127061da546Spatrick             lldb_private::ConstString(module_name));
128061da546Spatrick     }
129061da546Spatrick   }
130061da546Spatrick   return lldb::ModuleSP();
131061da546Spatrick }
132061da546Spatrick 
ParseTypeFromClangModule(const SymbolContext & sc,const DWARFDIE & die,Log * log)133061da546Spatrick TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
134061da546Spatrick                                                      const DWARFDIE &die,
135061da546Spatrick                                                      Log *log) {
136061da546Spatrick   ModuleSP clang_module_sp = GetContainingClangModule(die);
137061da546Spatrick   if (!clang_module_sp)
138061da546Spatrick     return TypeSP();
139061da546Spatrick 
140061da546Spatrick   // If this type comes from a Clang module, recursively look in the
141061da546Spatrick   // DWARF section of the .pcm file in the module cache. Clang
142061da546Spatrick   // generates DWO skeleton units as breadcrumbs to find them.
143061da546Spatrick   llvm::SmallVector<CompilerContext, 4> decl_context;
144061da546Spatrick   die.GetDeclContext(decl_context);
145061da546Spatrick   TypeMap pcm_types;
146061da546Spatrick 
147061da546Spatrick   // The type in the Clang module must have the same language as the current CU.
148061da546Spatrick   LanguageSet languages;
149be691f3bSpatrick   languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
150061da546Spatrick   llvm::DenseSet<SymbolFile *> searched_symbol_files;
151061da546Spatrick   clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
152061da546Spatrick                                               searched_symbol_files, pcm_types);
153061da546Spatrick   if (pcm_types.Empty()) {
154061da546Spatrick     // Since this type is defined in one of the Clang modules imported
155061da546Spatrick     // by this symbol file, search all of them. Instead of calling
156061da546Spatrick     // sym_file->FindTypes(), which would return this again, go straight
157061da546Spatrick     // to the imported modules.
158061da546Spatrick     auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
159061da546Spatrick 
160061da546Spatrick     // Well-formed clang modules never form cycles; guard against corrupted
161061da546Spatrick     // ones by inserting the current file.
162061da546Spatrick     searched_symbol_files.insert(&sym_file);
163061da546Spatrick     sym_file.ForEachExternalModule(
164061da546Spatrick         *sc.comp_unit, searched_symbol_files, [&](Module &module) {
165061da546Spatrick           module.GetSymbolFile()->FindTypes(decl_context, languages,
166061da546Spatrick                                             searched_symbol_files, pcm_types);
167061da546Spatrick           return pcm_types.GetSize();
168061da546Spatrick         });
169061da546Spatrick   }
170061da546Spatrick 
171061da546Spatrick   if (!pcm_types.GetSize())
172061da546Spatrick     return TypeSP();
173061da546Spatrick 
174061da546Spatrick   // We found a real definition for this type in the Clang module, so lets use
175061da546Spatrick   // it and cache the fact that we found a complete type for this die.
176061da546Spatrick   TypeSP pcm_type_sp = pcm_types.GetTypeAtIndex(0);
177061da546Spatrick   if (!pcm_type_sp)
178061da546Spatrick     return TypeSP();
179061da546Spatrick 
180061da546Spatrick   lldb_private::CompilerType pcm_type = pcm_type_sp->GetForwardCompilerType();
181061da546Spatrick   lldb_private::CompilerType type =
182061da546Spatrick       GetClangASTImporter().CopyType(m_ast, pcm_type);
183061da546Spatrick 
184061da546Spatrick   if (!type)
185061da546Spatrick     return TypeSP();
186061da546Spatrick 
187061da546Spatrick   // Under normal operation pcm_type is a shallow forward declaration
188061da546Spatrick   // that gets completed later. This is necessary to support cyclic
189061da546Spatrick   // data structures. If, however, pcm_type is already complete (for
190061da546Spatrick   // example, because it was loaded for a different target before),
191061da546Spatrick   // the definition needs to be imported right away, too.
192061da546Spatrick   // Type::ResolveClangType() effectively ignores the ResolveState
193061da546Spatrick   // inside type_sp and only looks at IsDefined(), so it never calls
194061da546Spatrick   // ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(),
195061da546Spatrick   // which does extra work for Objective-C classes. This would result
196061da546Spatrick   // in only the forward declaration to be visible.
197061da546Spatrick   if (pcm_type.IsDefined())
198061da546Spatrick     GetClangASTImporter().RequireCompleteType(ClangUtil::GetQualType(type));
199061da546Spatrick 
200061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
201*f6aab3d8Srobert   auto type_sp = dwarf->MakeType(
202*f6aab3d8Srobert       die.GetID(), pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(nullptr),
203*f6aab3d8Srobert       nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
204*f6aab3d8Srobert       &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
205*f6aab3d8Srobert       TypePayloadClang(GetOwningClangModule(die)));
206061da546Spatrick   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
207dda28197Spatrick   clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
208dda28197Spatrick   if (tag_decl) {
209061da546Spatrick     LinkDeclContextToDIE(tag_decl, die);
210dda28197Spatrick   } else {
211061da546Spatrick     clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die);
212061da546Spatrick     if (defn_decl_ctx)
213061da546Spatrick       LinkDeclContextToDIE(defn_decl_ctx, die);
214061da546Spatrick   }
215061da546Spatrick 
216061da546Spatrick   return type_sp;
217061da546Spatrick }
218061da546Spatrick 
ForcefullyCompleteType(CompilerType type)219be691f3bSpatrick static void ForcefullyCompleteType(CompilerType type) {
220be691f3bSpatrick   bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
221be691f3bSpatrick   lldbassert(started && "Unable to start a class type definition.");
222be691f3bSpatrick   TypeSystemClang::CompleteTagDeclarationDefinition(type);
223be691f3bSpatrick   const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
224*f6aab3d8Srobert   auto ts_sp = type.GetTypeSystem();
225*f6aab3d8Srobert   auto ts = ts_sp.dyn_cast_or_null<TypeSystemClang>();
226*f6aab3d8Srobert   if (ts)
227*f6aab3d8Srobert     ts->SetDeclIsForcefullyCompleted(td);
228be691f3bSpatrick }
229be691f3bSpatrick 
230be691f3bSpatrick /// This function serves a similar purpose as RequireCompleteType above, but it
231be691f3bSpatrick /// avoids completing the type if it is not immediately necessary. It only
232be691f3bSpatrick /// ensures we _can_ complete the type later.
PrepareContextToReceiveMembers(TypeSystemClang & ast,ClangASTImporter & ast_importer,clang::DeclContext * decl_ctx,DWARFDIE die,const char * type_name_cstr)233be691f3bSpatrick static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
234061da546Spatrick                                            ClangASTImporter &ast_importer,
235061da546Spatrick                                            clang::DeclContext *decl_ctx,
236061da546Spatrick                                            DWARFDIE die,
237061da546Spatrick                                            const char *type_name_cstr) {
238061da546Spatrick   auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
239061da546Spatrick   if (!tag_decl_ctx)
240be691f3bSpatrick     return; // Non-tag context are always ready.
241be691f3bSpatrick 
242be691f3bSpatrick   // We have already completed the type, or we have found its definition and are
243be691f3bSpatrick   // ready to complete it later (cf. ParseStructureLikeDIE).
244be691f3bSpatrick   if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())
245061da546Spatrick     return;
246061da546Spatrick 
247be691f3bSpatrick   // We reach this point of the tag was present in the debug info as a
248be691f3bSpatrick   // declaration only. If it was imported from another AST context (in the
249be691f3bSpatrick   // gmodules case), we can complete the type by doing a full import.
250be691f3bSpatrick 
251061da546Spatrick   // If this type was not imported from an external AST, there's nothing to do.
252061da546Spatrick   CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);
253be691f3bSpatrick   if (type && ast_importer.CanImport(type)) {
254061da546Spatrick     auto qual_type = ClangUtil::GetQualType(type);
255be691f3bSpatrick     if (ast_importer.RequireCompleteType(qual_type))
256be691f3bSpatrick       return;
257061da546Spatrick     die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
258*f6aab3d8Srobert         "Unable to complete the Decl context for DIE {0} at offset "
259*f6aab3d8Srobert         "{1:x16}.\nPlease file a bug report.",
260061da546Spatrick         type_name_cstr ? type_name_cstr : "", die.GetOffset());
261061da546Spatrick   }
262be691f3bSpatrick 
263be691f3bSpatrick   // We don't have a type definition and/or the import failed. We must
264be691f3bSpatrick   // forcefully complete the type to avoid crashes.
265be691f3bSpatrick   ForcefullyCompleteType(type);
266061da546Spatrick }
267061da546Spatrick 
ParsedDWARFTypeAttributes(const DWARFDIE & die)268061da546Spatrick ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
269061da546Spatrick   DWARFAttributes attributes;
270061da546Spatrick   size_t num_attributes = die.GetAttributes(attributes);
271061da546Spatrick   for (size_t i = 0; i < num_attributes; ++i) {
272061da546Spatrick     dw_attr_t attr = attributes.AttributeAtIndex(i);
273061da546Spatrick     DWARFFormValue form_value;
274061da546Spatrick     if (!attributes.ExtractFormValueAtIndex(i, form_value))
275061da546Spatrick       continue;
276061da546Spatrick     switch (attr) {
277061da546Spatrick     case DW_AT_abstract_origin:
278061da546Spatrick       abstract_origin = form_value;
279061da546Spatrick       break;
280061da546Spatrick 
281061da546Spatrick     case DW_AT_accessibility:
282*f6aab3d8Srobert       accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());
283061da546Spatrick       break;
284061da546Spatrick 
285061da546Spatrick     case DW_AT_artificial:
286061da546Spatrick       is_artificial = form_value.Boolean();
287061da546Spatrick       break;
288061da546Spatrick 
289061da546Spatrick     case DW_AT_bit_stride:
290061da546Spatrick       bit_stride = form_value.Unsigned();
291061da546Spatrick       break;
292061da546Spatrick 
293061da546Spatrick     case DW_AT_byte_size:
294061da546Spatrick       byte_size = form_value.Unsigned();
295061da546Spatrick       break;
296061da546Spatrick 
297061da546Spatrick     case DW_AT_byte_stride:
298061da546Spatrick       byte_stride = form_value.Unsigned();
299061da546Spatrick       break;
300061da546Spatrick 
301061da546Spatrick     case DW_AT_calling_convention:
302061da546Spatrick       calling_convention = form_value.Unsigned();
303061da546Spatrick       break;
304061da546Spatrick 
305061da546Spatrick     case DW_AT_containing_type:
306061da546Spatrick       containing_type = form_value;
307061da546Spatrick       break;
308061da546Spatrick 
309061da546Spatrick     case DW_AT_decl_file:
310be691f3bSpatrick       // die.GetCU() can differ if DW_AT_specification uses DW_FORM_ref_addr.
311be691f3bSpatrick       decl.SetFile(
312be691f3bSpatrick           attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
313061da546Spatrick       break;
314061da546Spatrick     case DW_AT_decl_line:
315061da546Spatrick       decl.SetLine(form_value.Unsigned());
316061da546Spatrick       break;
317061da546Spatrick     case DW_AT_decl_column:
318061da546Spatrick       decl.SetColumn(form_value.Unsigned());
319061da546Spatrick       break;
320061da546Spatrick 
321061da546Spatrick     case DW_AT_declaration:
322061da546Spatrick       is_forward_declaration = form_value.Boolean();
323061da546Spatrick       break;
324061da546Spatrick 
325061da546Spatrick     case DW_AT_encoding:
326061da546Spatrick       encoding = form_value.Unsigned();
327061da546Spatrick       break;
328061da546Spatrick 
329061da546Spatrick     case DW_AT_enum_class:
330061da546Spatrick       is_scoped_enum = form_value.Boolean();
331061da546Spatrick       break;
332061da546Spatrick 
333061da546Spatrick     case DW_AT_explicit:
334061da546Spatrick       is_explicit = form_value.Boolean();
335061da546Spatrick       break;
336061da546Spatrick 
337061da546Spatrick     case DW_AT_external:
338061da546Spatrick       if (form_value.Unsigned())
339061da546Spatrick         storage = clang::SC_Extern;
340061da546Spatrick       break;
341061da546Spatrick 
342061da546Spatrick     case DW_AT_inline:
343061da546Spatrick       is_inline = form_value.Boolean();
344061da546Spatrick       break;
345061da546Spatrick 
346061da546Spatrick     case DW_AT_linkage_name:
347061da546Spatrick     case DW_AT_MIPS_linkage_name:
348061da546Spatrick       mangled_name = form_value.AsCString();
349061da546Spatrick       break;
350061da546Spatrick 
351061da546Spatrick     case DW_AT_name:
352061da546Spatrick       name.SetCString(form_value.AsCString());
353061da546Spatrick       break;
354061da546Spatrick 
355061da546Spatrick     case DW_AT_object_pointer:
356061da546Spatrick       object_pointer = form_value.Reference();
357061da546Spatrick       break;
358061da546Spatrick 
359061da546Spatrick     case DW_AT_signature:
360061da546Spatrick       signature = form_value;
361061da546Spatrick       break;
362061da546Spatrick 
363061da546Spatrick     case DW_AT_specification:
364061da546Spatrick       specification = form_value;
365061da546Spatrick       break;
366061da546Spatrick 
367061da546Spatrick     case DW_AT_type:
368061da546Spatrick       type = form_value;
369061da546Spatrick       break;
370061da546Spatrick 
371061da546Spatrick     case DW_AT_virtuality:
372061da546Spatrick       is_virtual = form_value.Boolean();
373061da546Spatrick       break;
374061da546Spatrick 
375061da546Spatrick     case DW_AT_APPLE_objc_complete_type:
376061da546Spatrick       is_complete_objc_class = form_value.Signed();
377061da546Spatrick       break;
378061da546Spatrick 
379061da546Spatrick     case DW_AT_APPLE_objc_direct:
380061da546Spatrick       is_objc_direct_call = true;
381061da546Spatrick       break;
382061da546Spatrick 
383061da546Spatrick     case DW_AT_APPLE_runtime_class:
384061da546Spatrick       class_language = (LanguageType)form_value.Signed();
385061da546Spatrick       break;
386061da546Spatrick 
387061da546Spatrick     case DW_AT_GNU_vector:
388061da546Spatrick       is_vector = form_value.Boolean();
389061da546Spatrick       break;
390061da546Spatrick     case DW_AT_export_symbols:
391061da546Spatrick       exports_symbols = form_value.Boolean();
392061da546Spatrick       break;
393*f6aab3d8Srobert     case DW_AT_rvalue_reference:
394*f6aab3d8Srobert       ref_qual = clang::RQ_RValue;
395*f6aab3d8Srobert       break;
396*f6aab3d8Srobert     case DW_AT_reference:
397*f6aab3d8Srobert       ref_qual = clang::RQ_LValue;
398*f6aab3d8Srobert       break;
399061da546Spatrick     }
400061da546Spatrick   }
401061da546Spatrick }
402061da546Spatrick 
GetUnitName(const DWARFDIE & die)403061da546Spatrick static std::string GetUnitName(const DWARFDIE &die) {
404061da546Spatrick   if (DWARFUnit *unit = die.GetCU())
405061da546Spatrick     return unit->GetAbsolutePath().GetPath();
406061da546Spatrick   return "<missing DWARF unit path>";
407061da546Spatrick }
408061da546Spatrick 
ParseTypeFromDWARF(const SymbolContext & sc,const DWARFDIE & die,bool * type_is_new_ptr)409061da546Spatrick TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
410061da546Spatrick                                                const DWARFDIE &die,
411061da546Spatrick                                                bool *type_is_new_ptr) {
412061da546Spatrick   if (type_is_new_ptr)
413061da546Spatrick     *type_is_new_ptr = false;
414061da546Spatrick 
415061da546Spatrick   if (!die)
416061da546Spatrick     return nullptr;
417061da546Spatrick 
418*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
419061da546Spatrick 
420061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
421061da546Spatrick   if (log) {
422061da546Spatrick     DWARFDIE context_die;
423061da546Spatrick     clang::DeclContext *context =
424061da546Spatrick         GetClangDeclContextContainingDIE(die, &context_die);
425061da546Spatrick 
426061da546Spatrick     dwarf->GetObjectFile()->GetModule()->LogMessage(
427061da546Spatrick         log,
428061da546Spatrick         "DWARFASTParserClang::ParseTypeFromDWARF "
429*f6aab3d8Srobert         "(die = {0:x16}, decl_ctx = {1:p} (die "
430*f6aab3d8Srobert         "{2:x16})) {3} name = '{4}')",
431061da546Spatrick         die.GetOffset(), static_cast<void *>(context), context_die.GetOffset(),
432061da546Spatrick         die.GetTagAsCString(), die.GetName());
433061da546Spatrick   }
434061da546Spatrick 
435061da546Spatrick   Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
436061da546Spatrick   if (type_ptr == DIE_IS_BEING_PARSED)
437061da546Spatrick     return nullptr;
438061da546Spatrick   if (type_ptr)
439061da546Spatrick     return type_ptr->shared_from_this();
440061da546Spatrick   // Set a bit that lets us know that we are currently parsing this
441061da546Spatrick   dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
442061da546Spatrick 
443061da546Spatrick   ParsedDWARFTypeAttributes attrs(die);
444061da546Spatrick 
445061da546Spatrick   if (DWARFDIE signature_die = attrs.signature.Reference()) {
446061da546Spatrick     if (TypeSP type_sp =
447061da546Spatrick             ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
448061da546Spatrick       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
449061da546Spatrick       if (clang::DeclContext *decl_ctx =
450061da546Spatrick               GetCachedClangDeclContextForDIE(signature_die))
451061da546Spatrick         LinkDeclContextToDIE(decl_ctx, die);
452061da546Spatrick       return type_sp;
453061da546Spatrick     }
454061da546Spatrick     return nullptr;
455061da546Spatrick   }
456061da546Spatrick 
457061da546Spatrick   if (type_is_new_ptr)
458061da546Spatrick     *type_is_new_ptr = true;
459061da546Spatrick 
460061da546Spatrick   const dw_tag_t tag = die.Tag();
461061da546Spatrick 
462061da546Spatrick   TypeSP type_sp;
463061da546Spatrick 
464061da546Spatrick   switch (tag) {
465061da546Spatrick   case DW_TAG_typedef:
466061da546Spatrick   case DW_TAG_base_type:
467061da546Spatrick   case DW_TAG_pointer_type:
468061da546Spatrick   case DW_TAG_reference_type:
469061da546Spatrick   case DW_TAG_rvalue_reference_type:
470061da546Spatrick   case DW_TAG_const_type:
471061da546Spatrick   case DW_TAG_restrict_type:
472061da546Spatrick   case DW_TAG_volatile_type:
473061da546Spatrick   case DW_TAG_atomic_type:
474061da546Spatrick   case DW_TAG_unspecified_type: {
475061da546Spatrick     type_sp = ParseTypeModifier(sc, die, attrs);
476061da546Spatrick     break;
477061da546Spatrick   }
478061da546Spatrick 
479061da546Spatrick   case DW_TAG_structure_type:
480061da546Spatrick   case DW_TAG_union_type:
481061da546Spatrick   case DW_TAG_class_type: {
482061da546Spatrick     type_sp = ParseStructureLikeDIE(sc, die, attrs);
483061da546Spatrick     break;
484061da546Spatrick   }
485061da546Spatrick 
486061da546Spatrick   case DW_TAG_enumeration_type: {
487061da546Spatrick     type_sp = ParseEnum(sc, die, attrs);
488061da546Spatrick     break;
489061da546Spatrick   }
490061da546Spatrick 
491061da546Spatrick   case DW_TAG_inlined_subroutine:
492061da546Spatrick   case DW_TAG_subprogram:
493061da546Spatrick   case DW_TAG_subroutine_type: {
494061da546Spatrick     type_sp = ParseSubroutine(die, attrs);
495061da546Spatrick     break;
496061da546Spatrick   }
497061da546Spatrick   case DW_TAG_array_type: {
498061da546Spatrick     type_sp = ParseArrayType(die, attrs);
499061da546Spatrick     break;
500061da546Spatrick   }
501061da546Spatrick   case DW_TAG_ptr_to_member_type: {
502061da546Spatrick     type_sp = ParsePointerToMemberType(die, attrs);
503061da546Spatrick     break;
504061da546Spatrick   }
505061da546Spatrick   default:
506061da546Spatrick     dwarf->GetObjectFile()->GetModule()->ReportError(
507*f6aab3d8Srobert         "[{0:x16}]: unhandled type tag {1:x4} ({2}), "
508*f6aab3d8Srobert         "please file a bug and "
509061da546Spatrick         "attach the file at the start of this error message",
510061da546Spatrick         die.GetOffset(), tag, DW_TAG_value_to_name(tag));
511061da546Spatrick     break;
512061da546Spatrick   }
513061da546Spatrick 
514061da546Spatrick   // TODO: We should consider making the switch above exhaustive to simplify
515061da546Spatrick   // control flow in ParseTypeFromDWARF. Then, we could simply replace this
516061da546Spatrick   // return statement with a call to llvm_unreachable.
517061da546Spatrick   return UpdateSymbolContextScopeForType(sc, die, type_sp);
518061da546Spatrick }
519061da546Spatrick 
520061da546Spatrick lldb::TypeSP
ParseTypeModifier(const SymbolContext & sc,const DWARFDIE & die,ParsedDWARFTypeAttributes & attrs)521061da546Spatrick DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
522061da546Spatrick                                        const DWARFDIE &die,
523061da546Spatrick                                        ParsedDWARFTypeAttributes &attrs) {
524*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
525061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
526061da546Spatrick   const dw_tag_t tag = die.Tag();
527dda28197Spatrick   LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
528061da546Spatrick   Type::ResolveState resolve_state = Type::ResolveState::Unresolved;
529061da546Spatrick   Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
530061da546Spatrick   TypeSP type_sp;
531061da546Spatrick   CompilerType clang_type;
532061da546Spatrick 
533be691f3bSpatrick   if (tag == DW_TAG_typedef) {
534be691f3bSpatrick     // DeclContext will be populated when the clang type is materialized in
535be691f3bSpatrick     // Type::ResolveCompilerType.
536be691f3bSpatrick     PrepareContextToReceiveMembers(
537be691f3bSpatrick         m_ast, GetClangASTImporter(),
538be691f3bSpatrick         GetClangDeclContextContainingDIE(die, nullptr), die,
539be691f3bSpatrick         attrs.name.GetCString());
540be691f3bSpatrick 
541be691f3bSpatrick     if (attrs.type.IsValid()) {
542061da546Spatrick       // Try to parse a typedef from the (DWARF embedded in the) Clang
543061da546Spatrick       // module file first as modules can contain typedef'ed
544061da546Spatrick       // structures that have no names like:
545061da546Spatrick       //
546061da546Spatrick       //  typedef struct { int a; } Foo;
547061da546Spatrick       //
548061da546Spatrick       // In this case we will have a structure with no name and a
549061da546Spatrick       // typedef named "Foo" that points to this unnamed
550061da546Spatrick       // structure. The name in the typedef is the only identifier for
551061da546Spatrick       // the struct, so always try to get typedefs from Clang modules
552061da546Spatrick       // if possible.
553061da546Spatrick       //
554061da546Spatrick       // The type_sp returned will be empty if the typedef doesn't
555061da546Spatrick       // exist in a module file, so it is cheap to call this function
556061da546Spatrick       // just to check.
557061da546Spatrick       //
558061da546Spatrick       // If we don't do this we end up creating a TypeSP that says
559061da546Spatrick       // this is a typedef to type 0x123 (the DW_AT_type value would
560061da546Spatrick       // be 0x123 in the DW_TAG_typedef), and this is the unnamed
561061da546Spatrick       // structure type. We will have a hard time tracking down an
562061da546Spatrick       // unnammed structure type in the module debug info, so we make
563061da546Spatrick       // sure we don't get into this situation by always resolving
564061da546Spatrick       // typedefs from the module.
565061da546Spatrick       const DWARFDIE encoding_die = attrs.type.Reference();
566061da546Spatrick 
567061da546Spatrick       // First make sure that the die that this is typedef'ed to _is_
568061da546Spatrick       // just a declaration (DW_AT_declaration == 1), not a full
569061da546Spatrick       // definition since template types can't be represented in
570061da546Spatrick       // modules since only concrete instances of templates are ever
571061da546Spatrick       // emitted and modules won't contain those
572061da546Spatrick       if (encoding_die &&
573061da546Spatrick           encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
574061da546Spatrick         type_sp = ParseTypeFromClangModule(sc, die, log);
575061da546Spatrick         if (type_sp)
576061da546Spatrick           return type_sp;
577061da546Spatrick       }
578061da546Spatrick     }
579be691f3bSpatrick   }
580061da546Spatrick 
581061da546Spatrick   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),
582061da546Spatrick                DW_TAG_value_to_name(tag), type_name_cstr,
583061da546Spatrick                encoding_uid.Reference());
584061da546Spatrick 
585061da546Spatrick   switch (tag) {
586061da546Spatrick   default:
587061da546Spatrick     break;
588061da546Spatrick 
589061da546Spatrick   case DW_TAG_unspecified_type:
590061da546Spatrick     if (attrs.name == "nullptr_t" || attrs.name == "decltype(nullptr)") {
591061da546Spatrick       resolve_state = Type::ResolveState::Full;
592061da546Spatrick       clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
593061da546Spatrick       break;
594061da546Spatrick     }
595061da546Spatrick     // Fall through to base type below in case we can handle the type
596061da546Spatrick     // there...
597*f6aab3d8Srobert     [[fallthrough]];
598061da546Spatrick 
599061da546Spatrick   case DW_TAG_base_type:
600061da546Spatrick     resolve_state = Type::ResolveState::Full;
601061da546Spatrick     clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
602061da546Spatrick         attrs.name.GetStringRef(), attrs.encoding,
603*f6aab3d8Srobert         attrs.byte_size.value_or(0) * 8);
604061da546Spatrick     break;
605061da546Spatrick 
606061da546Spatrick   case DW_TAG_pointer_type:
607061da546Spatrick     encoding_data_type = Type::eEncodingIsPointerUID;
608061da546Spatrick     break;
609061da546Spatrick   case DW_TAG_reference_type:
610061da546Spatrick     encoding_data_type = Type::eEncodingIsLValueReferenceUID;
611061da546Spatrick     break;
612061da546Spatrick   case DW_TAG_rvalue_reference_type:
613061da546Spatrick     encoding_data_type = Type::eEncodingIsRValueReferenceUID;
614061da546Spatrick     break;
615061da546Spatrick   case DW_TAG_typedef:
616061da546Spatrick     encoding_data_type = Type::eEncodingIsTypedefUID;
617061da546Spatrick     break;
618061da546Spatrick   case DW_TAG_const_type:
619061da546Spatrick     encoding_data_type = Type::eEncodingIsConstUID;
620061da546Spatrick     break;
621061da546Spatrick   case DW_TAG_restrict_type:
622061da546Spatrick     encoding_data_type = Type::eEncodingIsRestrictUID;
623061da546Spatrick     break;
624061da546Spatrick   case DW_TAG_volatile_type:
625061da546Spatrick     encoding_data_type = Type::eEncodingIsVolatileUID;
626061da546Spatrick     break;
627061da546Spatrick   case DW_TAG_atomic_type:
628061da546Spatrick     encoding_data_type = Type::eEncodingIsAtomicUID;
629061da546Spatrick     break;
630061da546Spatrick   }
631061da546Spatrick 
632061da546Spatrick   if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID ||
633061da546Spatrick                       encoding_data_type == Type::eEncodingIsTypedefUID)) {
634061da546Spatrick     if (tag == DW_TAG_pointer_type) {
635061da546Spatrick       DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
636061da546Spatrick 
637061da546Spatrick       if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
638061da546Spatrick         // Blocks have a __FuncPtr inside them which is a pointer to a
639061da546Spatrick         // function of the proper type.
640061da546Spatrick 
641be691f3bSpatrick         for (DWARFDIE child_die : target_die.children()) {
642061da546Spatrick           if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
643061da546Spatrick                       "__FuncPtr")) {
644061da546Spatrick             DWARFDIE function_pointer_type =
645061da546Spatrick                 child_die.GetReferencedDIE(DW_AT_type);
646061da546Spatrick 
647061da546Spatrick             if (function_pointer_type) {
648061da546Spatrick               DWARFDIE function_type =
649061da546Spatrick                   function_pointer_type.GetReferencedDIE(DW_AT_type);
650061da546Spatrick 
651061da546Spatrick               bool function_type_is_new_pointer;
652061da546Spatrick               TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
653061da546Spatrick                   sc, function_type, &function_type_is_new_pointer);
654061da546Spatrick 
655061da546Spatrick               if (lldb_function_type_sp) {
656061da546Spatrick                 clang_type = m_ast.CreateBlockPointerType(
657061da546Spatrick                     lldb_function_type_sp->GetForwardCompilerType());
658061da546Spatrick                 encoding_data_type = Type::eEncodingIsUID;
659061da546Spatrick                 attrs.type.Clear();
660061da546Spatrick                 resolve_state = Type::ResolveState::Full;
661061da546Spatrick               }
662061da546Spatrick             }
663061da546Spatrick 
664061da546Spatrick             break;
665061da546Spatrick           }
666061da546Spatrick         }
667061da546Spatrick       }
668061da546Spatrick     }
669061da546Spatrick 
670061da546Spatrick     if (cu_language == eLanguageTypeObjC ||
671061da546Spatrick         cu_language == eLanguageTypeObjC_plus_plus) {
672061da546Spatrick       if (attrs.name) {
673061da546Spatrick         if (attrs.name == "id") {
674061da546Spatrick           if (log)
675061da546Spatrick             dwarf->GetObjectFile()->GetModule()->LogMessage(
676061da546Spatrick                 log,
677*f6aab3d8Srobert                 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} '{2}' "
678061da546Spatrick                 "is Objective-C 'id' built-in type.",
679061da546Spatrick                 die.GetOffset(), die.GetTagAsCString(), die.GetName());
680061da546Spatrick           clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
681061da546Spatrick           encoding_data_type = Type::eEncodingIsUID;
682061da546Spatrick           attrs.type.Clear();
683061da546Spatrick           resolve_state = Type::ResolveState::Full;
684061da546Spatrick         } else if (attrs.name == "Class") {
685061da546Spatrick           if (log)
686061da546Spatrick             dwarf->GetObjectFile()->GetModule()->LogMessage(
687061da546Spatrick                 log,
688*f6aab3d8Srobert                 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} '{2}' "
689061da546Spatrick                 "is Objective-C 'Class' built-in type.",
690061da546Spatrick                 die.GetOffset(), die.GetTagAsCString(), die.GetName());
691061da546Spatrick           clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
692061da546Spatrick           encoding_data_type = Type::eEncodingIsUID;
693061da546Spatrick           attrs.type.Clear();
694061da546Spatrick           resolve_state = Type::ResolveState::Full;
695061da546Spatrick         } else if (attrs.name == "SEL") {
696061da546Spatrick           if (log)
697061da546Spatrick             dwarf->GetObjectFile()->GetModule()->LogMessage(
698061da546Spatrick                 log,
699*f6aab3d8Srobert                 "SymbolFileDWARF::ParseType (die = {0:x16}) {1} '{2}' "
700061da546Spatrick                 "is Objective-C 'selector' built-in type.",
701061da546Spatrick                 die.GetOffset(), die.GetTagAsCString(), die.GetName());
702061da546Spatrick           clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
703061da546Spatrick           encoding_data_type = Type::eEncodingIsUID;
704061da546Spatrick           attrs.type.Clear();
705061da546Spatrick           resolve_state = Type::ResolveState::Full;
706061da546Spatrick         }
707061da546Spatrick       } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
708061da546Spatrick                  attrs.type.IsValid()) {
709061da546Spatrick         // Clang sometimes erroneously emits id as objc_object*.  In that
710061da546Spatrick         // case we fix up the type to "id".
711061da546Spatrick 
712061da546Spatrick         const DWARFDIE encoding_die = attrs.type.Reference();
713061da546Spatrick 
714061da546Spatrick         if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
715061da546Spatrick           llvm::StringRef struct_name = encoding_die.GetName();
716061da546Spatrick           if (struct_name == "objc_object") {
717061da546Spatrick             if (log)
718061da546Spatrick               dwarf->GetObjectFile()->GetModule()->LogMessage(
719061da546Spatrick                   log,
720*f6aab3d8Srobert                   "SymbolFileDWARF::ParseType (die = {0:x16}) {1} "
721*f6aab3d8Srobert                   "'{2}' is 'objc_object*', which we overrode to "
722061da546Spatrick                   "'id'.",
723061da546Spatrick                   die.GetOffset(), die.GetTagAsCString(), die.GetName());
724061da546Spatrick             clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
725061da546Spatrick             encoding_data_type = Type::eEncodingIsUID;
726061da546Spatrick             attrs.type.Clear();
727061da546Spatrick             resolve_state = Type::ResolveState::Full;
728061da546Spatrick           }
729061da546Spatrick         }
730061da546Spatrick       }
731061da546Spatrick     }
732061da546Spatrick   }
733061da546Spatrick 
734*f6aab3d8Srobert   type_sp = dwarf->MakeType(
735*f6aab3d8Srobert       die.GetID(), attrs.name, attrs.byte_size, nullptr,
736061da546Spatrick       dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
737dda28197Spatrick       clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die)));
738061da546Spatrick 
739061da546Spatrick   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
740061da546Spatrick   return type_sp;
741061da546Spatrick }
742061da546Spatrick 
743*f6aab3d8Srobert ConstString
GetDIEClassTemplateParams(const DWARFDIE & die)744*f6aab3d8Srobert DWARFASTParserClang::GetDIEClassTemplateParams(const DWARFDIE &die) {
745*f6aab3d8Srobert   if (llvm::StringRef(die.GetName()).contains("<"))
746*f6aab3d8Srobert     return ConstString();
747*f6aab3d8Srobert 
748*f6aab3d8Srobert   TypeSystemClang::TemplateParameterInfos template_param_infos;
749*f6aab3d8Srobert   if (ParseTemplateParameterInfos(die, template_param_infos)) {
750*f6aab3d8Srobert     return ConstString(m_ast.PrintTemplateParams(template_param_infos));
751*f6aab3d8Srobert   }
752*f6aab3d8Srobert   return ConstString();
753*f6aab3d8Srobert }
754*f6aab3d8Srobert 
ParseEnum(const SymbolContext & sc,const DWARFDIE & die,ParsedDWARFTypeAttributes & attrs)755061da546Spatrick TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
756061da546Spatrick                                       const DWARFDIE &die,
757061da546Spatrick                                       ParsedDWARFTypeAttributes &attrs) {
758*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
759061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
760061da546Spatrick   const dw_tag_t tag = die.Tag();
761061da546Spatrick   TypeSP type_sp;
762061da546Spatrick 
763061da546Spatrick   if (attrs.is_forward_declaration) {
764061da546Spatrick     type_sp = ParseTypeFromClangModule(sc, die, log);
765061da546Spatrick     if (type_sp)
766061da546Spatrick       return type_sp;
767061da546Spatrick 
768*f6aab3d8Srobert     type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die);
769061da546Spatrick 
770061da546Spatrick     if (!type_sp) {
771061da546Spatrick       SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
772061da546Spatrick       if (debug_map_symfile) {
773061da546Spatrick         // We weren't able to find a full declaration in this DWARF,
774061da546Spatrick         // see if we have a declaration anywhere else...
775*f6aab3d8Srobert         type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
776061da546Spatrick       }
777061da546Spatrick     }
778061da546Spatrick 
779061da546Spatrick     if (type_sp) {
780061da546Spatrick       if (log) {
781061da546Spatrick         dwarf->GetObjectFile()->GetModule()->LogMessage(
782061da546Spatrick             log,
783*f6aab3d8Srobert             "SymbolFileDWARF({0:p}) - {1:x16}}: {2} type \"{3}\" is a "
784*f6aab3d8Srobert             "forward declaration, complete type is {4:x8}",
785061da546Spatrick             static_cast<void *>(this), die.GetOffset(),
786061da546Spatrick             DW_TAG_value_to_name(tag), attrs.name.GetCString(),
787061da546Spatrick             type_sp->GetID());
788061da546Spatrick       }
789061da546Spatrick 
790061da546Spatrick       // We found a real definition for this type elsewhere so lets use
791061da546Spatrick       // it and cache the fact that we found a complete type for this
792061da546Spatrick       // die
793061da546Spatrick       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
794061da546Spatrick       clang::DeclContext *defn_decl_ctx =
795061da546Spatrick           GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
796061da546Spatrick       if (defn_decl_ctx)
797061da546Spatrick         LinkDeclContextToDIE(defn_decl_ctx, die);
798061da546Spatrick       return type_sp;
799061da546Spatrick     }
800061da546Spatrick   }
801061da546Spatrick   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
802061da546Spatrick                DW_TAG_value_to_name(tag), type_name_cstr);
803061da546Spatrick 
804061da546Spatrick   CompilerType enumerator_clang_type;
805061da546Spatrick   CompilerType clang_type;
806*f6aab3d8Srobert   clang_type =
807*f6aab3d8Srobert       CompilerType(m_ast.weak_from_this(),
808*f6aab3d8Srobert                    dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
809061da546Spatrick   if (!clang_type) {
810061da546Spatrick     if (attrs.type.IsValid()) {
811061da546Spatrick       Type *enumerator_type =
812061da546Spatrick           dwarf->ResolveTypeUID(attrs.type.Reference(), true);
813061da546Spatrick       if (enumerator_type)
814061da546Spatrick         enumerator_clang_type = enumerator_type->GetFullCompilerType();
815061da546Spatrick     }
816061da546Spatrick 
817061da546Spatrick     if (!enumerator_clang_type) {
818061da546Spatrick       if (attrs.byte_size) {
819061da546Spatrick         enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
820061da546Spatrick             "", DW_ATE_signed, *attrs.byte_size * 8);
821061da546Spatrick       } else {
822061da546Spatrick         enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
823061da546Spatrick       }
824061da546Spatrick     }
825061da546Spatrick 
826061da546Spatrick     clang_type = m_ast.CreateEnumerationType(
827*f6aab3d8Srobert         attrs.name.GetStringRef(),
828*f6aab3d8Srobert         GetClangDeclContextContainingDIE(die, nullptr),
829dda28197Spatrick         GetOwningClangModule(die), attrs.decl, enumerator_clang_type,
830dda28197Spatrick         attrs.is_scoped_enum);
831061da546Spatrick   } else {
832dda28197Spatrick     enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
833061da546Spatrick   }
834061da546Spatrick 
835dda28197Spatrick   LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die);
836061da546Spatrick 
837*f6aab3d8Srobert   type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
838*f6aab3d8Srobert                             dwarf->GetUID(attrs.type.Reference()),
839*f6aab3d8Srobert                             Type::eEncodingIsUID, &attrs.decl, clang_type,
840*f6aab3d8Srobert                             Type::ResolveState::Forward,
841dda28197Spatrick                             TypePayloadClang(GetOwningClangModule(die)));
842061da546Spatrick 
843dda28197Spatrick   if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
844061da546Spatrick     if (die.HasChildren()) {
845061da546Spatrick       bool is_signed = false;
846061da546Spatrick       enumerator_clang_type.IsIntegerType(is_signed);
847061da546Spatrick       ParseChildEnumerators(clang_type, is_signed,
848*f6aab3d8Srobert                             type_sp->GetByteSize(nullptr).value_or(0), die);
849061da546Spatrick     }
850dda28197Spatrick     TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
851061da546Spatrick   } else {
852061da546Spatrick     dwarf->GetObjectFile()->GetModule()->ReportError(
853*f6aab3d8Srobert         "DWARF DIE at {0:x16} named \"{1}\" was not able to start its "
854061da546Spatrick         "definition.\nPlease file a bug and attach the file at the "
855061da546Spatrick         "start of this error message",
856061da546Spatrick         die.GetOffset(), attrs.name.GetCString());
857061da546Spatrick   }
858061da546Spatrick   return type_sp;
859061da546Spatrick }
860061da546Spatrick 
861*f6aab3d8Srobert static clang::CallingConv
ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes & attrs)862*f6aab3d8Srobert ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) {
863*f6aab3d8Srobert   switch (attrs.calling_convention) {
864*f6aab3d8Srobert   case llvm::dwarf::DW_CC_normal:
865*f6aab3d8Srobert     return clang::CC_C;
866*f6aab3d8Srobert   case llvm::dwarf::DW_CC_BORLAND_stdcall:
867*f6aab3d8Srobert     return clang::CC_X86StdCall;
868*f6aab3d8Srobert   case llvm::dwarf::DW_CC_BORLAND_msfastcall:
869*f6aab3d8Srobert     return clang::CC_X86FastCall;
870*f6aab3d8Srobert   case llvm::dwarf::DW_CC_LLVM_vectorcall:
871*f6aab3d8Srobert     return clang::CC_X86VectorCall;
872*f6aab3d8Srobert   case llvm::dwarf::DW_CC_BORLAND_pascal:
873*f6aab3d8Srobert     return clang::CC_X86Pascal;
874*f6aab3d8Srobert   case llvm::dwarf::DW_CC_LLVM_Win64:
875*f6aab3d8Srobert     return clang::CC_Win64;
876*f6aab3d8Srobert   case llvm::dwarf::DW_CC_LLVM_X86_64SysV:
877*f6aab3d8Srobert     return clang::CC_X86_64SysV;
878*f6aab3d8Srobert   case llvm::dwarf::DW_CC_LLVM_X86RegCall:
879*f6aab3d8Srobert     return clang::CC_X86RegCall;
880*f6aab3d8Srobert   default:
881*f6aab3d8Srobert     break;
882*f6aab3d8Srobert   }
883*f6aab3d8Srobert 
884*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
885*f6aab3d8Srobert   LLDB_LOG(log, "Unsupported DW_AT_calling_convention value: {0}",
886*f6aab3d8Srobert            attrs.calling_convention);
887*f6aab3d8Srobert   // Use the default calling convention as a fallback.
888*f6aab3d8Srobert   return clang::CC_C;
889*f6aab3d8Srobert }
890*f6aab3d8Srobert 
ParseSubroutine(const DWARFDIE & die,ParsedDWARFTypeAttributes & attrs)891061da546Spatrick TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
892061da546Spatrick                            ParsedDWARFTypeAttributes &attrs) {
893*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
894061da546Spatrick 
895061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
896061da546Spatrick   const dw_tag_t tag = die.Tag();
897061da546Spatrick 
898061da546Spatrick   bool is_variadic = false;
899061da546Spatrick   bool is_static = false;
900061da546Spatrick   bool has_template_params = false;
901061da546Spatrick 
902061da546Spatrick   unsigned type_quals = 0;
903061da546Spatrick 
904061da546Spatrick   std::string object_pointer_name;
905061da546Spatrick   if (attrs.object_pointer) {
906061da546Spatrick     const char *object_pointer_name_cstr = attrs.object_pointer.GetName();
907061da546Spatrick     if (object_pointer_name_cstr)
908061da546Spatrick       object_pointer_name = object_pointer_name_cstr;
909061da546Spatrick   }
910061da546Spatrick 
911061da546Spatrick   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
912061da546Spatrick                DW_TAG_value_to_name(tag), type_name_cstr);
913061da546Spatrick 
914061da546Spatrick   CompilerType return_clang_type;
915*f6aab3d8Srobert   Type *func_type = nullptr;
916061da546Spatrick 
917061da546Spatrick   if (attrs.type.IsValid())
918061da546Spatrick     func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
919061da546Spatrick 
920061da546Spatrick   if (func_type)
921061da546Spatrick     return_clang_type = func_type->GetForwardCompilerType();
922061da546Spatrick   else
923061da546Spatrick     return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
924061da546Spatrick 
925061da546Spatrick   std::vector<CompilerType> function_param_types;
926061da546Spatrick   std::vector<clang::ParmVarDecl *> function_param_decls;
927061da546Spatrick 
928061da546Spatrick   // Parse the function children for the parameters
929061da546Spatrick 
930061da546Spatrick   DWARFDIE decl_ctx_die;
931061da546Spatrick   clang::DeclContext *containing_decl_ctx =
932061da546Spatrick       GetClangDeclContextContainingDIE(die, &decl_ctx_die);
933061da546Spatrick   const clang::Decl::Kind containing_decl_kind =
934061da546Spatrick       containing_decl_ctx->getDeclKind();
935061da546Spatrick 
936061da546Spatrick   bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
937061da546Spatrick   // Start off static. This will be set to false in
938061da546Spatrick   // ParseChildParameters(...) if we find a "this" parameters as the
939061da546Spatrick   // first parameter
940061da546Spatrick   if (is_cxx_method) {
941061da546Spatrick     is_static = true;
942061da546Spatrick   }
943061da546Spatrick 
944061da546Spatrick   if (die.HasChildren()) {
945061da546Spatrick     bool skip_artificial = true;
946061da546Spatrick     ParseChildParameters(containing_decl_ctx, die, skip_artificial, is_static,
947061da546Spatrick                          is_variadic, has_template_params,
948061da546Spatrick                          function_param_types, function_param_decls,
949061da546Spatrick                          type_quals);
950061da546Spatrick   }
951061da546Spatrick 
952061da546Spatrick   bool ignore_containing_context = false;
953061da546Spatrick   // Check for templatized class member functions. If we had any
954061da546Spatrick   // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
955061da546Spatrick   // the DW_TAG_subprogram DIE, then we can't let this become a method in
956061da546Spatrick   // a class. Why? Because templatized functions are only emitted if one
957061da546Spatrick   // of the templatized methods is used in the current compile unit and
958061da546Spatrick   // we will end up with classes that may or may not include these member
959061da546Spatrick   // functions and this means one class won't match another class
960061da546Spatrick   // definition and it affects our ability to use a class in the clang
961061da546Spatrick   // expression parser. So for the greater good, we currently must not
962061da546Spatrick   // allow any template member functions in a class definition.
963061da546Spatrick   if (is_cxx_method && has_template_params) {
964061da546Spatrick     ignore_containing_context = true;
965061da546Spatrick     is_cxx_method = false;
966061da546Spatrick   }
967061da546Spatrick 
968*f6aab3d8Srobert   clang::CallingConv calling_convention =
969*f6aab3d8Srobert       ConvertDWARFCallingConventionToClang(attrs);
970*f6aab3d8Srobert 
971061da546Spatrick   // clang_type will get the function prototype clang type after this
972061da546Spatrick   // call
973*f6aab3d8Srobert   CompilerType clang_type =
974*f6aab3d8Srobert       m_ast.CreateFunctionType(return_clang_type, function_param_types.data(),
975*f6aab3d8Srobert                                function_param_types.size(), is_variadic,
976*f6aab3d8Srobert                                type_quals, calling_convention, attrs.ref_qual);
977061da546Spatrick 
978061da546Spatrick   if (attrs.name) {
979061da546Spatrick     bool type_handled = false;
980061da546Spatrick     if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
981061da546Spatrick       ObjCLanguage::MethodName objc_method(attrs.name.GetStringRef(), true);
982061da546Spatrick       if (objc_method.IsValid(true)) {
983061da546Spatrick         CompilerType class_opaque_type;
984061da546Spatrick         ConstString class_name(objc_method.GetClassName());
985061da546Spatrick         if (class_name) {
986061da546Spatrick           TypeSP complete_objc_class_type_sp(
987061da546Spatrick               dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(),
988061da546Spatrick                                                           class_name, false));
989061da546Spatrick 
990061da546Spatrick           if (complete_objc_class_type_sp) {
991061da546Spatrick             CompilerType type_clang_forward_type =
992061da546Spatrick                 complete_objc_class_type_sp->GetForwardCompilerType();
993dda28197Spatrick             if (TypeSystemClang::IsObjCObjectOrInterfaceType(
994061da546Spatrick                     type_clang_forward_type))
995061da546Spatrick               class_opaque_type = type_clang_forward_type;
996061da546Spatrick           }
997061da546Spatrick         }
998061da546Spatrick 
999061da546Spatrick         if (class_opaque_type) {
1000061da546Spatrick           // If accessibility isn't set to anything valid, assume public
1001061da546Spatrick           // for now...
1002061da546Spatrick           if (attrs.accessibility == eAccessNone)
1003061da546Spatrick             attrs.accessibility = eAccessPublic;
1004061da546Spatrick 
1005061da546Spatrick           clang::ObjCMethodDecl *objc_method_decl =
1006061da546Spatrick               m_ast.AddMethodToObjCObjectType(
1007061da546Spatrick                   class_opaque_type, attrs.name.GetCString(), clang_type,
1008061da546Spatrick                   attrs.accessibility, attrs.is_artificial, is_variadic,
1009061da546Spatrick                   attrs.is_objc_direct_call);
1010*f6aab3d8Srobert           type_handled = objc_method_decl != nullptr;
1011061da546Spatrick           if (type_handled) {
1012061da546Spatrick             LinkDeclContextToDIE(objc_method_decl, die);
1013061da546Spatrick             m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
1014061da546Spatrick           } else {
1015061da546Spatrick             dwarf->GetObjectFile()->GetModule()->ReportError(
1016*f6aab3d8Srobert                 "[{0:x16}]: invalid Objective-C method {1:x4} ({2}), "
1017061da546Spatrick                 "please file a bug and attach the file at the start of "
1018061da546Spatrick                 "this error message",
1019061da546Spatrick                 die.GetOffset(), tag, DW_TAG_value_to_name(tag));
1020061da546Spatrick           }
1021061da546Spatrick         }
1022061da546Spatrick       } else if (is_cxx_method) {
1023061da546Spatrick         // Look at the parent of this DIE and see if is is a class or
1024061da546Spatrick         // struct and see if this is actually a C++ method
1025061da546Spatrick         Type *class_type = dwarf->ResolveType(decl_ctx_die);
1026061da546Spatrick         if (class_type) {
1027061da546Spatrick           if (class_type->GetID() != decl_ctx_die.GetID() ||
1028061da546Spatrick               IsClangModuleFwdDecl(decl_ctx_die)) {
1029061da546Spatrick 
1030061da546Spatrick             // We uniqued the parent class of this function to another
1031061da546Spatrick             // class so we now need to associate all dies under
1032061da546Spatrick             // "decl_ctx_die" to DIEs in the DIE for "class_type"...
1033061da546Spatrick             DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
1034061da546Spatrick 
1035061da546Spatrick             if (class_type_die) {
1036061da546Spatrick               std::vector<DWARFDIE> failures;
1037061da546Spatrick 
1038061da546Spatrick               CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
1039061da546Spatrick                                          class_type, failures);
1040061da546Spatrick 
1041061da546Spatrick               // FIXME do something with these failures that's
1042061da546Spatrick               // smarter than just dropping them on the ground.
1043061da546Spatrick               // Unfortunately classes don't like having stuff added
1044061da546Spatrick               // to them after their definitions are complete...
1045061da546Spatrick 
1046061da546Spatrick               Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1047061da546Spatrick               if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
1048061da546Spatrick                 return type_ptr->shared_from_this();
1049061da546Spatrick               }
1050061da546Spatrick             }
1051061da546Spatrick           }
1052061da546Spatrick 
1053061da546Spatrick           if (attrs.specification.IsValid()) {
1054061da546Spatrick             // We have a specification which we are going to base our
1055061da546Spatrick             // function prototype off of, so we need this type to be
1056061da546Spatrick             // completed so that the m_die_to_decl_ctx for the method in
1057061da546Spatrick             // the specification has a valid clang decl context.
1058061da546Spatrick             class_type->GetForwardCompilerType();
1059061da546Spatrick             // If we have a specification, then the function type should
1060061da546Spatrick             // have been made with the specification and not with this
1061061da546Spatrick             // die.
1062061da546Spatrick             DWARFDIE spec_die = attrs.specification.Reference();
1063061da546Spatrick             clang::DeclContext *spec_clang_decl_ctx =
1064061da546Spatrick                 GetClangDeclContextForDIE(spec_die);
1065061da546Spatrick             if (spec_clang_decl_ctx) {
1066061da546Spatrick               LinkDeclContextToDIE(spec_clang_decl_ctx, die);
1067061da546Spatrick             } else {
1068061da546Spatrick               dwarf->GetObjectFile()->GetModule()->ReportWarning(
1069*f6aab3d8Srobert                   "{0:x8}: DW_AT_specification({1:x16}"
1070061da546Spatrick                   ") has no decl\n",
1071061da546Spatrick                   die.GetID(), spec_die.GetOffset());
1072061da546Spatrick             }
1073061da546Spatrick             type_handled = true;
1074061da546Spatrick           } else if (attrs.abstract_origin.IsValid()) {
1075061da546Spatrick             // We have a specification which we are going to base our
1076061da546Spatrick             // function prototype off of, so we need this type to be
1077061da546Spatrick             // completed so that the m_die_to_decl_ctx for the method in
1078061da546Spatrick             // the abstract origin has a valid clang decl context.
1079061da546Spatrick             class_type->GetForwardCompilerType();
1080061da546Spatrick 
1081061da546Spatrick             DWARFDIE abs_die = attrs.abstract_origin.Reference();
1082061da546Spatrick             clang::DeclContext *abs_clang_decl_ctx =
1083061da546Spatrick                 GetClangDeclContextForDIE(abs_die);
1084061da546Spatrick             if (abs_clang_decl_ctx) {
1085061da546Spatrick               LinkDeclContextToDIE(abs_clang_decl_ctx, die);
1086061da546Spatrick             } else {
1087061da546Spatrick               dwarf->GetObjectFile()->GetModule()->ReportWarning(
1088*f6aab3d8Srobert                   "{0:x8}: DW_AT_abstract_origin({1:x16}"
1089061da546Spatrick                   ") has no decl\n",
1090061da546Spatrick                   die.GetID(), abs_die.GetOffset());
1091061da546Spatrick             }
1092061da546Spatrick             type_handled = true;
1093061da546Spatrick           } else {
1094061da546Spatrick             CompilerType class_opaque_type =
1095061da546Spatrick                 class_type->GetForwardCompilerType();
1096dda28197Spatrick             if (TypeSystemClang::IsCXXClassType(class_opaque_type)) {
1097*f6aab3d8Srobert               if (class_opaque_type.IsBeingDefined()) {
1098061da546Spatrick                 if (!is_static && !die.HasChildren()) {
1099061da546Spatrick                   // We have a C++ member function with no children (this
1100061da546Spatrick                   // pointer!) and clang will get mad if we try and make
1101061da546Spatrick                   // a function that isn't well formed in the DWARF, so
1102061da546Spatrick                   // we will just skip it...
1103061da546Spatrick                   type_handled = true;
1104061da546Spatrick                 } else {
1105061da546Spatrick                   llvm::PrettyStackTraceFormat stack_trace(
1106061da546Spatrick                       "SymbolFileDWARF::ParseType() is adding a method "
1107061da546Spatrick                       "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
1108061da546Spatrick                       attrs.name.GetCString(),
1109061da546Spatrick                       class_type->GetName().GetCString(), die.GetID(),
1110*f6aab3d8Srobert                       dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str());
1111061da546Spatrick 
1112061da546Spatrick                   const bool is_attr_used = false;
1113061da546Spatrick                   // Neither GCC 4.2 nor clang++ currently set a valid
1114061da546Spatrick                   // accessibility in the DWARF for C++ methods...
1115061da546Spatrick                   // Default to public for now...
1116061da546Spatrick                   if (attrs.accessibility == eAccessNone)
1117061da546Spatrick                     attrs.accessibility = eAccessPublic;
1118061da546Spatrick 
1119061da546Spatrick                   clang::CXXMethodDecl *cxx_method_decl =
1120061da546Spatrick                       m_ast.AddMethodToCXXRecordType(
1121061da546Spatrick                           class_opaque_type.GetOpaqueQualType(),
1122061da546Spatrick                           attrs.name.GetCString(), attrs.mangled_name,
1123061da546Spatrick                           clang_type, attrs.accessibility, attrs.is_virtual,
1124061da546Spatrick                           is_static, attrs.is_inline, attrs.is_explicit,
1125061da546Spatrick                           is_attr_used, attrs.is_artificial);
1126061da546Spatrick 
1127*f6aab3d8Srobert                   type_handled = cxx_method_decl != nullptr;
1128061da546Spatrick                   // Artificial methods are always handled even when we
1129061da546Spatrick                   // don't create a new declaration for them.
1130061da546Spatrick                   type_handled |= attrs.is_artificial;
1131061da546Spatrick 
1132061da546Spatrick                   if (cxx_method_decl) {
1133061da546Spatrick                     LinkDeclContextToDIE(cxx_method_decl, die);
1134061da546Spatrick 
1135061da546Spatrick                     ClangASTMetadata metadata;
1136061da546Spatrick                     metadata.SetUserID(die.GetID());
1137061da546Spatrick 
1138061da546Spatrick                     if (!object_pointer_name.empty()) {
1139*f6aab3d8Srobert                       metadata.SetObjectPtrName(object_pointer_name.c_str());
1140061da546Spatrick                       LLDB_LOGF(log,
1141061da546Spatrick                                 "Setting object pointer name: %s on method "
1142061da546Spatrick                                 "object %p.\n",
1143061da546Spatrick                                 object_pointer_name.c_str(),
1144061da546Spatrick                                 static_cast<void *>(cxx_method_decl));
1145061da546Spatrick                     }
1146061da546Spatrick                     m_ast.SetMetadata(cxx_method_decl, metadata);
1147061da546Spatrick                   } else {
1148061da546Spatrick                     ignore_containing_context = true;
1149061da546Spatrick                   }
1150061da546Spatrick                 }
1151061da546Spatrick               } else {
1152061da546Spatrick                 // We were asked to parse the type for a method in a
1153061da546Spatrick                 // class, yet the class hasn't been asked to complete
1154061da546Spatrick                 // itself through the clang::ExternalASTSource protocol,
1155061da546Spatrick                 // so we need to just have the class complete itself and
1156061da546Spatrick                 // do things the right way, then our
1157061da546Spatrick                 // DIE should then have an entry in the
1158061da546Spatrick                 // dwarf->GetDIEToType() map. First
1159061da546Spatrick                 // we need to modify the dwarf->GetDIEToType() so it
1160061da546Spatrick                 // doesn't think we are trying to parse this DIE
1161061da546Spatrick                 // anymore...
1162061da546Spatrick                 dwarf->GetDIEToType()[die.GetDIE()] = NULL;
1163061da546Spatrick 
1164061da546Spatrick                 // Now we get the full type to force our class type to
1165061da546Spatrick                 // complete itself using the clang::ExternalASTSource
1166061da546Spatrick                 // protocol which will parse all base classes and all
1167061da546Spatrick                 // methods (including the method for this DIE).
1168061da546Spatrick                 class_type->GetFullCompilerType();
1169061da546Spatrick 
1170061da546Spatrick                 // The type for this DIE should have been filled in the
1171061da546Spatrick                 // function call above
1172061da546Spatrick                 Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1173061da546Spatrick                 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
1174061da546Spatrick                   return type_ptr->shared_from_this();
1175061da546Spatrick                 }
1176061da546Spatrick 
1177061da546Spatrick                 // FIXME This is fixing some even uglier behavior but we
1178061da546Spatrick                 // really need to
1179061da546Spatrick                 // uniq the methods of each class as well as the class
1180061da546Spatrick                 // itself. <rdar://problem/11240464>
1181061da546Spatrick                 type_handled = true;
1182061da546Spatrick               }
1183061da546Spatrick             }
1184061da546Spatrick           }
1185061da546Spatrick         }
1186061da546Spatrick       }
1187061da546Spatrick     }
1188061da546Spatrick 
1189061da546Spatrick     if (!type_handled) {
1190061da546Spatrick       clang::FunctionDecl *function_decl = nullptr;
1191061da546Spatrick       clang::FunctionDecl *template_function_decl = nullptr;
1192061da546Spatrick 
1193061da546Spatrick       if (attrs.abstract_origin.IsValid()) {
1194061da546Spatrick         DWARFDIE abs_die = attrs.abstract_origin.Reference();
1195061da546Spatrick 
1196061da546Spatrick         if (dwarf->ResolveType(abs_die)) {
1197061da546Spatrick           function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1198061da546Spatrick               GetCachedClangDeclContextForDIE(abs_die));
1199061da546Spatrick 
1200061da546Spatrick           if (function_decl) {
1201061da546Spatrick             LinkDeclContextToDIE(function_decl, die);
1202061da546Spatrick           }
1203061da546Spatrick         }
1204061da546Spatrick       }
1205061da546Spatrick 
1206061da546Spatrick       if (!function_decl) {
1207be691f3bSpatrick         char *name_buf = nullptr;
1208be691f3bSpatrick         llvm::StringRef name = attrs.name.GetStringRef();
1209dda28197Spatrick 
1210dda28197Spatrick         // We currently generate function templates with template parameters in
1211dda28197Spatrick         // their name. In order to get closer to the AST that clang generates
1212dda28197Spatrick         // we want to strip these from the name when creating the AST.
1213dda28197Spatrick         if (attrs.mangled_name) {
1214dda28197Spatrick           llvm::ItaniumPartialDemangler D;
1215be691f3bSpatrick           if (!D.partialDemangle(attrs.mangled_name)) {
1216be691f3bSpatrick             name_buf = D.getFunctionBaseName(nullptr, nullptr);
1217be691f3bSpatrick             name = name_buf;
1218be691f3bSpatrick           }
1219dda28197Spatrick         }
1220dda28197Spatrick 
1221061da546Spatrick         // We just have a function that isn't part of a class
1222061da546Spatrick         function_decl = m_ast.CreateFunctionDeclaration(
1223061da546Spatrick             ignore_containing_context ? m_ast.GetTranslationUnitDecl()
1224061da546Spatrick                                       : containing_decl_ctx,
1225dda28197Spatrick             GetOwningClangModule(die), name, clang_type, attrs.storage,
1226061da546Spatrick             attrs.is_inline);
1227be691f3bSpatrick         std::free(name_buf);
1228061da546Spatrick 
1229061da546Spatrick         if (has_template_params) {
1230dda28197Spatrick           TypeSystemClang::TemplateParameterInfos template_param_infos;
1231061da546Spatrick           ParseTemplateParameterInfos(die, template_param_infos);
1232061da546Spatrick           template_function_decl = m_ast.CreateFunctionDeclaration(
1233061da546Spatrick               ignore_containing_context ? m_ast.GetTranslationUnitDecl()
1234061da546Spatrick                                         : containing_decl_ctx,
1235be691f3bSpatrick               GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type,
1236dda28197Spatrick               attrs.storage, attrs.is_inline);
1237061da546Spatrick           clang::FunctionTemplateDecl *func_template_decl =
1238061da546Spatrick               m_ast.CreateFunctionTemplateDecl(
1239dda28197Spatrick                   containing_decl_ctx, GetOwningClangModule(die),
1240be691f3bSpatrick                   template_function_decl, template_param_infos);
1241061da546Spatrick           m_ast.CreateFunctionTemplateSpecializationInfo(
1242dda28197Spatrick               template_function_decl, func_template_decl, template_param_infos);
1243061da546Spatrick         }
1244061da546Spatrick 
1245061da546Spatrick         lldbassert(function_decl);
1246061da546Spatrick 
1247061da546Spatrick         if (function_decl) {
1248*f6aab3d8Srobert           // Attach an asm(<mangled_name>) label to the FunctionDecl.
1249*f6aab3d8Srobert           // This ensures that clang::CodeGen emits function calls
1250*f6aab3d8Srobert           // using symbols that are mangled according to the DW_AT_linkage_name.
1251*f6aab3d8Srobert           // If we didn't do this, the external symbols wouldn't exactly
1252*f6aab3d8Srobert           // match the mangled name LLDB knows about and the IRExecutionUnit
1253*f6aab3d8Srobert           // would have to fall back to searching object files for
1254*f6aab3d8Srobert           // approximately matching function names. The motivating
1255*f6aab3d8Srobert           // example is generating calls to ABI-tagged template functions.
1256*f6aab3d8Srobert           // This is done separately for member functions in
1257*f6aab3d8Srobert           // AddMethodToCXXRecordType.
1258*f6aab3d8Srobert           if (attrs.mangled_name)
1259*f6aab3d8Srobert             function_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
1260*f6aab3d8Srobert                 m_ast.getASTContext(), attrs.mangled_name, /*literal=*/false));
1261*f6aab3d8Srobert 
1262061da546Spatrick           LinkDeclContextToDIE(function_decl, die);
1263061da546Spatrick 
1264061da546Spatrick           if (!function_param_decls.empty()) {
1265be691f3bSpatrick             m_ast.SetFunctionParameters(function_decl, function_param_decls);
1266061da546Spatrick             if (template_function_decl)
1267061da546Spatrick               m_ast.SetFunctionParameters(template_function_decl,
1268be691f3bSpatrick                                           function_param_decls);
1269061da546Spatrick           }
1270061da546Spatrick 
1271061da546Spatrick           ClangASTMetadata metadata;
1272061da546Spatrick           metadata.SetUserID(die.GetID());
1273061da546Spatrick 
1274061da546Spatrick           if (!object_pointer_name.empty()) {
1275061da546Spatrick             metadata.SetObjectPtrName(object_pointer_name.c_str());
1276061da546Spatrick             LLDB_LOGF(log,
1277061da546Spatrick                       "Setting object pointer name: %s on function "
1278061da546Spatrick                       "object %p.",
1279061da546Spatrick                       object_pointer_name.c_str(),
1280061da546Spatrick                       static_cast<void *>(function_decl));
1281061da546Spatrick           }
1282061da546Spatrick           m_ast.SetMetadata(function_decl, metadata);
1283061da546Spatrick         }
1284061da546Spatrick       }
1285061da546Spatrick     }
1286061da546Spatrick   }
1287*f6aab3d8Srobert   return dwarf->MakeType(
1288*f6aab3d8Srobert       die.GetID(), attrs.name, std::nullopt, nullptr, LLDB_INVALID_UID,
1289061da546Spatrick       Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Full);
1290061da546Spatrick }
1291061da546Spatrick 
1292*f6aab3d8Srobert TypeSP
ParseArrayType(const DWARFDIE & die,const ParsedDWARFTypeAttributes & attrs)1293*f6aab3d8Srobert DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
1294*f6aab3d8Srobert                                     const ParsedDWARFTypeAttributes &attrs) {
1295061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
1296061da546Spatrick 
1297061da546Spatrick   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
1298061da546Spatrick                DW_TAG_value_to_name(tag), type_name_cstr);
1299061da546Spatrick 
1300061da546Spatrick   DWARFDIE type_die = attrs.type.Reference();
1301061da546Spatrick   Type *element_type = dwarf->ResolveTypeUID(type_die, true);
1302061da546Spatrick 
1303061da546Spatrick   if (!element_type)
1304061da546Spatrick     return nullptr;
1305061da546Spatrick 
1306*f6aab3d8Srobert   std::optional<SymbolFile::ArrayInfo> array_info = ParseChildArrayInfo(die);
1307*f6aab3d8Srobert   uint32_t byte_stride = attrs.byte_stride;
1308*f6aab3d8Srobert   uint32_t bit_stride = attrs.bit_stride;
1309061da546Spatrick   if (array_info) {
1310*f6aab3d8Srobert     byte_stride = array_info->byte_stride;
1311*f6aab3d8Srobert     bit_stride = array_info->bit_stride;
1312061da546Spatrick   }
1313*f6aab3d8Srobert   if (byte_stride == 0 && bit_stride == 0)
1314*f6aab3d8Srobert     byte_stride = element_type->GetByteSize(nullptr).value_or(0);
1315061da546Spatrick   CompilerType array_element_type = element_type->GetForwardCompilerType();
1316*f6aab3d8Srobert   TypeSystemClang::RequireCompleteType(array_element_type);
1317061da546Spatrick 
1318*f6aab3d8Srobert   uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
1319061da546Spatrick   CompilerType clang_type;
1320061da546Spatrick   if (array_info && array_info->element_orders.size() > 0) {
1321061da546Spatrick     uint64_t num_elements = 0;
1322061da546Spatrick     auto end = array_info->element_orders.rend();
1323061da546Spatrick     for (auto pos = array_info->element_orders.rbegin(); pos != end; ++pos) {
1324061da546Spatrick       num_elements = *pos;
1325061da546Spatrick       clang_type = m_ast.CreateArrayType(array_element_type, num_elements,
1326061da546Spatrick                                          attrs.is_vector);
1327061da546Spatrick       array_element_type = clang_type;
1328061da546Spatrick       array_element_bit_stride = num_elements
1329061da546Spatrick                                      ? array_element_bit_stride * num_elements
1330061da546Spatrick                                      : array_element_bit_stride;
1331061da546Spatrick     }
1332061da546Spatrick   } else {
1333061da546Spatrick     clang_type =
1334061da546Spatrick         m_ast.CreateArrayType(array_element_type, 0, attrs.is_vector);
1335061da546Spatrick   }
1336061da546Spatrick   ConstString empty_name;
1337*f6aab3d8Srobert   TypeSP type_sp =
1338*f6aab3d8Srobert       dwarf->MakeType(die.GetID(), empty_name, array_element_bit_stride / 8,
1339*f6aab3d8Srobert                       nullptr, dwarf->GetUID(type_die), Type::eEncodingIsUID,
1340*f6aab3d8Srobert                       &attrs.decl, clang_type, Type::ResolveState::Full);
1341061da546Spatrick   type_sp->SetEncodingType(element_type);
1342061da546Spatrick   const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr();
1343061da546Spatrick   m_ast.SetMetadataAsUserID(type, die.GetID());
1344061da546Spatrick   return type_sp;
1345061da546Spatrick }
1346061da546Spatrick 
ParsePointerToMemberType(const DWARFDIE & die,const ParsedDWARFTypeAttributes & attrs)1347061da546Spatrick TypeSP DWARFASTParserClang::ParsePointerToMemberType(
1348061da546Spatrick     const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) {
1349061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
1350061da546Spatrick   Type *pointee_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
1351061da546Spatrick   Type *class_type =
1352061da546Spatrick       dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
1353061da546Spatrick 
1354061da546Spatrick   CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
1355be691f3bSpatrick   CompilerType class_clang_type = class_type->GetForwardCompilerType();
1356061da546Spatrick 
1357dda28197Spatrick   CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(
1358061da546Spatrick       class_clang_type, pointee_clang_type);
1359061da546Spatrick 
1360*f6aab3d8Srobert   if (std::optional<uint64_t> clang_type_size =
1361061da546Spatrick           clang_type.GetByteSize(nullptr)) {
1362*f6aab3d8Srobert     return dwarf->MakeType(die.GetID(), attrs.name, *clang_type_size, nullptr,
1363*f6aab3d8Srobert                            LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr,
1364*f6aab3d8Srobert                            clang_type, Type::ResolveState::Forward);
1365061da546Spatrick   }
1366061da546Spatrick   return nullptr;
1367061da546Spatrick }
1368061da546Spatrick 
ParseInheritance(const DWARFDIE & die,const DWARFDIE & parent_die,const CompilerType class_clang_type,const AccessType default_accessibility,const lldb::ModuleSP & module_sp,std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> & base_classes,ClangASTImporter::LayoutInfo & layout_info)1369*f6aab3d8Srobert void DWARFASTParserClang::ParseInheritance(
1370*f6aab3d8Srobert     const DWARFDIE &die, const DWARFDIE &parent_die,
1371*f6aab3d8Srobert     const CompilerType class_clang_type, const AccessType default_accessibility,
1372*f6aab3d8Srobert     const lldb::ModuleSP &module_sp,
1373*f6aab3d8Srobert     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
1374*f6aab3d8Srobert     ClangASTImporter::LayoutInfo &layout_info) {
1375*f6aab3d8Srobert   auto ast =
1376*f6aab3d8Srobert       class_clang_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
1377*f6aab3d8Srobert   if (ast == nullptr)
1378*f6aab3d8Srobert     return;
1379*f6aab3d8Srobert 
1380*f6aab3d8Srobert   // TODO: implement DW_TAG_inheritance type parsing.
1381*f6aab3d8Srobert   DWARFAttributes attributes;
1382*f6aab3d8Srobert   const size_t num_attributes = die.GetAttributes(attributes);
1383*f6aab3d8Srobert   if (num_attributes == 0)
1384*f6aab3d8Srobert     return;
1385*f6aab3d8Srobert 
1386*f6aab3d8Srobert   DWARFFormValue encoding_form;
1387*f6aab3d8Srobert   AccessType accessibility = default_accessibility;
1388*f6aab3d8Srobert   bool is_virtual = false;
1389*f6aab3d8Srobert   bool is_base_of_class = true;
1390*f6aab3d8Srobert   off_t member_byte_offset = 0;
1391*f6aab3d8Srobert 
1392*f6aab3d8Srobert   for (uint32_t i = 0; i < num_attributes; ++i) {
1393*f6aab3d8Srobert     const dw_attr_t attr = attributes.AttributeAtIndex(i);
1394*f6aab3d8Srobert     DWARFFormValue form_value;
1395*f6aab3d8Srobert     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1396*f6aab3d8Srobert       switch (attr) {
1397*f6aab3d8Srobert       case DW_AT_type:
1398*f6aab3d8Srobert         encoding_form = form_value;
1399*f6aab3d8Srobert         break;
1400*f6aab3d8Srobert       case DW_AT_data_member_location:
1401*f6aab3d8Srobert         if (form_value.BlockData()) {
1402*f6aab3d8Srobert           Value initialValue(0);
1403*f6aab3d8Srobert           Value memberOffset(0);
1404*f6aab3d8Srobert           const DWARFDataExtractor &debug_info_data = die.GetData();
1405*f6aab3d8Srobert           uint32_t block_length = form_value.Unsigned();
1406*f6aab3d8Srobert           uint32_t block_offset =
1407*f6aab3d8Srobert               form_value.BlockData() - debug_info_data.GetDataStart();
1408*f6aab3d8Srobert           if (DWARFExpression::Evaluate(
1409*f6aab3d8Srobert                   nullptr, nullptr, module_sp,
1410*f6aab3d8Srobert                   DataExtractor(debug_info_data, block_offset, block_length),
1411*f6aab3d8Srobert                   die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
1412*f6aab3d8Srobert                   memberOffset, nullptr)) {
1413*f6aab3d8Srobert             member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
1414*f6aab3d8Srobert           }
1415*f6aab3d8Srobert         } else {
1416*f6aab3d8Srobert           // With DWARF 3 and later, if the value is an integer constant,
1417*f6aab3d8Srobert           // this form value is the offset in bytes from the beginning of
1418*f6aab3d8Srobert           // the containing entity.
1419*f6aab3d8Srobert           member_byte_offset = form_value.Unsigned();
1420*f6aab3d8Srobert         }
1421*f6aab3d8Srobert         break;
1422*f6aab3d8Srobert 
1423*f6aab3d8Srobert       case DW_AT_accessibility:
1424*f6aab3d8Srobert         accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());
1425*f6aab3d8Srobert         break;
1426*f6aab3d8Srobert 
1427*f6aab3d8Srobert       case DW_AT_virtuality:
1428*f6aab3d8Srobert         is_virtual = form_value.Boolean();
1429*f6aab3d8Srobert         break;
1430*f6aab3d8Srobert 
1431*f6aab3d8Srobert       default:
1432*f6aab3d8Srobert         break;
1433*f6aab3d8Srobert       }
1434*f6aab3d8Srobert     }
1435*f6aab3d8Srobert   }
1436*f6aab3d8Srobert 
1437*f6aab3d8Srobert   Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());
1438*f6aab3d8Srobert   if (base_class_type == nullptr) {
1439*f6aab3d8Srobert     module_sp->ReportError("{0:x16}: DW_TAG_inheritance failed to "
1440*f6aab3d8Srobert                            "resolve the base class at {1:x16}"
1441*f6aab3d8Srobert                            " from enclosing type {2:x16}. \nPlease file "
1442*f6aab3d8Srobert                            "a bug and attach the file at the start of "
1443*f6aab3d8Srobert                            "this error message",
1444*f6aab3d8Srobert                            die.GetOffset(),
1445*f6aab3d8Srobert                            encoding_form.Reference().GetOffset(),
1446*f6aab3d8Srobert                            parent_die.GetOffset());
1447*f6aab3d8Srobert     return;
1448*f6aab3d8Srobert   }
1449*f6aab3d8Srobert 
1450*f6aab3d8Srobert   CompilerType base_class_clang_type = base_class_type->GetFullCompilerType();
1451*f6aab3d8Srobert   assert(base_class_clang_type);
1452*f6aab3d8Srobert   if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) {
1453*f6aab3d8Srobert     ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
1454*f6aab3d8Srobert     return;
1455*f6aab3d8Srobert   }
1456*f6aab3d8Srobert   std::unique_ptr<clang::CXXBaseSpecifier> result =
1457*f6aab3d8Srobert       ast->CreateBaseClassSpecifier(base_class_clang_type.GetOpaqueQualType(),
1458*f6aab3d8Srobert                                     accessibility, is_virtual,
1459*f6aab3d8Srobert                                     is_base_of_class);
1460*f6aab3d8Srobert   if (!result)
1461*f6aab3d8Srobert     return;
1462*f6aab3d8Srobert 
1463*f6aab3d8Srobert   base_classes.push_back(std::move(result));
1464*f6aab3d8Srobert 
1465*f6aab3d8Srobert   if (is_virtual) {
1466*f6aab3d8Srobert     // Do not specify any offset for virtual inheritance. The DWARF
1467*f6aab3d8Srobert     // produced by clang doesn't give us a constant offset, but gives
1468*f6aab3d8Srobert     // us a DWARF expressions that requires an actual object in memory.
1469*f6aab3d8Srobert     // the DW_AT_data_member_location for a virtual base class looks
1470*f6aab3d8Srobert     // like:
1471*f6aab3d8Srobert     //      DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
1472*f6aab3d8Srobert     //      DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
1473*f6aab3d8Srobert     //      DW_OP_plus )
1474*f6aab3d8Srobert     // Given this, there is really no valid response we can give to
1475*f6aab3d8Srobert     // clang for virtual base class offsets, and this should eventually
1476*f6aab3d8Srobert     // be removed from LayoutRecordType() in the external
1477*f6aab3d8Srobert     // AST source in clang.
1478*f6aab3d8Srobert   } else {
1479*f6aab3d8Srobert     layout_info.base_offsets.insert(std::make_pair(
1480*f6aab3d8Srobert         ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
1481*f6aab3d8Srobert         clang::CharUnits::fromQuantity(member_byte_offset)));
1482*f6aab3d8Srobert   }
1483*f6aab3d8Srobert }
1484*f6aab3d8Srobert 
UpdateSymbolContextScopeForType(const SymbolContext & sc,const DWARFDIE & die,TypeSP type_sp)1485061da546Spatrick TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
1486061da546Spatrick     const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
1487061da546Spatrick   if (!type_sp)
1488061da546Spatrick     return type_sp;
1489061da546Spatrick 
1490061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
1491061da546Spatrick   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
1492061da546Spatrick   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
1493061da546Spatrick 
1494061da546Spatrick   SymbolContextScope *symbol_context_scope = nullptr;
1495061da546Spatrick   if (sc_parent_tag == DW_TAG_compile_unit ||
1496061da546Spatrick       sc_parent_tag == DW_TAG_partial_unit) {
1497061da546Spatrick     symbol_context_scope = sc.comp_unit;
1498061da546Spatrick   } else if (sc.function != nullptr && sc_parent_die) {
1499061da546Spatrick     symbol_context_scope =
1500061da546Spatrick         sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
1501061da546Spatrick     if (symbol_context_scope == nullptr)
1502061da546Spatrick       symbol_context_scope = sc.function;
1503061da546Spatrick   } else {
1504061da546Spatrick     symbol_context_scope = sc.module_sp.get();
1505061da546Spatrick   }
1506061da546Spatrick 
1507061da546Spatrick   if (symbol_context_scope != nullptr)
1508061da546Spatrick     type_sp->SetSymbolContextScope(symbol_context_scope);
1509061da546Spatrick 
1510061da546Spatrick   dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1511061da546Spatrick   return type_sp;
1512061da546Spatrick }
1513061da546Spatrick 
1514*f6aab3d8Srobert std::string
GetCPlusPlusQualifiedName(const DWARFDIE & die)1515*f6aab3d8Srobert DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
1516*f6aab3d8Srobert   if (!die.IsValid())
1517*f6aab3d8Srobert     return "";
1518*f6aab3d8Srobert   const char *name = die.GetName();
1519*f6aab3d8Srobert   if (!name)
1520*f6aab3d8Srobert     return "";
1521*f6aab3d8Srobert   std::string qualified_name;
1522*f6aab3d8Srobert   DWARFDIE parent_decl_ctx_die = die.GetParentDeclContextDIE();
1523*f6aab3d8Srobert   // TODO: change this to get the correct decl context parent....
1524*f6aab3d8Srobert   while (parent_decl_ctx_die) {
1525*f6aab3d8Srobert     // The name may not contain template parameters due to
1526*f6aab3d8Srobert     // -gsimple-template-names; we must reconstruct the full name from child
1527*f6aab3d8Srobert     // template parameter dies via GetDIEClassTemplateParams().
1528*f6aab3d8Srobert     const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
1529*f6aab3d8Srobert     switch (parent_tag) {
1530*f6aab3d8Srobert     case DW_TAG_namespace: {
1531*f6aab3d8Srobert       if (const char *namespace_name = parent_decl_ctx_die.GetName()) {
1532*f6aab3d8Srobert         qualified_name.insert(0, "::");
1533*f6aab3d8Srobert         qualified_name.insert(0, namespace_name);
1534*f6aab3d8Srobert       } else {
1535*f6aab3d8Srobert         qualified_name.insert(0, "(anonymous namespace)::");
1536*f6aab3d8Srobert       }
1537*f6aab3d8Srobert       parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1538*f6aab3d8Srobert       break;
1539*f6aab3d8Srobert     }
1540*f6aab3d8Srobert 
1541*f6aab3d8Srobert     case DW_TAG_class_type:
1542*f6aab3d8Srobert     case DW_TAG_structure_type:
1543*f6aab3d8Srobert     case DW_TAG_union_type: {
1544*f6aab3d8Srobert       if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) {
1545*f6aab3d8Srobert         qualified_name.insert(
1546*f6aab3d8Srobert             0, GetDIEClassTemplateParams(parent_decl_ctx_die).AsCString(""));
1547*f6aab3d8Srobert         qualified_name.insert(0, "::");
1548*f6aab3d8Srobert         qualified_name.insert(0, class_union_struct_name);
1549*f6aab3d8Srobert       }
1550*f6aab3d8Srobert       parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
1551*f6aab3d8Srobert       break;
1552*f6aab3d8Srobert     }
1553*f6aab3d8Srobert 
1554*f6aab3d8Srobert     default:
1555*f6aab3d8Srobert       parent_decl_ctx_die.Clear();
1556*f6aab3d8Srobert       break;
1557*f6aab3d8Srobert     }
1558*f6aab3d8Srobert   }
1559*f6aab3d8Srobert 
1560*f6aab3d8Srobert   if (qualified_name.empty())
1561*f6aab3d8Srobert     qualified_name.append("::");
1562*f6aab3d8Srobert 
1563*f6aab3d8Srobert   qualified_name.append(name);
1564*f6aab3d8Srobert   qualified_name.append(GetDIEClassTemplateParams(die).AsCString(""));
1565*f6aab3d8Srobert 
1566*f6aab3d8Srobert   return qualified_name;
1567*f6aab3d8Srobert }
1568*f6aab3d8Srobert 
1569061da546Spatrick TypeSP
ParseStructureLikeDIE(const SymbolContext & sc,const DWARFDIE & die,ParsedDWARFTypeAttributes & attrs)1570061da546Spatrick DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
1571061da546Spatrick                                            const DWARFDIE &die,
1572061da546Spatrick                                            ParsedDWARFTypeAttributes &attrs) {
1573061da546Spatrick   TypeSP type_sp;
1574061da546Spatrick   CompilerType clang_type;
1575061da546Spatrick   const dw_tag_t tag = die.Tag();
1576061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
1577dda28197Spatrick   LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
1578*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
1579061da546Spatrick 
1580061da546Spatrick   // UniqueDWARFASTType is large, so don't create a local variables on the
1581061da546Spatrick   // stack, put it on the heap. This function is often called recursively and
1582061da546Spatrick   // clang isn't good at sharing the stack space for variables in different
1583061da546Spatrick   // blocks.
1584061da546Spatrick   auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
1585061da546Spatrick 
1586061da546Spatrick   ConstString unique_typename(attrs.name);
1587061da546Spatrick   Declaration unique_decl(attrs.decl);
1588061da546Spatrick 
1589061da546Spatrick   if (attrs.name) {
1590061da546Spatrick     if (Language::LanguageIsCPlusPlus(cu_language)) {
1591061da546Spatrick       // For C++, we rely solely upon the one definition rule that says
1592061da546Spatrick       // only one thing can exist at a given decl context. We ignore the
1593061da546Spatrick       // file and line that things are declared on.
1594*f6aab3d8Srobert       std::string qualified_name = GetCPlusPlusQualifiedName(die);
1595*f6aab3d8Srobert       if (!qualified_name.empty())
1596061da546Spatrick         unique_typename = ConstString(qualified_name);
1597061da546Spatrick       unique_decl.Clear();
1598061da546Spatrick     }
1599061da546Spatrick 
1600061da546Spatrick     if (dwarf->GetUniqueDWARFASTTypeMap().Find(
1601*f6aab3d8Srobert             unique_typename, die, unique_decl, attrs.byte_size.value_or(-1),
1602061da546Spatrick             *unique_ast_entry_up)) {
1603061da546Spatrick       type_sp = unique_ast_entry_up->m_type_sp;
1604061da546Spatrick       if (type_sp) {
1605061da546Spatrick         dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1606061da546Spatrick         LinkDeclContextToDIE(
1607061da546Spatrick             GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
1608061da546Spatrick         return type_sp;
1609061da546Spatrick       }
1610061da546Spatrick     }
1611061da546Spatrick   }
1612061da546Spatrick 
1613061da546Spatrick   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
1614061da546Spatrick                DW_TAG_value_to_name(tag), type_name_cstr);
1615061da546Spatrick 
1616061da546Spatrick   int tag_decl_kind = -1;
1617061da546Spatrick   AccessType default_accessibility = eAccessNone;
1618061da546Spatrick   if (tag == DW_TAG_structure_type) {
1619061da546Spatrick     tag_decl_kind = clang::TTK_Struct;
1620061da546Spatrick     default_accessibility = eAccessPublic;
1621061da546Spatrick   } else if (tag == DW_TAG_union_type) {
1622061da546Spatrick     tag_decl_kind = clang::TTK_Union;
1623061da546Spatrick     default_accessibility = eAccessPublic;
1624061da546Spatrick   } else if (tag == DW_TAG_class_type) {
1625061da546Spatrick     tag_decl_kind = clang::TTK_Class;
1626061da546Spatrick     default_accessibility = eAccessPrivate;
1627061da546Spatrick   }
1628061da546Spatrick 
1629061da546Spatrick   if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
1630061da546Spatrick       !die.HasChildren() && cu_language == eLanguageTypeObjC) {
1631061da546Spatrick     // Work around an issue with clang at the moment where forward
1632061da546Spatrick     // declarations for objective C classes are emitted as:
1633061da546Spatrick     //  DW_TAG_structure_type [2]
1634061da546Spatrick     //  DW_AT_name( "ForwardObjcClass" )
1635061da546Spatrick     //  DW_AT_byte_size( 0x00 )
1636061da546Spatrick     //  DW_AT_decl_file( "..." )
1637061da546Spatrick     //  DW_AT_decl_line( 1 )
1638061da546Spatrick     //
1639061da546Spatrick     // Note that there is no DW_AT_declaration and there are no children,
1640061da546Spatrick     // and the byte size is zero.
1641061da546Spatrick     attrs.is_forward_declaration = true;
1642061da546Spatrick   }
1643061da546Spatrick 
1644061da546Spatrick   if (attrs.class_language == eLanguageTypeObjC ||
1645061da546Spatrick       attrs.class_language == eLanguageTypeObjC_plus_plus) {
1646061da546Spatrick     if (!attrs.is_complete_objc_class &&
1647061da546Spatrick         die.Supports_DW_AT_APPLE_objc_complete_type()) {
1648061da546Spatrick       // We have a valid eSymbolTypeObjCClass class symbol whose name
1649061da546Spatrick       // matches the current objective C class that we are trying to find
1650061da546Spatrick       // and this DIE isn't the complete definition (we checked
1651061da546Spatrick       // is_complete_objc_class above and know it is false), so the real
1652061da546Spatrick       // definition is in here somewhere
1653061da546Spatrick       type_sp =
1654061da546Spatrick           dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
1655061da546Spatrick 
1656061da546Spatrick       if (!type_sp) {
1657061da546Spatrick         SymbolFileDWARFDebugMap *debug_map_symfile =
1658061da546Spatrick             dwarf->GetDebugMapSymfile();
1659061da546Spatrick         if (debug_map_symfile) {
1660061da546Spatrick           // We weren't able to find a full declaration in this DWARF,
1661061da546Spatrick           // see if we have a declaration anywhere else...
1662061da546Spatrick           type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
1663061da546Spatrick               die, attrs.name, true);
1664061da546Spatrick         }
1665061da546Spatrick       }
1666061da546Spatrick 
1667061da546Spatrick       if (type_sp) {
1668061da546Spatrick         if (log) {
1669061da546Spatrick           dwarf->GetObjectFile()->GetModule()->LogMessage(
1670061da546Spatrick               log,
1671*f6aab3d8Srobert               "SymbolFileDWARF({0:p}) - {1:x16}: {2} type "
1672*f6aab3d8Srobert               "\"{3}\" is an "
1673*f6aab3d8Srobert               "incomplete objc type, complete type is {4:x8}",
1674061da546Spatrick               static_cast<void *>(this), die.GetOffset(),
1675061da546Spatrick               DW_TAG_value_to_name(tag), attrs.name.GetCString(),
1676061da546Spatrick               type_sp->GetID());
1677061da546Spatrick         }
1678061da546Spatrick 
1679061da546Spatrick         // We found a real definition for this type elsewhere so lets use
1680061da546Spatrick         // it and cache the fact that we found a complete type for this
1681061da546Spatrick         // die
1682061da546Spatrick         dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1683061da546Spatrick         return type_sp;
1684061da546Spatrick       }
1685061da546Spatrick     }
1686061da546Spatrick   }
1687061da546Spatrick 
1688061da546Spatrick   if (attrs.is_forward_declaration) {
1689061da546Spatrick     // We have a forward declaration to a type and we need to try and
1690061da546Spatrick     // find a full declaration. We look in the current type index just in
1691061da546Spatrick     // case we have a forward declaration followed by an actual
1692061da546Spatrick     // declarations in the DWARF. If this fails, we need to look
1693061da546Spatrick     // elsewhere...
1694061da546Spatrick     if (log) {
1695061da546Spatrick       dwarf->GetObjectFile()->GetModule()->LogMessage(
1696061da546Spatrick           log,
1697*f6aab3d8Srobert           "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
1698061da546Spatrick           "forward declaration, trying to find complete type",
1699061da546Spatrick           static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
1700061da546Spatrick           attrs.name.GetCString());
1701061da546Spatrick     }
1702061da546Spatrick 
1703061da546Spatrick     // See if the type comes from a Clang module and if so, track down
1704061da546Spatrick     // that type.
1705061da546Spatrick     type_sp = ParseTypeFromClangModule(sc, die, log);
1706061da546Spatrick     if (type_sp)
1707061da546Spatrick       return type_sp;
1708061da546Spatrick 
1709061da546Spatrick     // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
1710061da546Spatrick     // type_name_const_str);
1711*f6aab3d8Srobert     type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die);
1712061da546Spatrick 
1713061da546Spatrick     if (!type_sp) {
1714061da546Spatrick       SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
1715061da546Spatrick       if (debug_map_symfile) {
1716061da546Spatrick         // We weren't able to find a full declaration in this DWARF, see
1717061da546Spatrick         // if we have a declaration anywhere else...
1718*f6aab3d8Srobert         type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
1719061da546Spatrick       }
1720061da546Spatrick     }
1721061da546Spatrick 
1722061da546Spatrick     if (type_sp) {
1723061da546Spatrick       if (log) {
1724061da546Spatrick         dwarf->GetObjectFile()->GetModule()->LogMessage(
1725061da546Spatrick             log,
1726*f6aab3d8Srobert             "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
1727*f6aab3d8Srobert             "forward declaration, complete type is {4:x8}",
1728061da546Spatrick             static_cast<void *>(this), die.GetOffset(),
1729061da546Spatrick             DW_TAG_value_to_name(tag), attrs.name.GetCString(),
1730061da546Spatrick             type_sp->GetID());
1731061da546Spatrick       }
1732061da546Spatrick 
1733061da546Spatrick       // We found a real definition for this type elsewhere so lets use
1734061da546Spatrick       // it and cache the fact that we found a complete type for this die
1735061da546Spatrick       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1736061da546Spatrick       clang::DeclContext *defn_decl_ctx =
1737061da546Spatrick           GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
1738061da546Spatrick       if (defn_decl_ctx)
1739061da546Spatrick         LinkDeclContextToDIE(defn_decl_ctx, die);
1740061da546Spatrick       return type_sp;
1741061da546Spatrick     }
1742061da546Spatrick   }
1743061da546Spatrick   assert(tag_decl_kind != -1);
1744*f6aab3d8Srobert   (void)tag_decl_kind;
1745061da546Spatrick   bool clang_type_was_created = false;
1746*f6aab3d8Srobert   clang_type =
1747*f6aab3d8Srobert       CompilerType(m_ast.weak_from_this(),
1748*f6aab3d8Srobert                    dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
1749061da546Spatrick   if (!clang_type) {
1750061da546Spatrick     clang::DeclContext *decl_ctx =
1751061da546Spatrick         GetClangDeclContextContainingDIE(die, nullptr);
1752061da546Spatrick 
1753be691f3bSpatrick     PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx, die,
1754061da546Spatrick                                    attrs.name.GetCString());
1755061da546Spatrick 
1756061da546Spatrick     if (attrs.accessibility == eAccessNone && decl_ctx) {
1757061da546Spatrick       // Check the decl context that contains this class/struct/union. If
1758061da546Spatrick       // it is a class we must give it an accessibility.
1759061da546Spatrick       const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
1760061da546Spatrick       if (DeclKindIsCXXClass(containing_decl_kind))
1761061da546Spatrick         attrs.accessibility = default_accessibility;
1762061da546Spatrick     }
1763061da546Spatrick 
1764061da546Spatrick     ClangASTMetadata metadata;
1765061da546Spatrick     metadata.SetUserID(die.GetID());
1766061da546Spatrick     metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
1767061da546Spatrick 
1768dda28197Spatrick     TypeSystemClang::TemplateParameterInfos template_param_infos;
1769061da546Spatrick     if (ParseTemplateParameterInfos(die, template_param_infos)) {
1770061da546Spatrick       clang::ClassTemplateDecl *class_template_decl =
1771dda28197Spatrick           m_ast.ParseClassTemplateDecl(
1772dda28197Spatrick               decl_ctx, GetOwningClangModule(die), attrs.accessibility,
1773dda28197Spatrick               attrs.name.GetCString(), tag_decl_kind, template_param_infos);
1774061da546Spatrick       if (!class_template_decl) {
1775061da546Spatrick         if (log) {
1776061da546Spatrick           dwarf->GetObjectFile()->GetModule()->LogMessage(
1777061da546Spatrick               log,
1778*f6aab3d8Srobert               "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" "
1779061da546Spatrick               "clang::ClassTemplateDecl failed to return a decl.",
1780061da546Spatrick               static_cast<void *>(this), die.GetOffset(),
1781061da546Spatrick               DW_TAG_value_to_name(tag), attrs.name.GetCString());
1782061da546Spatrick         }
1783061da546Spatrick         return TypeSP();
1784061da546Spatrick       }
1785061da546Spatrick 
1786061da546Spatrick       clang::ClassTemplateSpecializationDecl *class_specialization_decl =
1787061da546Spatrick           m_ast.CreateClassTemplateSpecializationDecl(
1788dda28197Spatrick               decl_ctx, GetOwningClangModule(die), class_template_decl,
1789dda28197Spatrick               tag_decl_kind, template_param_infos);
1790061da546Spatrick       clang_type = m_ast.CreateClassTemplateSpecializationType(
1791061da546Spatrick           class_specialization_decl);
1792061da546Spatrick       clang_type_was_created = true;
1793061da546Spatrick 
1794061da546Spatrick       m_ast.SetMetadata(class_template_decl, metadata);
1795061da546Spatrick       m_ast.SetMetadata(class_specialization_decl, metadata);
1796061da546Spatrick     }
1797061da546Spatrick 
1798061da546Spatrick     if (!clang_type_was_created) {
1799061da546Spatrick       clang_type_was_created = true;
1800061da546Spatrick       clang_type = m_ast.CreateRecordType(
1801dda28197Spatrick           decl_ctx, GetOwningClangModule(die), attrs.accessibility,
1802dda28197Spatrick           attrs.name.GetCString(), tag_decl_kind, attrs.class_language,
1803dda28197Spatrick           &metadata, attrs.exports_symbols);
1804061da546Spatrick     }
1805061da546Spatrick   }
1806061da546Spatrick 
1807061da546Spatrick   // Store a forward declaration to this class type in case any
1808061da546Spatrick   // parameters in any class methods need it for the clang types for
1809061da546Spatrick   // function prototypes.
1810061da546Spatrick   LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
1811*f6aab3d8Srobert   type_sp = dwarf->MakeType(
1812*f6aab3d8Srobert       die.GetID(), attrs.name, attrs.byte_size, nullptr, LLDB_INVALID_UID,
1813*f6aab3d8Srobert       Type::eEncodingIsUID, &attrs.decl, clang_type,
1814dda28197Spatrick       Type::ResolveState::Forward,
1815dda28197Spatrick       TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class));
1816061da546Spatrick 
1817061da546Spatrick   // Add our type to the unique type map so we don't end up creating many
1818061da546Spatrick   // copies of the same type over and over in the ASTContext for our
1819061da546Spatrick   // module
1820061da546Spatrick   unique_ast_entry_up->m_type_sp = type_sp;
1821061da546Spatrick   unique_ast_entry_up->m_die = die;
1822061da546Spatrick   unique_ast_entry_up->m_declaration = unique_decl;
1823*f6aab3d8Srobert   unique_ast_entry_up->m_byte_size = attrs.byte_size.value_or(0);
1824061da546Spatrick   dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
1825061da546Spatrick                                            *unique_ast_entry_up);
1826061da546Spatrick 
1827061da546Spatrick   if (!attrs.is_forward_declaration) {
1828061da546Spatrick     // Always start the definition for a class type so that if the class
1829061da546Spatrick     // has child classes or types that require the class to be created
1830061da546Spatrick     // for use as their decl contexts the class will be ready to accept
1831061da546Spatrick     // these child definitions.
1832061da546Spatrick     if (!die.HasChildren()) {
1833061da546Spatrick       // No children for this struct/union/class, lets finish it
1834dda28197Spatrick       if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
1835dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
1836061da546Spatrick       } else {
1837061da546Spatrick         dwarf->GetObjectFile()->GetModule()->ReportError(
1838*f6aab3d8Srobert 
1839*f6aab3d8Srobert             "DWARF DIE at {0:x16} named \"{1}\" was not able to start "
1840*f6aab3d8Srobert             "its "
1841061da546Spatrick             "definition.\nPlease file a bug and attach the file at the "
1842061da546Spatrick             "start of this error message",
1843061da546Spatrick             die.GetOffset(), attrs.name.GetCString());
1844061da546Spatrick       }
1845061da546Spatrick 
1846be691f3bSpatrick       // If the byte size of the record is specified then overwrite the size
1847be691f3bSpatrick       // that would be computed by Clang. This is only needed as LLDB's
1848be691f3bSpatrick       // TypeSystemClang is always in C++ mode, but some compilers such as
1849be691f3bSpatrick       // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
1850be691f3bSpatrick       // the size of 1 for empty structs that would be computed in C++ mode).
1851be691f3bSpatrick       if (attrs.byte_size) {
1852061da546Spatrick         clang::RecordDecl *record_decl =
1853dda28197Spatrick             TypeSystemClang::GetAsRecordDecl(clang_type);
1854061da546Spatrick         if (record_decl) {
1855be691f3bSpatrick           ClangASTImporter::LayoutInfo layout;
1856be691f3bSpatrick           layout.bit_size = *attrs.byte_size * 8;
1857be691f3bSpatrick           GetClangASTImporter().SetRecordLayout(record_decl, layout);
1858061da546Spatrick         }
1859061da546Spatrick       }
1860061da546Spatrick     } else if (clang_type_was_created) {
1861061da546Spatrick       // Start the definition if the class is not objective C since the
1862061da546Spatrick       // underlying decls respond to isCompleteDefinition(). Objective
1863061da546Spatrick       // C decls don't respond to isCompleteDefinition() so we can't
1864061da546Spatrick       // start the declaration definition right away. For C++
1865061da546Spatrick       // class/union/structs we want to start the definition in case the
1866061da546Spatrick       // class is needed as the declaration context for a contained class
1867061da546Spatrick       // or type without the need to complete that type..
1868061da546Spatrick 
1869061da546Spatrick       if (attrs.class_language != eLanguageTypeObjC &&
1870061da546Spatrick           attrs.class_language != eLanguageTypeObjC_plus_plus)
1871dda28197Spatrick         TypeSystemClang::StartTagDeclarationDefinition(clang_type);
1872061da546Spatrick 
1873061da546Spatrick       // Leave this as a forward declaration until we need to know the
1874061da546Spatrick       // details of the type. lldb_private::Type will automatically call
1875061da546Spatrick       // the SymbolFile virtual function
1876061da546Spatrick       // "SymbolFileDWARF::CompleteType(Type *)" When the definition
1877061da546Spatrick       // needs to be defined.
1878061da546Spatrick       assert(!dwarf->GetForwardDeclClangTypeToDie().count(
1879061da546Spatrick                  ClangUtil::RemoveFastQualifiers(clang_type)
1880061da546Spatrick                      .GetOpaqueQualType()) &&
1881061da546Spatrick              "Type already in the forward declaration map!");
1882061da546Spatrick       // Can't assume m_ast.GetSymbolFile() is actually a
1883061da546Spatrick       // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
1884061da546Spatrick       // binaries.
1885061da546Spatrick       dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
1886061da546Spatrick           clang_type.GetOpaqueQualType();
1887dda28197Spatrick       dwarf->GetForwardDeclClangTypeToDie().try_emplace(
1888dda28197Spatrick           ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
1889dda28197Spatrick           *die.GetDIERef());
1890061da546Spatrick       m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
1891061da546Spatrick     }
1892061da546Spatrick   }
1893061da546Spatrick 
1894061da546Spatrick   // If we made a clang type, set the trivial abi if applicable: We only
1895061da546Spatrick   // do this for pass by value - which implies the Trivial ABI. There
1896061da546Spatrick   // isn't a way to assert that something that would normally be pass by
1897061da546Spatrick   // value is pass by reference, so we ignore that attribute if set.
1898061da546Spatrick   if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
1899061da546Spatrick     clang::CXXRecordDecl *record_decl =
1900061da546Spatrick         m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
1901061da546Spatrick     if (record_decl && record_decl->getDefinition()) {
1902061da546Spatrick       record_decl->setHasTrivialSpecialMemberForCall();
1903061da546Spatrick     }
1904061da546Spatrick   }
1905061da546Spatrick 
1906061da546Spatrick   if (attrs.calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
1907061da546Spatrick     clang::CXXRecordDecl *record_decl =
1908061da546Spatrick         m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
1909061da546Spatrick     if (record_decl)
1910061da546Spatrick       record_decl->setArgPassingRestrictions(
1911061da546Spatrick           clang::RecordDecl::APK_CannotPassInRegs);
1912061da546Spatrick   }
1913061da546Spatrick   return type_sp;
1914061da546Spatrick }
1915061da546Spatrick 
1916061da546Spatrick // DWARF parsing functions
1917061da546Spatrick 
1918061da546Spatrick class DWARFASTParserClang::DelayedAddObjCClassProperty {
1919061da546Spatrick public:
DelayedAddObjCClassProperty(const CompilerType & class_opaque_type,const char * property_name,const CompilerType & property_opaque_type,const char * property_setter_name,const char * property_getter_name,uint32_t property_attributes,const ClangASTMetadata * metadata)1920061da546Spatrick   DelayedAddObjCClassProperty(
1921061da546Spatrick       const CompilerType &class_opaque_type, const char *property_name,
1922061da546Spatrick       const CompilerType &property_opaque_type, // The property type is only
1923061da546Spatrick                                                 // required if you don't have an
1924061da546Spatrick                                                 // ivar decl
1925*f6aab3d8Srobert       const char *property_setter_name, const char *property_getter_name,
1926*f6aab3d8Srobert       uint32_t property_attributes, const ClangASTMetadata *metadata)
1927061da546Spatrick       : m_class_opaque_type(class_opaque_type), m_property_name(property_name),
1928*f6aab3d8Srobert         m_property_opaque_type(property_opaque_type),
1929061da546Spatrick         m_property_setter_name(property_setter_name),
1930061da546Spatrick         m_property_getter_name(property_getter_name),
1931061da546Spatrick         m_property_attributes(property_attributes) {
1932061da546Spatrick     if (metadata != nullptr) {
1933dda28197Spatrick       m_metadata_up = std::make_unique<ClangASTMetadata>();
1934061da546Spatrick       *m_metadata_up = *metadata;
1935061da546Spatrick     }
1936061da546Spatrick   }
1937061da546Spatrick 
DelayedAddObjCClassProperty(const DelayedAddObjCClassProperty & rhs)1938061da546Spatrick   DelayedAddObjCClassProperty(const DelayedAddObjCClassProperty &rhs) {
1939061da546Spatrick     *this = rhs;
1940061da546Spatrick   }
1941061da546Spatrick 
1942061da546Spatrick   DelayedAddObjCClassProperty &
operator =(const DelayedAddObjCClassProperty & rhs)1943061da546Spatrick   operator=(const DelayedAddObjCClassProperty &rhs) {
1944061da546Spatrick     m_class_opaque_type = rhs.m_class_opaque_type;
1945061da546Spatrick     m_property_name = rhs.m_property_name;
1946061da546Spatrick     m_property_opaque_type = rhs.m_property_opaque_type;
1947061da546Spatrick     m_property_setter_name = rhs.m_property_setter_name;
1948061da546Spatrick     m_property_getter_name = rhs.m_property_getter_name;
1949061da546Spatrick     m_property_attributes = rhs.m_property_attributes;
1950061da546Spatrick 
1951061da546Spatrick     if (rhs.m_metadata_up) {
1952dda28197Spatrick       m_metadata_up = std::make_unique<ClangASTMetadata>();
1953061da546Spatrick       *m_metadata_up = *rhs.m_metadata_up;
1954061da546Spatrick     }
1955061da546Spatrick     return *this;
1956061da546Spatrick   }
1957061da546Spatrick 
Finalize()1958061da546Spatrick   bool Finalize() {
1959dda28197Spatrick     return TypeSystemClang::AddObjCClassProperty(
1960061da546Spatrick         m_class_opaque_type, m_property_name, m_property_opaque_type,
1961*f6aab3d8Srobert         /*ivar_decl=*/nullptr, m_property_setter_name, m_property_getter_name,
1962061da546Spatrick         m_property_attributes, m_metadata_up.get());
1963061da546Spatrick   }
1964061da546Spatrick 
1965061da546Spatrick private:
1966061da546Spatrick   CompilerType m_class_opaque_type;
1967061da546Spatrick   const char *m_property_name;
1968061da546Spatrick   CompilerType m_property_opaque_type;
1969061da546Spatrick   const char *m_property_setter_name;
1970061da546Spatrick   const char *m_property_getter_name;
1971061da546Spatrick   uint32_t m_property_attributes;
1972061da546Spatrick   std::unique_ptr<ClangASTMetadata> m_metadata_up;
1973061da546Spatrick };
1974061da546Spatrick 
ParseTemplateDIE(const DWARFDIE & die,TypeSystemClang::TemplateParameterInfos & template_param_infos)1975061da546Spatrick bool DWARFASTParserClang::ParseTemplateDIE(
1976061da546Spatrick     const DWARFDIE &die,
1977dda28197Spatrick     TypeSystemClang::TemplateParameterInfos &template_param_infos) {
1978061da546Spatrick   const dw_tag_t tag = die.Tag();
1979061da546Spatrick   bool is_template_template_argument = false;
1980061da546Spatrick 
1981061da546Spatrick   switch (tag) {
1982061da546Spatrick   case DW_TAG_GNU_template_parameter_pack: {
1983dda28197Spatrick     template_param_infos.packed_args =
1984dda28197Spatrick         std::make_unique<TypeSystemClang::TemplateParameterInfos>();
1985be691f3bSpatrick     for (DWARFDIE child_die : die.children()) {
1986061da546Spatrick       if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
1987061da546Spatrick         return false;
1988061da546Spatrick     }
1989061da546Spatrick     if (const char *name = die.GetName()) {
1990061da546Spatrick       template_param_infos.pack_name = name;
1991061da546Spatrick     }
1992061da546Spatrick     return true;
1993061da546Spatrick   }
1994061da546Spatrick   case DW_TAG_GNU_template_template_param:
1995061da546Spatrick     is_template_template_argument = true;
1996*f6aab3d8Srobert     [[fallthrough]];
1997061da546Spatrick   case DW_TAG_template_type_parameter:
1998061da546Spatrick   case DW_TAG_template_value_parameter: {
1999061da546Spatrick     DWARFAttributes attributes;
2000061da546Spatrick     const size_t num_attributes = die.GetAttributes(attributes);
2001061da546Spatrick     const char *name = nullptr;
2002061da546Spatrick     const char *template_name = nullptr;
2003061da546Spatrick     CompilerType clang_type;
2004061da546Spatrick     uint64_t uval64 = 0;
2005061da546Spatrick     bool uval64_valid = false;
2006061da546Spatrick     if (num_attributes > 0) {
2007061da546Spatrick       DWARFFormValue form_value;
2008061da546Spatrick       for (size_t i = 0; i < num_attributes; ++i) {
2009061da546Spatrick         const dw_attr_t attr = attributes.AttributeAtIndex(i);
2010061da546Spatrick 
2011061da546Spatrick         switch (attr) {
2012061da546Spatrick         case DW_AT_name:
2013061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value))
2014061da546Spatrick             name = form_value.AsCString();
2015061da546Spatrick           break;
2016061da546Spatrick 
2017061da546Spatrick         case DW_AT_GNU_template_name:
2018061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value))
2019061da546Spatrick             template_name = form_value.AsCString();
2020061da546Spatrick           break;
2021061da546Spatrick 
2022061da546Spatrick         case DW_AT_type:
2023061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2024061da546Spatrick             Type *lldb_type = die.ResolveTypeUID(form_value.Reference());
2025061da546Spatrick             if (lldb_type)
2026061da546Spatrick               clang_type = lldb_type->GetForwardCompilerType();
2027061da546Spatrick           }
2028061da546Spatrick           break;
2029061da546Spatrick 
2030061da546Spatrick         case DW_AT_const_value:
2031061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2032061da546Spatrick             uval64_valid = true;
2033061da546Spatrick             uval64 = form_value.Unsigned();
2034061da546Spatrick           }
2035061da546Spatrick           break;
2036061da546Spatrick         default:
2037061da546Spatrick           break;
2038061da546Spatrick         }
2039061da546Spatrick       }
2040061da546Spatrick 
2041061da546Spatrick       clang::ASTContext &ast = m_ast.getASTContext();
2042061da546Spatrick       if (!clang_type)
2043061da546Spatrick         clang_type = m_ast.GetBasicType(eBasicTypeVoid);
2044061da546Spatrick 
2045061da546Spatrick       if (!is_template_template_argument) {
2046061da546Spatrick         bool is_signed = false;
2047061da546Spatrick         if (name && name[0])
2048061da546Spatrick           template_param_infos.names.push_back(name);
2049061da546Spatrick         else
2050*f6aab3d8Srobert           template_param_infos.names.push_back(nullptr);
2051061da546Spatrick 
2052061da546Spatrick         // Get the signed value for any integer or enumeration if available
2053061da546Spatrick         clang_type.IsIntegerOrEnumerationType(is_signed);
2054061da546Spatrick 
2055061da546Spatrick         if (tag == DW_TAG_template_value_parameter && uval64_valid) {
2056*f6aab3d8Srobert           std::optional<uint64_t> size = clang_type.GetBitSize(nullptr);
2057061da546Spatrick           if (!size)
2058061da546Spatrick             return false;
2059061da546Spatrick           llvm::APInt apint(*size, uval64, is_signed);
2060061da546Spatrick           template_param_infos.args.push_back(
2061061da546Spatrick               clang::TemplateArgument(ast, llvm::APSInt(apint, !is_signed),
2062061da546Spatrick                                       ClangUtil::GetQualType(clang_type)));
2063061da546Spatrick         } else {
2064061da546Spatrick           template_param_infos.args.push_back(
2065061da546Spatrick               clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
2066061da546Spatrick         }
2067061da546Spatrick       } else {
2068061da546Spatrick         auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name);
2069061da546Spatrick         template_param_infos.names.push_back(name);
2070061da546Spatrick         template_param_infos.args.push_back(
2071061da546Spatrick             clang::TemplateArgument(clang::TemplateName(tplt_type)));
2072061da546Spatrick       }
2073061da546Spatrick     }
2074061da546Spatrick   }
2075061da546Spatrick     return true;
2076061da546Spatrick 
2077061da546Spatrick   default:
2078061da546Spatrick     break;
2079061da546Spatrick   }
2080061da546Spatrick   return false;
2081061da546Spatrick }
2082061da546Spatrick 
ParseTemplateParameterInfos(const DWARFDIE & parent_die,TypeSystemClang::TemplateParameterInfos & template_param_infos)2083061da546Spatrick bool DWARFASTParserClang::ParseTemplateParameterInfos(
2084061da546Spatrick     const DWARFDIE &parent_die,
2085dda28197Spatrick     TypeSystemClang::TemplateParameterInfos &template_param_infos) {
2086061da546Spatrick 
2087061da546Spatrick   if (!parent_die)
2088061da546Spatrick     return false;
2089061da546Spatrick 
2090be691f3bSpatrick   for (DWARFDIE die : parent_die.children()) {
2091061da546Spatrick     const dw_tag_t tag = die.Tag();
2092061da546Spatrick 
2093061da546Spatrick     switch (tag) {
2094061da546Spatrick     case DW_TAG_template_type_parameter:
2095061da546Spatrick     case DW_TAG_template_value_parameter:
2096061da546Spatrick     case DW_TAG_GNU_template_parameter_pack:
2097061da546Spatrick     case DW_TAG_GNU_template_template_param:
2098061da546Spatrick       ParseTemplateDIE(die, template_param_infos);
2099061da546Spatrick       break;
2100061da546Spatrick 
2101061da546Spatrick     default:
2102061da546Spatrick       break;
2103061da546Spatrick     }
2104061da546Spatrick   }
2105*f6aab3d8Srobert   return template_param_infos.args.size() ==
2106*f6aab3d8Srobert              template_param_infos.names.size() &&
2107*f6aab3d8Srobert          (!template_param_infos.args.empty() ||
2108*f6aab3d8Srobert           template_param_infos.packed_args);
2109061da546Spatrick }
2110061da546Spatrick 
CompleteRecordType(const DWARFDIE & die,lldb_private::Type * type,CompilerType & clang_type)2111061da546Spatrick bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
2112061da546Spatrick                                              lldb_private::Type *type,
2113061da546Spatrick                                              CompilerType &clang_type) {
2114061da546Spatrick   const dw_tag_t tag = die.Tag();
2115061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
2116061da546Spatrick 
2117061da546Spatrick   ClangASTImporter::LayoutInfo layout_info;
2118061da546Spatrick 
2119061da546Spatrick   if (die.HasChildren()) {
2120dda28197Spatrick     const bool type_is_objc_object_or_interface =
2121dda28197Spatrick         TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type);
2122dda28197Spatrick     if (type_is_objc_object_or_interface) {
2123061da546Spatrick       // For objective C we don't start the definition when the class is
2124061da546Spatrick       // created.
2125dda28197Spatrick       TypeSystemClang::StartTagDeclarationDefinition(clang_type);
2126061da546Spatrick     }
2127061da546Spatrick 
2128061da546Spatrick     AccessType default_accessibility = eAccessNone;
2129061da546Spatrick     if (tag == DW_TAG_structure_type) {
2130061da546Spatrick       default_accessibility = eAccessPublic;
2131061da546Spatrick     } else if (tag == DW_TAG_union_type) {
2132061da546Spatrick       default_accessibility = eAccessPublic;
2133061da546Spatrick     } else if (tag == DW_TAG_class_type) {
2134061da546Spatrick       default_accessibility = eAccessPrivate;
2135061da546Spatrick     }
2136061da546Spatrick 
2137061da546Spatrick     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
2138061da546Spatrick     // Parse members and base classes first
2139061da546Spatrick     std::vector<DWARFDIE> member_function_dies;
2140061da546Spatrick 
2141061da546Spatrick     DelayedPropertyList delayed_properties;
2142be691f3bSpatrick     ParseChildMembers(die, clang_type, bases, member_function_dies,
2143be691f3bSpatrick                       delayed_properties, default_accessibility, layout_info);
2144061da546Spatrick 
2145061da546Spatrick     // Now parse any methods if there were any...
2146061da546Spatrick     for (const DWARFDIE &die : member_function_dies)
2147061da546Spatrick       dwarf->ResolveType(die);
2148061da546Spatrick 
2149dda28197Spatrick     if (type_is_objc_object_or_interface) {
2150061da546Spatrick       ConstString class_name(clang_type.GetTypeName());
2151061da546Spatrick       if (class_name) {
2152dda28197Spatrick         dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) {
2153061da546Spatrick           method_die.ResolveType();
2154dda28197Spatrick           return true;
2155dda28197Spatrick         });
2156061da546Spatrick 
2157*f6aab3d8Srobert         for (DelayedAddObjCClassProperty &property : delayed_properties)
2158*f6aab3d8Srobert           property.Finalize();
2159061da546Spatrick       }
2160061da546Spatrick     }
2161061da546Spatrick 
2162061da546Spatrick     if (!bases.empty()) {
2163061da546Spatrick       // Make sure all base classes refer to complete types and not forward
2164061da546Spatrick       // declarations. If we don't do this, clang will crash with an
2165061da546Spatrick       // assertion in the call to clang_type.TransferBaseClasses()
2166061da546Spatrick       for (const auto &base_class : bases) {
2167061da546Spatrick         clang::TypeSourceInfo *type_source_info =
2168061da546Spatrick             base_class->getTypeSourceInfo();
2169dda28197Spatrick         if (type_source_info)
2170*f6aab3d8Srobert           TypeSystemClang::RequireCompleteType(
2171*f6aab3d8Srobert               m_ast.GetType(type_source_info->getType()));
2172061da546Spatrick       }
2173061da546Spatrick 
2174061da546Spatrick       m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
2175061da546Spatrick                                 std::move(bases));
2176061da546Spatrick     }
2177061da546Spatrick   }
2178061da546Spatrick 
2179061da546Spatrick   m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType());
2180dda28197Spatrick   TypeSystemClang::BuildIndirectFields(clang_type);
2181dda28197Spatrick   TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
2182061da546Spatrick 
2183061da546Spatrick   if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() ||
2184061da546Spatrick       !layout_info.vbase_offsets.empty()) {
2185061da546Spatrick     if (type)
2186*f6aab3d8Srobert       layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8;
2187061da546Spatrick     if (layout_info.bit_size == 0)
2188061da546Spatrick       layout_info.bit_size =
2189061da546Spatrick           die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
2190061da546Spatrick 
2191061da546Spatrick     clang::CXXRecordDecl *record_decl =
2192061da546Spatrick         m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
2193061da546Spatrick     if (record_decl)
2194061da546Spatrick       GetClangASTImporter().SetRecordLayout(record_decl, layout_info);
2195061da546Spatrick   }
2196061da546Spatrick 
2197061da546Spatrick   return (bool)clang_type;
2198061da546Spatrick }
2199061da546Spatrick 
CompleteEnumType(const DWARFDIE & die,lldb_private::Type * type,CompilerType & clang_type)2200061da546Spatrick bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die,
2201061da546Spatrick                                            lldb_private::Type *type,
2202061da546Spatrick                                            CompilerType &clang_type) {
2203dda28197Spatrick   if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
2204061da546Spatrick     if (die.HasChildren()) {
2205061da546Spatrick       bool is_signed = false;
2206061da546Spatrick       clang_type.IsIntegerType(is_signed);
2207061da546Spatrick       ParseChildEnumerators(clang_type, is_signed,
2208*f6aab3d8Srobert                             type->GetByteSize(nullptr).value_or(0), die);
2209061da546Spatrick     }
2210dda28197Spatrick     TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
2211061da546Spatrick   }
2212061da546Spatrick   return (bool)clang_type;
2213061da546Spatrick }
2214061da546Spatrick 
CompleteTypeFromDWARF(const DWARFDIE & die,lldb_private::Type * type,CompilerType & clang_type)2215061da546Spatrick bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
2216061da546Spatrick                                                 lldb_private::Type *type,
2217061da546Spatrick                                                 CompilerType &clang_type) {
2218061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
2219061da546Spatrick 
2220061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(
2221061da546Spatrick       dwarf->GetObjectFile()->GetModule()->GetMutex());
2222061da546Spatrick 
2223061da546Spatrick   // Disable external storage for this type so we don't get anymore
2224061da546Spatrick   // clang::ExternalASTSource queries for this type.
2225061da546Spatrick   m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false);
2226061da546Spatrick 
2227061da546Spatrick   if (!die)
2228061da546Spatrick     return false;
2229061da546Spatrick 
2230061da546Spatrick   const dw_tag_t tag = die.Tag();
2231061da546Spatrick 
2232061da546Spatrick   assert(clang_type);
2233061da546Spatrick   DWARFAttributes attributes;
2234061da546Spatrick   switch (tag) {
2235061da546Spatrick   case DW_TAG_structure_type:
2236061da546Spatrick   case DW_TAG_union_type:
2237061da546Spatrick   case DW_TAG_class_type:
2238061da546Spatrick     return CompleteRecordType(die, type, clang_type);
2239061da546Spatrick   case DW_TAG_enumeration_type:
2240061da546Spatrick     return CompleteEnumType(die, type, clang_type);
2241061da546Spatrick   default:
2242061da546Spatrick     assert(false && "not a forward clang type decl!");
2243061da546Spatrick     break;
2244061da546Spatrick   }
2245061da546Spatrick 
2246061da546Spatrick   return false;
2247061da546Spatrick }
2248061da546Spatrick 
EnsureAllDIEsInDeclContextHaveBeenParsed(lldb_private::CompilerDeclContext decl_context)2249061da546Spatrick void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
2250061da546Spatrick     lldb_private::CompilerDeclContext decl_context) {
2251061da546Spatrick   auto opaque_decl_ctx =
2252061da546Spatrick       (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
2253061da546Spatrick   for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
2254061da546Spatrick        it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
2255061da546Spatrick        it = m_decl_ctx_to_die.erase(it))
2256be691f3bSpatrick     for (DWARFDIE decl : it->second.children())
2257061da546Spatrick       GetClangDeclForDIE(decl);
2258061da546Spatrick }
2259061da546Spatrick 
GetDeclForUIDFromDWARF(const DWARFDIE & die)2260061da546Spatrick CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
2261061da546Spatrick   clang::Decl *clang_decl = GetClangDeclForDIE(die);
2262061da546Spatrick   if (clang_decl != nullptr)
2263dda28197Spatrick     return m_ast.GetCompilerDecl(clang_decl);
2264061da546Spatrick   return CompilerDecl();
2265061da546Spatrick }
2266061da546Spatrick 
2267061da546Spatrick CompilerDeclContext
GetDeclContextForUIDFromDWARF(const DWARFDIE & die)2268061da546Spatrick DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
2269061da546Spatrick   clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);
2270061da546Spatrick   if (clang_decl_ctx)
2271061da546Spatrick     return m_ast.CreateDeclContext(clang_decl_ctx);
2272061da546Spatrick   return CompilerDeclContext();
2273061da546Spatrick }
2274061da546Spatrick 
2275061da546Spatrick CompilerDeclContext
GetDeclContextContainingUIDFromDWARF(const DWARFDIE & die)2276061da546Spatrick DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
2277061da546Spatrick   clang::DeclContext *clang_decl_ctx =
2278061da546Spatrick       GetClangDeclContextContainingDIE(die, nullptr);
2279061da546Spatrick   if (clang_decl_ctx)
2280061da546Spatrick     return m_ast.CreateDeclContext(clang_decl_ctx);
2281061da546Spatrick   return CompilerDeclContext();
2282061da546Spatrick }
2283061da546Spatrick 
ParseChildEnumerators(lldb_private::CompilerType & clang_type,bool is_signed,uint32_t enumerator_byte_size,const DWARFDIE & parent_die)2284061da546Spatrick size_t DWARFASTParserClang::ParseChildEnumerators(
2285061da546Spatrick     lldb_private::CompilerType &clang_type, bool is_signed,
2286061da546Spatrick     uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
2287061da546Spatrick   if (!parent_die)
2288061da546Spatrick     return 0;
2289061da546Spatrick 
2290061da546Spatrick   size_t enumerators_added = 0;
2291061da546Spatrick 
2292be691f3bSpatrick   for (DWARFDIE die : parent_die.children()) {
2293061da546Spatrick     const dw_tag_t tag = die.Tag();
2294061da546Spatrick     if (tag == DW_TAG_enumerator) {
2295061da546Spatrick       DWARFAttributes attributes;
2296061da546Spatrick       const size_t num_child_attributes = die.GetAttributes(attributes);
2297061da546Spatrick       if (num_child_attributes > 0) {
2298061da546Spatrick         const char *name = nullptr;
2299061da546Spatrick         bool got_value = false;
2300061da546Spatrick         int64_t enum_value = 0;
2301061da546Spatrick         Declaration decl;
2302061da546Spatrick 
2303061da546Spatrick         uint32_t i;
2304061da546Spatrick         for (i = 0; i < num_child_attributes; ++i) {
2305061da546Spatrick           const dw_attr_t attr = attributes.AttributeAtIndex(i);
2306061da546Spatrick           DWARFFormValue form_value;
2307061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2308061da546Spatrick             switch (attr) {
2309061da546Spatrick             case DW_AT_const_value:
2310061da546Spatrick               got_value = true;
2311061da546Spatrick               if (is_signed)
2312061da546Spatrick                 enum_value = form_value.Signed();
2313061da546Spatrick               else
2314061da546Spatrick                 enum_value = form_value.Unsigned();
2315061da546Spatrick               break;
2316061da546Spatrick 
2317061da546Spatrick             case DW_AT_name:
2318061da546Spatrick               name = form_value.AsCString();
2319061da546Spatrick               break;
2320061da546Spatrick 
2321061da546Spatrick             case DW_AT_description:
2322061da546Spatrick             default:
2323061da546Spatrick             case DW_AT_decl_file:
2324be691f3bSpatrick               decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile(
2325be691f3bSpatrick                   form_value.Unsigned()));
2326061da546Spatrick               break;
2327061da546Spatrick             case DW_AT_decl_line:
2328061da546Spatrick               decl.SetLine(form_value.Unsigned());
2329061da546Spatrick               break;
2330061da546Spatrick             case DW_AT_decl_column:
2331061da546Spatrick               decl.SetColumn(form_value.Unsigned());
2332061da546Spatrick               break;
2333061da546Spatrick             case DW_AT_sibling:
2334061da546Spatrick               break;
2335061da546Spatrick             }
2336061da546Spatrick           }
2337061da546Spatrick         }
2338061da546Spatrick 
2339061da546Spatrick         if (name && name[0] && got_value) {
2340061da546Spatrick           m_ast.AddEnumerationValueToEnumerationType(
2341061da546Spatrick               clang_type, decl, name, enum_value, enumerator_byte_size * 8);
2342061da546Spatrick           ++enumerators_added;
2343061da546Spatrick         }
2344061da546Spatrick       }
2345061da546Spatrick     }
2346061da546Spatrick   }
2347061da546Spatrick   return enumerators_added;
2348061da546Spatrick }
2349061da546Spatrick 
2350*f6aab3d8Srobert ConstString
ConstructDemangledNameFromDWARF(const DWARFDIE & die)2351*f6aab3d8Srobert DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
2352061da546Spatrick   bool is_static = false;
2353061da546Spatrick   bool is_variadic = false;
2354061da546Spatrick   bool has_template_params = false;
2355061da546Spatrick   unsigned type_quals = 0;
2356061da546Spatrick   std::vector<CompilerType> param_types;
2357061da546Spatrick   std::vector<clang::ParmVarDecl *> param_decls;
2358061da546Spatrick   StreamString sstr;
2359061da546Spatrick 
2360dda28197Spatrick   DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
2361061da546Spatrick   sstr << decl_ctx.GetQualifiedName();
2362061da546Spatrick 
2363061da546Spatrick   clang::DeclContext *containing_decl_ctx =
2364061da546Spatrick       GetClangDeclContextContainingDIE(die, nullptr);
2365*f6aab3d8Srobert   ParseChildParameters(containing_decl_ctx, die, true, is_static, is_variadic,
2366*f6aab3d8Srobert                        has_template_params, param_types, param_decls,
2367*f6aab3d8Srobert                        type_quals);
2368061da546Spatrick   sstr << "(";
2369061da546Spatrick   for (size_t i = 0; i < param_types.size(); i++) {
2370061da546Spatrick     if (i > 0)
2371061da546Spatrick       sstr << ", ";
2372061da546Spatrick     sstr << param_types[i].GetTypeName();
2373061da546Spatrick   }
2374061da546Spatrick   if (is_variadic)
2375061da546Spatrick     sstr << ", ...";
2376061da546Spatrick   sstr << ")";
2377061da546Spatrick   if (type_quals & clang::Qualifiers::Const)
2378061da546Spatrick     sstr << " const";
2379061da546Spatrick 
2380*f6aab3d8Srobert   return ConstString(sstr.GetString());
2381*f6aab3d8Srobert }
2382*f6aab3d8Srobert 
2383*f6aab3d8Srobert Function *
ParseFunctionFromDWARF(CompileUnit & comp_unit,const DWARFDIE & die,const AddressRange & func_range)2384*f6aab3d8Srobert DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2385*f6aab3d8Srobert                                             const DWARFDIE &die,
2386*f6aab3d8Srobert                                             const AddressRange &func_range) {
2387*f6aab3d8Srobert   assert(func_range.GetBaseAddress().IsValid());
2388*f6aab3d8Srobert   DWARFRangeList func_ranges;
2389*f6aab3d8Srobert   const char *name = nullptr;
2390*f6aab3d8Srobert   const char *mangled = nullptr;
2391*f6aab3d8Srobert   int decl_file = 0;
2392*f6aab3d8Srobert   int decl_line = 0;
2393*f6aab3d8Srobert   int decl_column = 0;
2394*f6aab3d8Srobert   int call_file = 0;
2395*f6aab3d8Srobert   int call_line = 0;
2396*f6aab3d8Srobert   int call_column = 0;
2397*f6aab3d8Srobert   DWARFExpressionList frame_base;
2398*f6aab3d8Srobert 
2399*f6aab3d8Srobert   const dw_tag_t tag = die.Tag();
2400*f6aab3d8Srobert 
2401*f6aab3d8Srobert   if (tag != DW_TAG_subprogram)
2402*f6aab3d8Srobert     return nullptr;
2403*f6aab3d8Srobert 
2404*f6aab3d8Srobert   if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
2405*f6aab3d8Srobert                                decl_column, call_file, call_line, call_column,
2406*f6aab3d8Srobert                                &frame_base)) {
2407*f6aab3d8Srobert     Mangled func_name;
2408*f6aab3d8Srobert     if (mangled)
2409*f6aab3d8Srobert       func_name.SetValue(ConstString(mangled), true);
2410*f6aab3d8Srobert     else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
2411*f6aab3d8Srobert               die.GetParent().Tag() == DW_TAG_partial_unit) &&
2412*f6aab3d8Srobert              Language::LanguageIsCPlusPlus(
2413*f6aab3d8Srobert                  SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2414*f6aab3d8Srobert              !Language::LanguageIsObjC(
2415*f6aab3d8Srobert                  SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2416*f6aab3d8Srobert              name && strcmp(name, "main") != 0) {
2417*f6aab3d8Srobert       // If the mangled name is not present in the DWARF, generate the
2418*f6aab3d8Srobert       // demangled name using the decl context. We skip if the function is
2419*f6aab3d8Srobert       // "main" as its name is never mangled.
2420*f6aab3d8Srobert       func_name.SetValue(ConstructDemangledNameFromDWARF(die), false);
2421061da546Spatrick     } else
2422061da546Spatrick       func_name.SetValue(ConstString(name), false);
2423061da546Spatrick 
2424061da546Spatrick     FunctionSP func_sp;
2425061da546Spatrick     std::unique_ptr<Declaration> decl_up;
2426061da546Spatrick     if (decl_file != 0 || decl_line != 0 || decl_column != 0)
2427dda28197Spatrick       decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file),
2428dda28197Spatrick                                               decl_line, decl_column);
2429061da546Spatrick 
2430061da546Spatrick     SymbolFileDWARF *dwarf = die.GetDWARF();
2431061da546Spatrick     // Supply the type _only_ if it has already been parsed
2432061da546Spatrick     Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
2433061da546Spatrick 
2434061da546Spatrick     assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
2435061da546Spatrick 
2436061da546Spatrick     const user_id_t func_user_id = die.GetID();
2437061da546Spatrick     func_sp =
2438061da546Spatrick         std::make_shared<Function>(&comp_unit,
2439061da546Spatrick                                    func_user_id, // UserID is the DIE offset
2440061da546Spatrick                                    func_user_id, func_name, func_type,
2441061da546Spatrick                                    func_range); // first address range
2442061da546Spatrick 
2443061da546Spatrick     if (func_sp.get() != nullptr) {
2444061da546Spatrick       if (frame_base.IsValid())
2445061da546Spatrick         func_sp->GetFrameBaseExpression() = frame_base;
2446061da546Spatrick       comp_unit.AddFunction(func_sp);
2447061da546Spatrick       return func_sp.get();
2448061da546Spatrick     }
2449061da546Spatrick   }
2450061da546Spatrick   return nullptr;
2451061da546Spatrick }
2452061da546Spatrick 
2453*f6aab3d8Srobert namespace {
2454*f6aab3d8Srobert /// Parsed form of all attributes that are relevant for parsing type members.
2455*f6aab3d8Srobert struct MemberAttributes {
2456*f6aab3d8Srobert   explicit MemberAttributes(const DWARFDIE &die, const DWARFDIE &parent_die,
2457*f6aab3d8Srobert                             ModuleSP module_sp);
2458061da546Spatrick   const char *name = nullptr;
2459*f6aab3d8Srobert   /// Indicates how many bits into the word (according to the host endianness)
2460*f6aab3d8Srobert   /// the low-order bit of the field starts. Can be negative.
2461*f6aab3d8Srobert   int64_t bit_offset = 0;
2462*f6aab3d8Srobert   /// Indicates the size of the field in bits.
2463*f6aab3d8Srobert   size_t bit_size = 0;
2464*f6aab3d8Srobert   uint64_t data_bit_offset = UINT64_MAX;
2465*f6aab3d8Srobert   AccessType accessibility = eAccessNone;
2466*f6aab3d8Srobert   std::optional<uint64_t> byte_size;
2467*f6aab3d8Srobert   std::optional<DWARFFormValue> const_value_form;
2468*f6aab3d8Srobert   DWARFFormValue encoding_form;
2469*f6aab3d8Srobert   /// Indicates the byte offset of the word from the base address of the
2470*f6aab3d8Srobert   /// structure.
2471*f6aab3d8Srobert   uint32_t member_byte_offset;
2472*f6aab3d8Srobert   bool is_artificial = false;
2473*f6aab3d8Srobert };
2474*f6aab3d8Srobert 
2475*f6aab3d8Srobert /// Parsed form of all attributes that are relevant for parsing Objective-C
2476*f6aab3d8Srobert /// properties.
2477*f6aab3d8Srobert struct PropertyAttributes {
2478*f6aab3d8Srobert   explicit PropertyAttributes(const DWARFDIE &die);
2479061da546Spatrick   const char *prop_name = nullptr;
2480061da546Spatrick   const char *prop_getter_name = nullptr;
2481061da546Spatrick   const char *prop_setter_name = nullptr;
2482*f6aab3d8Srobert   /// \see clang::ObjCPropertyAttribute
2483061da546Spatrick   uint32_t prop_attributes = 0;
2484*f6aab3d8Srobert };
2485*f6aab3d8Srobert } // namespace
2486061da546Spatrick 
MemberAttributes(const DWARFDIE & die,const DWARFDIE & parent_die,ModuleSP module_sp)2487*f6aab3d8Srobert MemberAttributes::MemberAttributes(const DWARFDIE &die,
2488*f6aab3d8Srobert                                    const DWARFDIE &parent_die,
2489*f6aab3d8Srobert                                    ModuleSP module_sp) {
2490*f6aab3d8Srobert   member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
2491*f6aab3d8Srobert 
2492*f6aab3d8Srobert   DWARFAttributes attributes;
2493*f6aab3d8Srobert   const size_t num_attributes = die.GetAttributes(attributes);
2494*f6aab3d8Srobert   for (std::size_t i = 0; i < num_attributes; ++i) {
2495061da546Spatrick     const dw_attr_t attr = attributes.AttributeAtIndex(i);
2496061da546Spatrick     DWARFFormValue form_value;
2497061da546Spatrick     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2498061da546Spatrick       switch (attr) {
2499061da546Spatrick       case DW_AT_name:
2500061da546Spatrick         name = form_value.AsCString();
2501061da546Spatrick         break;
2502061da546Spatrick       case DW_AT_type:
2503061da546Spatrick         encoding_form = form_value;
2504061da546Spatrick         break;
2505061da546Spatrick       case DW_AT_bit_offset:
2506061da546Spatrick         bit_offset = form_value.Signed();
2507061da546Spatrick         break;
2508061da546Spatrick       case DW_AT_bit_size:
2509061da546Spatrick         bit_size = form_value.Unsigned();
2510061da546Spatrick         break;
2511061da546Spatrick       case DW_AT_byte_size:
2512061da546Spatrick         byte_size = form_value.Unsigned();
2513061da546Spatrick         break;
2514*f6aab3d8Srobert       case DW_AT_const_value:
2515*f6aab3d8Srobert         const_value_form = form_value;
2516*f6aab3d8Srobert         break;
2517061da546Spatrick       case DW_AT_data_bit_offset:
2518061da546Spatrick         data_bit_offset = form_value.Unsigned();
2519061da546Spatrick         break;
2520061da546Spatrick       case DW_AT_data_member_location:
2521061da546Spatrick         if (form_value.BlockData()) {
2522061da546Spatrick           Value initialValue(0);
2523061da546Spatrick           Value memberOffset(0);
2524061da546Spatrick           const DWARFDataExtractor &debug_info_data = die.GetData();
2525061da546Spatrick           uint32_t block_length = form_value.Unsigned();
2526061da546Spatrick           uint32_t block_offset =
2527061da546Spatrick               form_value.BlockData() - debug_info_data.GetDataStart();
2528061da546Spatrick           if (DWARFExpression::Evaluate(
2529061da546Spatrick                   nullptr, // ExecutionContext *
2530061da546Spatrick                   nullptr, // RegisterContext *
2531061da546Spatrick                   module_sp,
2532061da546Spatrick                   DataExtractor(debug_info_data, block_offset, block_length),
2533061da546Spatrick                   die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
2534061da546Spatrick                   memberOffset, nullptr)) {
2535061da546Spatrick             member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
2536061da546Spatrick           }
2537061da546Spatrick         } else {
2538061da546Spatrick           // With DWARF 3 and later, if the value is an integer constant,
2539061da546Spatrick           // this form value is the offset in bytes from the beginning of
2540061da546Spatrick           // the containing entity.
2541061da546Spatrick           member_byte_offset = form_value.Unsigned();
2542061da546Spatrick         }
2543061da546Spatrick         break;
2544061da546Spatrick 
2545061da546Spatrick       case DW_AT_accessibility:
2546*f6aab3d8Srobert         accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned());
2547061da546Spatrick         break;
2548061da546Spatrick       case DW_AT_artificial:
2549061da546Spatrick         is_artificial = form_value.Boolean();
2550061da546Spatrick         break;
2551061da546Spatrick       default:
2552061da546Spatrick         break;
2553061da546Spatrick       }
2554061da546Spatrick     }
2555061da546Spatrick   }
2556061da546Spatrick 
2557061da546Spatrick   // Clang has a DWARF generation bug where sometimes it represents
2558061da546Spatrick   // fields that are references with bad byte size and bit size/offset
2559061da546Spatrick   // information such as:
2560061da546Spatrick   //
2561061da546Spatrick   //  DW_AT_byte_size( 0x00 )
2562061da546Spatrick   //  DW_AT_bit_size( 0x40 )
2563061da546Spatrick   //  DW_AT_bit_offset( 0xffffffffffffffc0 )
2564061da546Spatrick   //
2565061da546Spatrick   // So check the bit offset to make sure it is sane, and if the values
2566061da546Spatrick   // are not sane, remove them. If we don't do this then we will end up
2567061da546Spatrick   // with a crash if we try to use this type in an expression when clang
2568061da546Spatrick   // becomes unhappy with its recycled debug info.
2569*f6aab3d8Srobert   if (byte_size.value_or(0) == 0 && bit_offset < 0) {
2570061da546Spatrick     bit_size = 0;
2571061da546Spatrick     bit_offset = 0;
2572061da546Spatrick   }
2573*f6aab3d8Srobert }
2574*f6aab3d8Srobert 
PropertyAttributes(const DWARFDIE & die)2575*f6aab3d8Srobert PropertyAttributes::PropertyAttributes(const DWARFDIE &die) {
2576*f6aab3d8Srobert 
2577*f6aab3d8Srobert   DWARFAttributes attributes;
2578*f6aab3d8Srobert   const size_t num_attributes = die.GetAttributes(attributes);
2579*f6aab3d8Srobert   for (size_t i = 0; i < num_attributes; ++i) {
2580*f6aab3d8Srobert     const dw_attr_t attr = attributes.AttributeAtIndex(i);
2581*f6aab3d8Srobert     DWARFFormValue form_value;
2582*f6aab3d8Srobert     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2583*f6aab3d8Srobert       switch (attr) {
2584*f6aab3d8Srobert       case DW_AT_APPLE_property_name:
2585*f6aab3d8Srobert         prop_name = form_value.AsCString();
2586*f6aab3d8Srobert         break;
2587*f6aab3d8Srobert       case DW_AT_APPLE_property_getter:
2588*f6aab3d8Srobert         prop_getter_name = form_value.AsCString();
2589*f6aab3d8Srobert         break;
2590*f6aab3d8Srobert       case DW_AT_APPLE_property_setter:
2591*f6aab3d8Srobert         prop_setter_name = form_value.AsCString();
2592*f6aab3d8Srobert         break;
2593*f6aab3d8Srobert       case DW_AT_APPLE_property_attribute:
2594*f6aab3d8Srobert         prop_attributes = form_value.Unsigned();
2595*f6aab3d8Srobert         break;
2596*f6aab3d8Srobert       default:
2597*f6aab3d8Srobert         break;
2598*f6aab3d8Srobert       }
2599*f6aab3d8Srobert     }
2600*f6aab3d8Srobert   }
2601*f6aab3d8Srobert 
2602*f6aab3d8Srobert   if (!prop_name)
2603*f6aab3d8Srobert     return;
2604*f6aab3d8Srobert   ConstString fixed_setter;
2605*f6aab3d8Srobert 
2606*f6aab3d8Srobert   // Check if the property getter/setter were provided as full names.
2607*f6aab3d8Srobert   // We want basenames, so we extract them.
2608*f6aab3d8Srobert   if (prop_getter_name && prop_getter_name[0] == '-') {
2609*f6aab3d8Srobert     ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
2610*f6aab3d8Srobert     prop_getter_name = prop_getter_method.GetSelector().GetCString();
2611*f6aab3d8Srobert   }
2612*f6aab3d8Srobert 
2613*f6aab3d8Srobert   if (prop_setter_name && prop_setter_name[0] == '-') {
2614*f6aab3d8Srobert     ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
2615*f6aab3d8Srobert     prop_setter_name = prop_setter_method.GetSelector().GetCString();
2616*f6aab3d8Srobert   }
2617*f6aab3d8Srobert 
2618*f6aab3d8Srobert   // If the names haven't been provided, they need to be filled in.
2619*f6aab3d8Srobert   if (!prop_getter_name)
2620*f6aab3d8Srobert     prop_getter_name = prop_name;
2621*f6aab3d8Srobert   if (!prop_setter_name && prop_name[0] &&
2622*f6aab3d8Srobert       !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
2623*f6aab3d8Srobert     StreamString ss;
2624*f6aab3d8Srobert 
2625*f6aab3d8Srobert     ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
2626*f6aab3d8Srobert 
2627*f6aab3d8Srobert     fixed_setter.SetString(ss.GetString());
2628*f6aab3d8Srobert     prop_setter_name = fixed_setter.GetCString();
2629*f6aab3d8Srobert   }
2630*f6aab3d8Srobert }
2631*f6aab3d8Srobert 
ParseObjCProperty(const DWARFDIE & die,const DWARFDIE & parent_die,const lldb_private::CompilerType & class_clang_type,DelayedPropertyList & delayed_properties)2632*f6aab3d8Srobert void DWARFASTParserClang::ParseObjCProperty(
2633*f6aab3d8Srobert     const DWARFDIE &die, const DWARFDIE &parent_die,
2634*f6aab3d8Srobert     const lldb_private::CompilerType &class_clang_type,
2635*f6aab3d8Srobert     DelayedPropertyList &delayed_properties) {
2636*f6aab3d8Srobert   // This function can only parse DW_TAG_APPLE_property.
2637*f6aab3d8Srobert   assert(die.Tag() == DW_TAG_APPLE_property);
2638*f6aab3d8Srobert 
2639*f6aab3d8Srobert   ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
2640*f6aab3d8Srobert 
2641*f6aab3d8Srobert   const MemberAttributes attrs(die, parent_die, module_sp);
2642*f6aab3d8Srobert   const PropertyAttributes propAttrs(die);
2643*f6aab3d8Srobert 
2644*f6aab3d8Srobert   if (!propAttrs.prop_name) {
2645*f6aab3d8Srobert     module_sp->ReportError("{0:x8}: DW_TAG_APPLE_property has no name.",
2646*f6aab3d8Srobert                            die.GetID());
2647*f6aab3d8Srobert     return;
2648*f6aab3d8Srobert   }
2649*f6aab3d8Srobert 
2650*f6aab3d8Srobert   Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
2651*f6aab3d8Srobert   if (!member_type) {
2652*f6aab3d8Srobert     module_sp->ReportError(
2653*f6aab3d8Srobert         "{0:x8}: DW_TAG_APPLE_property '{1}' refers to type {2:x16}"
2654*f6aab3d8Srobert         " which was unable to be parsed",
2655*f6aab3d8Srobert         die.GetID(), propAttrs.prop_name,
2656*f6aab3d8Srobert         attrs.encoding_form.Reference().GetOffset());
2657*f6aab3d8Srobert     return;
2658*f6aab3d8Srobert   }
2659*f6aab3d8Srobert 
2660*f6aab3d8Srobert   ClangASTMetadata metadata;
2661*f6aab3d8Srobert   metadata.SetUserID(die.GetID());
2662*f6aab3d8Srobert   delayed_properties.push_back(DelayedAddObjCClassProperty(
2663*f6aab3d8Srobert       class_clang_type, propAttrs.prop_name,
2664*f6aab3d8Srobert       member_type->GetLayoutCompilerType(), propAttrs.prop_setter_name,
2665*f6aab3d8Srobert       propAttrs.prop_getter_name, propAttrs.prop_attributes, &metadata));
2666*f6aab3d8Srobert }
2667*f6aab3d8Srobert 
ExtractIntFromFormValue(const CompilerType & int_type,const DWARFFormValue & form_value) const2668*f6aab3d8Srobert llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(
2669*f6aab3d8Srobert     const CompilerType &int_type, const DWARFFormValue &form_value) const {
2670*f6aab3d8Srobert   clang::QualType qt = ClangUtil::GetQualType(int_type);
2671*f6aab3d8Srobert   assert(qt->isIntegralOrEnumerationType());
2672*f6aab3d8Srobert   auto ts_ptr = int_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
2673*f6aab3d8Srobert   if (!ts_ptr)
2674*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(),
2675*f6aab3d8Srobert                                    "TypeSystem not clang");
2676*f6aab3d8Srobert   TypeSystemClang &ts = *ts_ptr;
2677*f6aab3d8Srobert   clang::ASTContext &ast = ts.getASTContext();
2678*f6aab3d8Srobert 
2679*f6aab3d8Srobert   const unsigned type_bits = ast.getIntWidth(qt);
2680*f6aab3d8Srobert   const bool is_unsigned = qt->isUnsignedIntegerType();
2681*f6aab3d8Srobert 
2682*f6aab3d8Srobert   // The maximum int size supported at the moment by this function. Limited
2683*f6aab3d8Srobert   // by the uint64_t return type of DWARFFormValue::Signed/Unsigned.
2684*f6aab3d8Srobert   constexpr std::size_t max_bit_size = 64;
2685*f6aab3d8Srobert 
2686*f6aab3d8Srobert   // For values bigger than 64 bit (e.g. __int128_t values),
2687*f6aab3d8Srobert   // DWARFFormValue's Signed/Unsigned functions will return wrong results so
2688*f6aab3d8Srobert   // emit an error for now.
2689*f6aab3d8Srobert   if (type_bits > max_bit_size) {
2690*f6aab3d8Srobert     auto msg = llvm::formatv("Can only parse integers with up to {0} bits, but "
2691*f6aab3d8Srobert                              "given integer has {1} bits.",
2692*f6aab3d8Srobert                              max_bit_size, type_bits);
2693*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str());
2694*f6aab3d8Srobert   }
2695*f6aab3d8Srobert 
2696*f6aab3d8Srobert   // Construct an APInt with the maximum bit size and the given integer.
2697*f6aab3d8Srobert   llvm::APInt result(max_bit_size, form_value.Unsigned(), !is_unsigned);
2698*f6aab3d8Srobert 
2699*f6aab3d8Srobert   // Calculate how many bits are required to represent the input value.
2700*f6aab3d8Srobert   // For unsigned types, take the number of active bits in the APInt.
2701*f6aab3d8Srobert   // For signed types, ask APInt how many bits are required to represent the
2702*f6aab3d8Srobert   // signed integer.
2703*f6aab3d8Srobert   const unsigned required_bits =
2704*f6aab3d8Srobert       is_unsigned ? result.getActiveBits() : result.getMinSignedBits();
2705*f6aab3d8Srobert 
2706*f6aab3d8Srobert   // If the input value doesn't fit into the integer type, return an error.
2707*f6aab3d8Srobert   if (required_bits > type_bits) {
2708*f6aab3d8Srobert     std::string value_as_str = is_unsigned
2709*f6aab3d8Srobert                                    ? std::to_string(form_value.Unsigned())
2710*f6aab3d8Srobert                                    : std::to_string(form_value.Signed());
2711*f6aab3d8Srobert     auto msg = llvm::formatv("Can't store {0} value {1} in integer with {2} "
2712*f6aab3d8Srobert                              "bits.",
2713*f6aab3d8Srobert                              (is_unsigned ? "unsigned" : "signed"),
2714*f6aab3d8Srobert                              value_as_str, type_bits);
2715*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(), msg.str());
2716*f6aab3d8Srobert   }
2717*f6aab3d8Srobert 
2718*f6aab3d8Srobert   // Trim the result to the bit width our the int type.
2719*f6aab3d8Srobert   if (result.getBitWidth() > type_bits)
2720*f6aab3d8Srobert     result = result.trunc(type_bits);
2721*f6aab3d8Srobert   return result;
2722*f6aab3d8Srobert }
2723*f6aab3d8Srobert 
ParseSingleMember(const DWARFDIE & die,const DWARFDIE & parent_die,const lldb_private::CompilerType & class_clang_type,lldb::AccessType default_accessibility,lldb_private::ClangASTImporter::LayoutInfo & layout_info,FieldInfo & last_field_info)2724*f6aab3d8Srobert void DWARFASTParserClang::ParseSingleMember(
2725*f6aab3d8Srobert     const DWARFDIE &die, const DWARFDIE &parent_die,
2726*f6aab3d8Srobert     const lldb_private::CompilerType &class_clang_type,
2727*f6aab3d8Srobert     lldb::AccessType default_accessibility,
2728*f6aab3d8Srobert     lldb_private::ClangASTImporter::LayoutInfo &layout_info,
2729*f6aab3d8Srobert     FieldInfo &last_field_info) {
2730*f6aab3d8Srobert   Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
2731*f6aab3d8Srobert   // This function can only parse DW_TAG_member.
2732*f6aab3d8Srobert   assert(die.Tag() == DW_TAG_member);
2733*f6aab3d8Srobert 
2734*f6aab3d8Srobert   ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
2735*f6aab3d8Srobert   const dw_tag_t tag = die.Tag();
2736*f6aab3d8Srobert   // Get the parent byte size so we can verify any members will fit
2737*f6aab3d8Srobert   const uint64_t parent_byte_size =
2738*f6aab3d8Srobert       parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
2739*f6aab3d8Srobert   const uint64_t parent_bit_size =
2740*f6aab3d8Srobert       parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
2741*f6aab3d8Srobert 
2742*f6aab3d8Srobert   // FIXME: Remove the workarounds below and make this const.
2743*f6aab3d8Srobert   MemberAttributes attrs(die, parent_die, module_sp);
2744061da546Spatrick 
2745dda28197Spatrick   const bool class_is_objc_object_or_interface =
2746dda28197Spatrick       TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type);
2747dda28197Spatrick 
2748061da546Spatrick   // FIXME: Make Clang ignore Objective-C accessibility for expressions
2749dda28197Spatrick   if (class_is_objc_object_or_interface)
2750*f6aab3d8Srobert     attrs.accessibility = eAccessNone;
2751061da546Spatrick 
2752*f6aab3d8Srobert   // Handle static members, which is any member that doesn't have a bit or a
2753*f6aab3d8Srobert   // byte member offset.
2754*f6aab3d8Srobert   if (attrs.member_byte_offset == UINT32_MAX &&
2755*f6aab3d8Srobert       attrs.data_bit_offset == UINT64_MAX) {
2756*f6aab3d8Srobert     Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
2757061da546Spatrick 
2758061da546Spatrick     if (var_type) {
2759*f6aab3d8Srobert       if (attrs.accessibility == eAccessNone)
2760*f6aab3d8Srobert         attrs.accessibility = eAccessPublic;
2761*f6aab3d8Srobert       CompilerType ct = var_type->GetForwardCompilerType();
2762*f6aab3d8Srobert       clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(
2763*f6aab3d8Srobert           class_clang_type, attrs.name, ct, attrs.accessibility);
2764*f6aab3d8Srobert       if (!v) {
2765*f6aab3d8Srobert         LLDB_LOG(log, "Failed to add variable to the record type");
2766*f6aab3d8Srobert         return;
2767*f6aab3d8Srobert       }
2768*f6aab3d8Srobert 
2769*f6aab3d8Srobert       bool unused;
2770*f6aab3d8Srobert       // TODO: Support float/double static members as well.
2771*f6aab3d8Srobert       if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused))
2772*f6aab3d8Srobert         return;
2773*f6aab3d8Srobert 
2774*f6aab3d8Srobert       llvm::Expected<llvm::APInt> const_value_or_err =
2775*f6aab3d8Srobert           ExtractIntFromFormValue(ct, *attrs.const_value_form);
2776*f6aab3d8Srobert       if (!const_value_or_err) {
2777*f6aab3d8Srobert         LLDB_LOG_ERROR(log, const_value_or_err.takeError(),
2778*f6aab3d8Srobert                        "Failed to add const value to variable {1}: {0}",
2779*f6aab3d8Srobert                        v->getQualifiedNameAsString());
2780*f6aab3d8Srobert         return;
2781*f6aab3d8Srobert       }
2782*f6aab3d8Srobert 
2783*f6aab3d8Srobert       TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
2784061da546Spatrick     }
2785061da546Spatrick     return;
2786061da546Spatrick   }
2787061da546Spatrick 
2788*f6aab3d8Srobert   Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
2789*f6aab3d8Srobert   if (!member_type) {
2790*f6aab3d8Srobert     if (attrs.name)
2791*f6aab3d8Srobert       module_sp->ReportError(
2792*f6aab3d8Srobert           "{0:x8}: DW_TAG_member '{1}' refers to type {2:x16}"
2793*f6aab3d8Srobert           " which was unable to be parsed",
2794*f6aab3d8Srobert           die.GetID(), attrs.name, attrs.encoding_form.Reference().GetOffset());
2795*f6aab3d8Srobert     else
2796*f6aab3d8Srobert       module_sp->ReportError("{0:x8}: DW_TAG_member refers to type {1:x16}"
2797*f6aab3d8Srobert                              " which was unable to be parsed",
2798*f6aab3d8Srobert                              die.GetID(),
2799*f6aab3d8Srobert                              attrs.encoding_form.Reference().GetOffset());
2800*f6aab3d8Srobert     return;
2801*f6aab3d8Srobert   }
2802061da546Spatrick 
2803061da546Spatrick   const uint64_t character_width = 8;
2804061da546Spatrick   const uint64_t word_width = 32;
2805061da546Spatrick   CompilerType member_clang_type = member_type->GetLayoutCompilerType();
2806061da546Spatrick 
2807*f6aab3d8Srobert   if (attrs.accessibility == eAccessNone)
2808*f6aab3d8Srobert     attrs.accessibility = default_accessibility;
2809061da546Spatrick 
2810*f6aab3d8Srobert   uint64_t field_bit_offset = (attrs.member_byte_offset == UINT32_MAX
2811*f6aab3d8Srobert                                    ? 0
2812*f6aab3d8Srobert                                    : (attrs.member_byte_offset * 8ULL));
2813061da546Spatrick 
2814*f6aab3d8Srobert   if (attrs.bit_size > 0) {
2815061da546Spatrick     FieldInfo this_field_info;
2816061da546Spatrick     this_field_info.bit_offset = field_bit_offset;
2817*f6aab3d8Srobert     this_field_info.bit_size = attrs.bit_size;
2818061da546Spatrick 
2819*f6aab3d8Srobert     if (attrs.data_bit_offset != UINT64_MAX) {
2820*f6aab3d8Srobert       this_field_info.bit_offset = attrs.data_bit_offset;
2821061da546Spatrick     } else {
2822*f6aab3d8Srobert       if (!attrs.byte_size)
2823*f6aab3d8Srobert         attrs.byte_size = member_type->GetByteSize(nullptr);
2824061da546Spatrick 
2825061da546Spatrick       ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
2826061da546Spatrick       if (objfile->GetByteOrder() == eByteOrderLittle) {
2827*f6aab3d8Srobert         this_field_info.bit_offset += attrs.byte_size.value_or(0) * 8;
2828*f6aab3d8Srobert         this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size);
2829061da546Spatrick       } else {
2830*f6aab3d8Srobert         this_field_info.bit_offset += attrs.bit_offset;
2831061da546Spatrick       }
2832061da546Spatrick     }
2833061da546Spatrick 
2834be691f3bSpatrick     // The ObjC runtime knows the byte offset but we still need to provide
2835be691f3bSpatrick     // the bit-offset in the layout. It just means something different then
2836be691f3bSpatrick     // what it does in C and C++. So we skip this check for ObjC types.
2837be691f3bSpatrick     //
2838be691f3bSpatrick     // We also skip this for fields of a union since they will all have a
2839be691f3bSpatrick     // zero offset.
2840be691f3bSpatrick     if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) &&
2841*f6aab3d8Srobert         !(parent_die.Tag() == DW_TAG_union_type &&
2842*f6aab3d8Srobert           this_field_info.bit_offset == 0) &&
2843be691f3bSpatrick         ((this_field_info.bit_offset >= parent_bit_size) ||
2844061da546Spatrick          (last_field_info.IsBitfield() &&
2845061da546Spatrick           !last_field_info.NextBitfieldOffsetIsValid(
2846be691f3bSpatrick               this_field_info.bit_offset)))) {
2847061da546Spatrick       ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
2848061da546Spatrick       objfile->GetModule()->ReportWarning(
2849*f6aab3d8Srobert           "{0:x16}: {1} bitfield named \"{2}\" has invalid "
2850*f6aab3d8Srobert           "bit offset ({3:x8}) member will be ignored. Please file a bug "
2851*f6aab3d8Srobert           "against the "
2852*f6aab3d8Srobert           "compiler and include the preprocessed output for {4}\n",
2853*f6aab3d8Srobert           die.GetID(), DW_TAG_value_to_name(tag), attrs.name,
2854061da546Spatrick           this_field_info.bit_offset, GetUnitName(parent_die).c_str());
2855061da546Spatrick       return;
2856061da546Spatrick     }
2857061da546Spatrick 
2858061da546Spatrick     // Update the field bit offset we will report for layout
2859061da546Spatrick     field_bit_offset = this_field_info.bit_offset;
2860061da546Spatrick 
2861061da546Spatrick     // Objective-C has invalid DW_AT_bit_offset values in older
2862061da546Spatrick     // versions of clang, so we have to be careful and only insert
2863061da546Spatrick     // unnamed bitfields if we have a new enough clang.
2864061da546Spatrick     bool detect_unnamed_bitfields = true;
2865061da546Spatrick 
2866dda28197Spatrick     if (class_is_objc_object_or_interface)
2867061da546Spatrick       detect_unnamed_bitfields =
2868061da546Spatrick           die.GetCU()->Supports_unnamed_objc_bitfields();
2869061da546Spatrick 
2870061da546Spatrick     if (detect_unnamed_bitfields) {
2871*f6aab3d8Srobert       std::optional<FieldInfo> unnamed_field_info;
2872061da546Spatrick       uint64_t last_field_end = 0;
2873061da546Spatrick 
2874*f6aab3d8Srobert       last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
2875061da546Spatrick 
2876061da546Spatrick       if (!last_field_info.IsBitfield()) {
2877061da546Spatrick         // The last field was not a bit-field...
2878061da546Spatrick         // but if it did take up the entire word then we need to extend
2879061da546Spatrick         // last_field_end so the bit-field does not step into the last
2880061da546Spatrick         // fields padding.
2881061da546Spatrick         if (last_field_end != 0 && ((last_field_end % word_width) != 0))
2882061da546Spatrick           last_field_end += word_width - (last_field_end % word_width);
2883061da546Spatrick       }
2884061da546Spatrick 
2885061da546Spatrick       // If we have a gap between the last_field_end and the current
2886dda28197Spatrick       // field we have an unnamed bit-field.
2887dda28197Spatrick       // If we have a base class, we assume there is no unnamed
2888dda28197Spatrick       // bit-field if this is the first field since the gap can be
2889dda28197Spatrick       // attributed to the members from the base class. This assumption
2890dda28197Spatrick       // is not correct if the first field of the derived class is
2891dda28197Spatrick       // indeed an unnamed bit-field. We currently do not have the
2892dda28197Spatrick       // machinary to track the offset of the last field of classes we
2893dda28197Spatrick       // have seen before, so we are not handling this case.
2894061da546Spatrick       if (this_field_info.bit_offset != last_field_end &&
2895dda28197Spatrick           this_field_info.bit_offset > last_field_end &&
2896dda28197Spatrick           !(last_field_info.bit_offset == 0 &&
2897dda28197Spatrick             last_field_info.bit_size == 0 &&
2898dda28197Spatrick             layout_info.base_offsets.size() != 0)) {
2899061da546Spatrick         unnamed_field_info = FieldInfo{};
2900061da546Spatrick         unnamed_field_info->bit_size =
2901061da546Spatrick             this_field_info.bit_offset - last_field_end;
2902061da546Spatrick         unnamed_field_info->bit_offset = last_field_end;
2903061da546Spatrick       }
2904061da546Spatrick 
2905061da546Spatrick       if (unnamed_field_info) {
2906061da546Spatrick         clang::FieldDecl *unnamed_bitfield_decl =
2907dda28197Spatrick             TypeSystemClang::AddFieldToRecordType(
2908061da546Spatrick                 class_clang_type, llvm::StringRef(),
2909061da546Spatrick                 m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
2910061da546Spatrick                                                           word_width),
2911*f6aab3d8Srobert                 attrs.accessibility, unnamed_field_info->bit_size);
2912061da546Spatrick 
2913061da546Spatrick         layout_info.field_offsets.insert(std::make_pair(
2914061da546Spatrick             unnamed_bitfield_decl, unnamed_field_info->bit_offset));
2915061da546Spatrick       }
2916061da546Spatrick     }
2917061da546Spatrick 
2918061da546Spatrick     last_field_info = this_field_info;
2919061da546Spatrick     last_field_info.SetIsBitfield(true);
2920061da546Spatrick   } else {
2921061da546Spatrick     last_field_info.bit_offset = field_bit_offset;
2922061da546Spatrick 
2923*f6aab3d8Srobert     if (std::optional<uint64_t> clang_type_size =
2924be691f3bSpatrick             member_type->GetByteSize(nullptr)) {
2925061da546Spatrick       last_field_info.bit_size = *clang_type_size * character_width;
2926061da546Spatrick     }
2927061da546Spatrick 
2928061da546Spatrick     last_field_info.SetIsBitfield(false);
2929061da546Spatrick   }
2930061da546Spatrick 
2931*f6aab3d8Srobert   // Don't turn artificial members such as vtable pointers into real FieldDecls
2932*f6aab3d8Srobert   // in our AST. Clang will re-create those articial members and they would
2933*f6aab3d8Srobert   // otherwise just overlap in the layout with the FieldDecls we add here.
2934*f6aab3d8Srobert   // This needs to be done after updating FieldInfo which keeps track of where
2935*f6aab3d8Srobert   // field start/end so we don't later try to fill the the space of this
2936*f6aab3d8Srobert   // artificial member with (unnamed bitfield) padding.
2937*f6aab3d8Srobert   // FIXME: This check should verify that this is indeed an artificial member
2938*f6aab3d8Srobert   // we are supposed to ignore.
2939*f6aab3d8Srobert   if (attrs.is_artificial)
2940*f6aab3d8Srobert     return;
2941*f6aab3d8Srobert 
2942061da546Spatrick   if (!member_clang_type.IsCompleteType())
2943061da546Spatrick     member_clang_type.GetCompleteType();
2944061da546Spatrick 
2945061da546Spatrick   {
2946061da546Spatrick     // Older versions of clang emit array[0] and array[1] in the
2947061da546Spatrick     // same way (<rdar://problem/12566646>). If the current field
2948061da546Spatrick     // is at the end of the structure, then there is definitely no
2949061da546Spatrick     // room for extra elements and we override the type to
2950061da546Spatrick     // array[0].
2951061da546Spatrick 
2952061da546Spatrick     CompilerType member_array_element_type;
2953061da546Spatrick     uint64_t member_array_size;
2954061da546Spatrick     bool member_array_is_incomplete;
2955061da546Spatrick 
2956061da546Spatrick     if (member_clang_type.IsArrayType(&member_array_element_type,
2957061da546Spatrick                                       &member_array_size,
2958061da546Spatrick                                       &member_array_is_incomplete) &&
2959061da546Spatrick         !member_array_is_incomplete) {
2960061da546Spatrick       uint64_t parent_byte_size =
2961*f6aab3d8Srobert           parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
2962061da546Spatrick 
2963*f6aab3d8Srobert       if (attrs.member_byte_offset >= parent_byte_size) {
2964061da546Spatrick         if (member_array_size != 1 &&
2965061da546Spatrick             (member_array_size != 0 ||
2966*f6aab3d8Srobert              attrs.member_byte_offset > parent_byte_size)) {
2967061da546Spatrick           module_sp->ReportError(
2968*f6aab3d8Srobert               "{0:x8}: DW_TAG_member '{1}' refers to type {2:x16}"
2969*f6aab3d8Srobert               " which extends beyond the bounds of {3:x8}",
2970*f6aab3d8Srobert               die.GetID(), attrs.name,
2971*f6aab3d8Srobert               attrs.encoding_form.Reference().GetOffset(), parent_die.GetID());
2972061da546Spatrick         }
2973061da546Spatrick 
2974061da546Spatrick         member_clang_type =
2975061da546Spatrick             m_ast.CreateArrayType(member_array_element_type, 0, false);
2976061da546Spatrick       }
2977061da546Spatrick     }
2978061da546Spatrick   }
2979061da546Spatrick 
2980*f6aab3d8Srobert   TypeSystemClang::RequireCompleteType(member_clang_type);
2981061da546Spatrick 
2982*f6aab3d8Srobert   clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType(
2983*f6aab3d8Srobert       class_clang_type, attrs.name, member_clang_type, attrs.accessibility,
2984*f6aab3d8Srobert       attrs.bit_size);
2985061da546Spatrick 
2986061da546Spatrick   m_ast.SetMetadataAsUserID(field_decl, die.GetID());
2987061da546Spatrick 
2988061da546Spatrick   layout_info.field_offsets.insert(
2989061da546Spatrick       std::make_pair(field_decl, field_bit_offset));
2990061da546Spatrick }
2991061da546Spatrick 
ParseChildMembers(const DWARFDIE & parent_die,CompilerType & class_clang_type,std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> & base_classes,std::vector<DWARFDIE> & member_function_dies,DelayedPropertyList & delayed_properties,const AccessType default_accessibility,ClangASTImporter::LayoutInfo & layout_info)2992061da546Spatrick bool DWARFASTParserClang::ParseChildMembers(
2993061da546Spatrick     const DWARFDIE &parent_die, CompilerType &class_clang_type,
2994061da546Spatrick     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
2995061da546Spatrick     std::vector<DWARFDIE> &member_function_dies,
2996*f6aab3d8Srobert     DelayedPropertyList &delayed_properties,
2997*f6aab3d8Srobert     const AccessType default_accessibility,
2998be691f3bSpatrick     ClangASTImporter::LayoutInfo &layout_info) {
2999061da546Spatrick   if (!parent_die)
3000061da546Spatrick     return false;
3001061da546Spatrick 
3002061da546Spatrick   FieldInfo last_field_info;
3003061da546Spatrick 
3004061da546Spatrick   ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
3005*f6aab3d8Srobert   auto ts = class_clang_type.GetTypeSystem();
3006*f6aab3d8Srobert   auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
3007061da546Spatrick   if (ast == nullptr)
3008061da546Spatrick     return false;
3009061da546Spatrick 
3010be691f3bSpatrick   for (DWARFDIE die : parent_die.children()) {
3011061da546Spatrick     dw_tag_t tag = die.Tag();
3012061da546Spatrick 
3013061da546Spatrick     switch (tag) {
3014061da546Spatrick     case DW_TAG_APPLE_property:
3015*f6aab3d8Srobert       ParseObjCProperty(die, parent_die, class_clang_type, delayed_properties);
3016*f6aab3d8Srobert       break;
3017*f6aab3d8Srobert 
3018*f6aab3d8Srobert     case DW_TAG_member:
3019dda28197Spatrick       ParseSingleMember(die, parent_die, class_clang_type,
3020*f6aab3d8Srobert                         default_accessibility, layout_info, last_field_info);
3021061da546Spatrick       break;
3022061da546Spatrick 
3023061da546Spatrick     case DW_TAG_subprogram:
3024061da546Spatrick       // Let the type parsing code handle this one for us.
3025061da546Spatrick       member_function_dies.push_back(die);
3026061da546Spatrick       break;
3027061da546Spatrick 
3028*f6aab3d8Srobert     case DW_TAG_inheritance:
3029*f6aab3d8Srobert       ParseInheritance(die, parent_die, class_clang_type, default_accessibility,
3030*f6aab3d8Srobert                        module_sp, base_classes, layout_info);
3031061da546Spatrick       break;
3032061da546Spatrick 
3033061da546Spatrick     default:
3034061da546Spatrick       break;
3035061da546Spatrick     }
3036061da546Spatrick   }
3037061da546Spatrick 
3038061da546Spatrick   return true;
3039061da546Spatrick }
3040061da546Spatrick 
ParseChildParameters(clang::DeclContext * containing_decl_ctx,const DWARFDIE & parent_die,bool skip_artificial,bool & is_static,bool & is_variadic,bool & has_template_params,std::vector<CompilerType> & function_param_types,std::vector<clang::ParmVarDecl * > & function_param_decls,unsigned & type_quals)3041061da546Spatrick size_t DWARFASTParserClang::ParseChildParameters(
3042061da546Spatrick     clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,
3043061da546Spatrick     bool skip_artificial, bool &is_static, bool &is_variadic,
3044061da546Spatrick     bool &has_template_params, std::vector<CompilerType> &function_param_types,
3045061da546Spatrick     std::vector<clang::ParmVarDecl *> &function_param_decls,
3046061da546Spatrick     unsigned &type_quals) {
3047061da546Spatrick   if (!parent_die)
3048061da546Spatrick     return 0;
3049061da546Spatrick 
3050061da546Spatrick   size_t arg_idx = 0;
3051be691f3bSpatrick   for (DWARFDIE die : parent_die.children()) {
3052061da546Spatrick     const dw_tag_t tag = die.Tag();
3053061da546Spatrick     switch (tag) {
3054061da546Spatrick     case DW_TAG_formal_parameter: {
3055061da546Spatrick       DWARFAttributes attributes;
3056061da546Spatrick       const size_t num_attributes = die.GetAttributes(attributes);
3057061da546Spatrick       if (num_attributes > 0) {
3058061da546Spatrick         const char *name = nullptr;
3059061da546Spatrick         DWARFFormValue param_type_die_form;
3060061da546Spatrick         bool is_artificial = false;
3061061da546Spatrick         // one of None, Auto, Register, Extern, Static, PrivateExtern
3062061da546Spatrick 
3063061da546Spatrick         clang::StorageClass storage = clang::SC_None;
3064061da546Spatrick         uint32_t i;
3065061da546Spatrick         for (i = 0; i < num_attributes; ++i) {
3066061da546Spatrick           const dw_attr_t attr = attributes.AttributeAtIndex(i);
3067061da546Spatrick           DWARFFormValue form_value;
3068061da546Spatrick           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
3069061da546Spatrick             switch (attr) {
3070061da546Spatrick             case DW_AT_name:
3071061da546Spatrick               name = form_value.AsCString();
3072061da546Spatrick               break;
3073061da546Spatrick             case DW_AT_type:
3074061da546Spatrick               param_type_die_form = form_value;
3075061da546Spatrick               break;
3076061da546Spatrick             case DW_AT_artificial:
3077061da546Spatrick               is_artificial = form_value.Boolean();
3078061da546Spatrick               break;
3079061da546Spatrick             case DW_AT_location:
3080061da546Spatrick             case DW_AT_const_value:
3081061da546Spatrick             case DW_AT_default_value:
3082061da546Spatrick             case DW_AT_description:
3083061da546Spatrick             case DW_AT_endianity:
3084061da546Spatrick             case DW_AT_is_optional:
3085061da546Spatrick             case DW_AT_segment:
3086061da546Spatrick             case DW_AT_variable_parameter:
3087061da546Spatrick             default:
3088061da546Spatrick             case DW_AT_abstract_origin:
3089061da546Spatrick             case DW_AT_sibling:
3090061da546Spatrick               break;
3091061da546Spatrick             }
3092061da546Spatrick           }
3093061da546Spatrick         }
3094061da546Spatrick 
3095061da546Spatrick         bool skip = false;
3096061da546Spatrick         if (skip_artificial && is_artificial) {
3097061da546Spatrick           // In order to determine if a C++ member function is "const" we
3098061da546Spatrick           // have to look at the const-ness of "this"...
3099061da546Spatrick           if (arg_idx == 0 &&
3100061da546Spatrick               DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) &&
3101061da546Spatrick               // Often times compilers omit the "this" name for the
3102061da546Spatrick               // specification DIEs, so we can't rely upon the name being in
3103061da546Spatrick               // the formal parameter DIE...
3104061da546Spatrick               (name == nullptr || ::strcmp(name, "this") == 0)) {
3105061da546Spatrick             Type *this_type =
3106061da546Spatrick                 die.ResolveTypeUID(param_type_die_form.Reference());
3107061da546Spatrick             if (this_type) {
3108061da546Spatrick               uint32_t encoding_mask = this_type->GetEncodingMask();
3109061da546Spatrick               if (encoding_mask & Type::eEncodingIsPointerUID) {
3110061da546Spatrick                 is_static = false;
3111061da546Spatrick 
3112061da546Spatrick                 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3113061da546Spatrick                   type_quals |= clang::Qualifiers::Const;
3114061da546Spatrick                 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3115061da546Spatrick                   type_quals |= clang::Qualifiers::Volatile;
3116061da546Spatrick               }
3117061da546Spatrick             }
3118061da546Spatrick           }
3119061da546Spatrick           skip = true;
3120061da546Spatrick         }
3121061da546Spatrick 
3122061da546Spatrick         if (!skip) {
3123061da546Spatrick           Type *type = die.ResolveTypeUID(param_type_die_form.Reference());
3124061da546Spatrick           if (type) {
3125061da546Spatrick             function_param_types.push_back(type->GetForwardCompilerType());
3126061da546Spatrick 
3127061da546Spatrick             clang::ParmVarDecl *param_var_decl =
3128dda28197Spatrick                 m_ast.CreateParameterDeclaration(
3129dda28197Spatrick                     containing_decl_ctx, GetOwningClangModule(die), name,
3130dda28197Spatrick                     type->GetForwardCompilerType(), storage);
3131061da546Spatrick             assert(param_var_decl);
3132061da546Spatrick             function_param_decls.push_back(param_var_decl);
3133061da546Spatrick 
3134061da546Spatrick             m_ast.SetMetadataAsUserID(param_var_decl, die.GetID());
3135061da546Spatrick           }
3136061da546Spatrick         }
3137061da546Spatrick       }
3138061da546Spatrick       arg_idx++;
3139061da546Spatrick     } break;
3140061da546Spatrick 
3141061da546Spatrick     case DW_TAG_unspecified_parameters:
3142061da546Spatrick       is_variadic = true;
3143061da546Spatrick       break;
3144061da546Spatrick 
3145061da546Spatrick     case DW_TAG_template_type_parameter:
3146061da546Spatrick     case DW_TAG_template_value_parameter:
3147061da546Spatrick     case DW_TAG_GNU_template_parameter_pack:
3148061da546Spatrick       // The one caller of this was never using the template_param_infos, and
3149061da546Spatrick       // the local variable was taking up a large amount of stack space in
3150061da546Spatrick       // SymbolFileDWARF::ParseType() so this was removed. If we ever need the
3151061da546Spatrick       // template params back, we can add them back.
3152061da546Spatrick       // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
3153061da546Spatrick       has_template_params = true;
3154061da546Spatrick       break;
3155061da546Spatrick 
3156061da546Spatrick     default:
3157061da546Spatrick       break;
3158061da546Spatrick     }
3159061da546Spatrick   }
3160061da546Spatrick   return arg_idx;
3161061da546Spatrick }
3162061da546Spatrick 
GetTypeForDIE(const DWARFDIE & die)3163061da546Spatrick Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
3164061da546Spatrick   if (die) {
3165061da546Spatrick     SymbolFileDWARF *dwarf = die.GetDWARF();
3166061da546Spatrick     DWARFAttributes attributes;
3167061da546Spatrick     const size_t num_attributes = die.GetAttributes(attributes);
3168061da546Spatrick     if (num_attributes > 0) {
3169061da546Spatrick       DWARFFormValue type_die_form;
3170061da546Spatrick       for (size_t i = 0; i < num_attributes; ++i) {
3171061da546Spatrick         dw_attr_t attr = attributes.AttributeAtIndex(i);
3172061da546Spatrick         DWARFFormValue form_value;
3173061da546Spatrick 
3174061da546Spatrick         if (attr == DW_AT_type &&
3175061da546Spatrick             attributes.ExtractFormValueAtIndex(i, form_value))
3176061da546Spatrick           return dwarf->ResolveTypeUID(form_value.Reference(), true);
3177061da546Spatrick       }
3178061da546Spatrick     }
3179061da546Spatrick   }
3180061da546Spatrick 
3181061da546Spatrick   return nullptr;
3182061da546Spatrick }
3183061da546Spatrick 
GetClangDeclForDIE(const DWARFDIE & die)3184061da546Spatrick clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
3185061da546Spatrick   if (!die)
3186061da546Spatrick     return nullptr;
3187061da546Spatrick 
3188061da546Spatrick   switch (die.Tag()) {
3189061da546Spatrick   case DW_TAG_variable:
3190061da546Spatrick   case DW_TAG_constant:
3191061da546Spatrick   case DW_TAG_formal_parameter:
3192061da546Spatrick   case DW_TAG_imported_declaration:
3193061da546Spatrick   case DW_TAG_imported_module:
3194061da546Spatrick     break;
3195061da546Spatrick   default:
3196061da546Spatrick     return nullptr;
3197061da546Spatrick   }
3198061da546Spatrick 
3199061da546Spatrick   DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
3200061da546Spatrick   if (cache_pos != m_die_to_decl.end())
3201061da546Spatrick     return cache_pos->second;
3202061da546Spatrick 
3203061da546Spatrick   if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
3204061da546Spatrick     clang::Decl *decl = GetClangDeclForDIE(spec_die);
3205061da546Spatrick     m_die_to_decl[die.GetDIE()] = decl;
3206061da546Spatrick     return decl;
3207061da546Spatrick   }
3208061da546Spatrick 
3209061da546Spatrick   if (DWARFDIE abstract_origin_die =
3210061da546Spatrick           die.GetReferencedDIE(DW_AT_abstract_origin)) {
3211061da546Spatrick     clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
3212061da546Spatrick     m_die_to_decl[die.GetDIE()] = decl;
3213061da546Spatrick     return decl;
3214061da546Spatrick   }
3215061da546Spatrick 
3216061da546Spatrick   clang::Decl *decl = nullptr;
3217061da546Spatrick   switch (die.Tag()) {
3218061da546Spatrick   case DW_TAG_variable:
3219061da546Spatrick   case DW_TAG_constant:
3220061da546Spatrick   case DW_TAG_formal_parameter: {
3221061da546Spatrick     SymbolFileDWARF *dwarf = die.GetDWARF();
3222061da546Spatrick     Type *type = GetTypeForDIE(die);
3223061da546Spatrick     if (dwarf && type) {
3224061da546Spatrick       const char *name = die.GetName();
3225061da546Spatrick       clang::DeclContext *decl_context =
3226dda28197Spatrick           TypeSystemClang::DeclContextGetAsDeclContext(
3227061da546Spatrick               dwarf->GetDeclContextContainingUID(die.GetID()));
3228061da546Spatrick       decl = m_ast.CreateVariableDeclaration(
3229dda28197Spatrick           decl_context, GetOwningClangModule(die), name,
3230061da546Spatrick           ClangUtil::GetQualType(type->GetForwardCompilerType()));
3231061da546Spatrick     }
3232061da546Spatrick     break;
3233061da546Spatrick   }
3234061da546Spatrick   case DW_TAG_imported_declaration: {
3235061da546Spatrick     SymbolFileDWARF *dwarf = die.GetDWARF();
3236061da546Spatrick     DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
3237061da546Spatrick     if (imported_uid) {
3238dda28197Spatrick       CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid);
3239061da546Spatrick       if (imported_decl) {
3240061da546Spatrick         clang::DeclContext *decl_context =
3241dda28197Spatrick             TypeSystemClang::DeclContextGetAsDeclContext(
3242061da546Spatrick                 dwarf->GetDeclContextContainingUID(die.GetID()));
3243061da546Spatrick         if (clang::NamedDecl *clang_imported_decl =
3244061da546Spatrick                 llvm::dyn_cast<clang::NamedDecl>(
3245061da546Spatrick                     (clang::Decl *)imported_decl.GetOpaqueDecl()))
3246dda28197Spatrick           decl = m_ast.CreateUsingDeclaration(
3247dda28197Spatrick               decl_context, OptionalClangModuleID(), clang_imported_decl);
3248061da546Spatrick       }
3249061da546Spatrick     }
3250061da546Spatrick     break;
3251061da546Spatrick   }
3252061da546Spatrick   case DW_TAG_imported_module: {
3253061da546Spatrick     SymbolFileDWARF *dwarf = die.GetDWARF();
3254061da546Spatrick     DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
3255061da546Spatrick 
3256061da546Spatrick     if (imported_uid) {
3257dda28197Spatrick       CompilerDeclContext imported_decl_ctx =
3258dda28197Spatrick           SymbolFileDWARF::GetDeclContext(imported_uid);
3259061da546Spatrick       if (imported_decl_ctx) {
3260061da546Spatrick         clang::DeclContext *decl_context =
3261dda28197Spatrick             TypeSystemClang::DeclContextGetAsDeclContext(
3262061da546Spatrick                 dwarf->GetDeclContextContainingUID(die.GetID()));
3263061da546Spatrick         if (clang::NamespaceDecl *ns_decl =
3264dda28197Spatrick                 TypeSystemClang::DeclContextGetAsNamespaceDecl(
3265061da546Spatrick                     imported_decl_ctx))
3266dda28197Spatrick           decl = m_ast.CreateUsingDirectiveDeclaration(
3267dda28197Spatrick               decl_context, OptionalClangModuleID(), ns_decl);
3268061da546Spatrick       }
3269061da546Spatrick     }
3270061da546Spatrick     break;
3271061da546Spatrick   }
3272061da546Spatrick   default:
3273061da546Spatrick     break;
3274061da546Spatrick   }
3275061da546Spatrick 
3276061da546Spatrick   m_die_to_decl[die.GetDIE()] = decl;
3277061da546Spatrick 
3278061da546Spatrick   return decl;
3279061da546Spatrick }
3280061da546Spatrick 
3281061da546Spatrick clang::DeclContext *
GetClangDeclContextForDIE(const DWARFDIE & die)3282061da546Spatrick DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
3283061da546Spatrick   if (die) {
3284061da546Spatrick     clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die);
3285061da546Spatrick     if (decl_ctx)
3286061da546Spatrick       return decl_ctx;
3287061da546Spatrick 
3288061da546Spatrick     bool try_parsing_type = true;
3289061da546Spatrick     switch (die.Tag()) {
3290061da546Spatrick     case DW_TAG_compile_unit:
3291061da546Spatrick     case DW_TAG_partial_unit:
3292061da546Spatrick       decl_ctx = m_ast.GetTranslationUnitDecl();
3293061da546Spatrick       try_parsing_type = false;
3294061da546Spatrick       break;
3295061da546Spatrick 
3296061da546Spatrick     case DW_TAG_namespace:
3297061da546Spatrick       decl_ctx = ResolveNamespaceDIE(die);
3298061da546Spatrick       try_parsing_type = false;
3299061da546Spatrick       break;
3300061da546Spatrick 
3301061da546Spatrick     case DW_TAG_lexical_block:
3302061da546Spatrick       decl_ctx = GetDeclContextForBlock(die);
3303061da546Spatrick       try_parsing_type = false;
3304061da546Spatrick       break;
3305061da546Spatrick 
3306061da546Spatrick     default:
3307061da546Spatrick       break;
3308061da546Spatrick     }
3309061da546Spatrick 
3310061da546Spatrick     if (decl_ctx == nullptr && try_parsing_type) {
3311061da546Spatrick       Type *type = die.GetDWARF()->ResolveType(die);
3312061da546Spatrick       if (type)
3313061da546Spatrick         decl_ctx = GetCachedClangDeclContextForDIE(die);
3314061da546Spatrick     }
3315061da546Spatrick 
3316061da546Spatrick     if (decl_ctx) {
3317061da546Spatrick       LinkDeclContextToDIE(decl_ctx, die);
3318061da546Spatrick       return decl_ctx;
3319061da546Spatrick     }
3320061da546Spatrick   }
3321061da546Spatrick   return nullptr;
3322061da546Spatrick }
3323061da546Spatrick 
3324dda28197Spatrick OptionalClangModuleID
GetOwningClangModule(const DWARFDIE & die)3325dda28197Spatrick DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
3326dda28197Spatrick   if (!die.IsValid())
3327dda28197Spatrick     return {};
3328dda28197Spatrick 
3329dda28197Spatrick   for (DWARFDIE parent = die.GetParent(); parent.IsValid();
3330dda28197Spatrick        parent = parent.GetParent()) {
3331dda28197Spatrick     const dw_tag_t tag = parent.Tag();
3332dda28197Spatrick     if (tag == DW_TAG_module) {
3333dda28197Spatrick       DWARFDIE module_die = parent;
3334dda28197Spatrick       auto it = m_die_to_module.find(module_die.GetDIE());
3335dda28197Spatrick       if (it != m_die_to_module.end())
3336dda28197Spatrick         return it->second;
3337*f6aab3d8Srobert       const char *name =
3338*f6aab3d8Srobert           module_die.GetAttributeValueAsString(DW_AT_name, nullptr);
3339dda28197Spatrick       if (!name)
3340dda28197Spatrick         return {};
3341dda28197Spatrick 
3342dda28197Spatrick       OptionalClangModuleID id =
3343dda28197Spatrick           m_ast.GetOrCreateClangModule(name, GetOwningClangModule(module_die));
3344dda28197Spatrick       m_die_to_module.insert({module_die.GetDIE(), id});
3345dda28197Spatrick       return id;
3346dda28197Spatrick     }
3347dda28197Spatrick   }
3348dda28197Spatrick   return {};
3349dda28197Spatrick }
3350dda28197Spatrick 
IsSubroutine(const DWARFDIE & die)3351061da546Spatrick static bool IsSubroutine(const DWARFDIE &die) {
3352061da546Spatrick   switch (die.Tag()) {
3353061da546Spatrick   case DW_TAG_subprogram:
3354061da546Spatrick   case DW_TAG_inlined_subroutine:
3355061da546Spatrick     return true;
3356061da546Spatrick   default:
3357061da546Spatrick     return false;
3358061da546Spatrick   }
3359061da546Spatrick }
3360061da546Spatrick 
GetContainingFunctionWithAbstractOrigin(const DWARFDIE & die)3361061da546Spatrick static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {
3362061da546Spatrick   for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) {
3363061da546Spatrick     if (IsSubroutine(candidate)) {
3364061da546Spatrick       if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
3365061da546Spatrick         return candidate;
3366061da546Spatrick       } else {
3367061da546Spatrick         return DWARFDIE();
3368061da546Spatrick       }
3369061da546Spatrick     }
3370061da546Spatrick   }
3371061da546Spatrick   assert(0 && "Shouldn't call GetContainingFunctionWithAbstractOrigin on "
3372061da546Spatrick               "something not in a function");
3373061da546Spatrick   return DWARFDIE();
3374061da546Spatrick }
3375061da546Spatrick 
FindAnyChildWithAbstractOrigin(const DWARFDIE & context)3376061da546Spatrick static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
3377be691f3bSpatrick   for (DWARFDIE candidate : context.children()) {
3378061da546Spatrick     if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
3379061da546Spatrick       return candidate;
3380061da546Spatrick     }
3381061da546Spatrick   }
3382061da546Spatrick   return DWARFDIE();
3383061da546Spatrick }
3384061da546Spatrick 
FindFirstChildWithAbstractOrigin(const DWARFDIE & block,const DWARFDIE & function)3385061da546Spatrick static DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block,
3386061da546Spatrick                                                  const DWARFDIE &function) {
3387061da546Spatrick   assert(IsSubroutine(function));
3388061da546Spatrick   for (DWARFDIE context = block; context != function.GetParent();
3389061da546Spatrick        context = context.GetParent()) {
3390061da546Spatrick     assert(!IsSubroutine(context) || context == function);
3391061da546Spatrick     if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) {
3392061da546Spatrick       return child;
3393061da546Spatrick     }
3394061da546Spatrick   }
3395061da546Spatrick   return DWARFDIE();
3396061da546Spatrick }
3397061da546Spatrick 
3398061da546Spatrick clang::DeclContext *
GetDeclContextForBlock(const DWARFDIE & die)3399061da546Spatrick DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) {
3400061da546Spatrick   assert(die.Tag() == DW_TAG_lexical_block);
3401061da546Spatrick   DWARFDIE containing_function_with_abstract_origin =
3402061da546Spatrick       GetContainingFunctionWithAbstractOrigin(die);
3403061da546Spatrick   if (!containing_function_with_abstract_origin) {
3404061da546Spatrick     return (clang::DeclContext *)ResolveBlockDIE(die);
3405061da546Spatrick   }
3406061da546Spatrick   DWARFDIE child = FindFirstChildWithAbstractOrigin(
3407061da546Spatrick       die, containing_function_with_abstract_origin);
3408061da546Spatrick   CompilerDeclContext decl_context =
3409061da546Spatrick       GetDeclContextContainingUIDFromDWARF(child);
3410061da546Spatrick   return (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
3411061da546Spatrick }
3412061da546Spatrick 
ResolveBlockDIE(const DWARFDIE & die)3413061da546Spatrick clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
3414061da546Spatrick   if (die && die.Tag() == DW_TAG_lexical_block) {
3415061da546Spatrick     clang::BlockDecl *decl =
3416061da546Spatrick         llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
3417061da546Spatrick 
3418061da546Spatrick     if (!decl) {
3419061da546Spatrick       DWARFDIE decl_context_die;
3420061da546Spatrick       clang::DeclContext *decl_context =
3421061da546Spatrick           GetClangDeclContextContainingDIE(die, &decl_context_die);
3422dda28197Spatrick       decl =
3423dda28197Spatrick           m_ast.CreateBlockDeclaration(decl_context, GetOwningClangModule(die));
3424061da546Spatrick 
3425061da546Spatrick       if (decl)
3426061da546Spatrick         LinkDeclContextToDIE((clang::DeclContext *)decl, die);
3427061da546Spatrick     }
3428061da546Spatrick 
3429061da546Spatrick     return decl;
3430061da546Spatrick   }
3431061da546Spatrick   return nullptr;
3432061da546Spatrick }
3433061da546Spatrick 
3434061da546Spatrick clang::NamespaceDecl *
ResolveNamespaceDIE(const DWARFDIE & die)3435061da546Spatrick DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
3436061da546Spatrick   if (die && die.Tag() == DW_TAG_namespace) {
3437061da546Spatrick     // See if we already parsed this namespace DIE and associated it with a
3438061da546Spatrick     // uniqued namespace declaration
3439061da546Spatrick     clang::NamespaceDecl *namespace_decl =
3440061da546Spatrick         static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
3441061da546Spatrick     if (namespace_decl)
3442061da546Spatrick       return namespace_decl;
3443061da546Spatrick     else {
3444061da546Spatrick       const char *namespace_name = die.GetName();
3445061da546Spatrick       clang::DeclContext *containing_decl_ctx =
3446061da546Spatrick           GetClangDeclContextContainingDIE(die, nullptr);
3447061da546Spatrick       bool is_inline =
3448061da546Spatrick           die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
3449061da546Spatrick 
3450061da546Spatrick       namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
3451dda28197Spatrick           namespace_name, containing_decl_ctx, GetOwningClangModule(die),
3452dda28197Spatrick           is_inline);
3453061da546Spatrick 
3454061da546Spatrick       if (namespace_decl)
3455061da546Spatrick         LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die);
3456061da546Spatrick       return namespace_decl;
3457061da546Spatrick     }
3458061da546Spatrick   }
3459061da546Spatrick   return nullptr;
3460061da546Spatrick }
3461061da546Spatrick 
GetClangDeclContextContainingDIE(const DWARFDIE & die,DWARFDIE * decl_ctx_die_copy)3462061da546Spatrick clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
3463061da546Spatrick     const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
3464061da546Spatrick   SymbolFileDWARF *dwarf = die.GetDWARF();
3465061da546Spatrick 
3466061da546Spatrick   DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);
3467061da546Spatrick 
3468061da546Spatrick   if (decl_ctx_die_copy)
3469061da546Spatrick     *decl_ctx_die_copy = decl_ctx_die;
3470061da546Spatrick 
3471061da546Spatrick   if (decl_ctx_die) {
3472061da546Spatrick     clang::DeclContext *clang_decl_ctx =
3473061da546Spatrick         GetClangDeclContextForDIE(decl_ctx_die);
3474061da546Spatrick     if (clang_decl_ctx)
3475061da546Spatrick       return clang_decl_ctx;
3476061da546Spatrick   }
3477061da546Spatrick   return m_ast.GetTranslationUnitDecl();
3478061da546Spatrick }
3479061da546Spatrick 
3480061da546Spatrick clang::DeclContext *
GetCachedClangDeclContextForDIE(const DWARFDIE & die)3481061da546Spatrick DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {
3482061da546Spatrick   if (die) {
3483061da546Spatrick     DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
3484061da546Spatrick     if (pos != m_die_to_decl_ctx.end())
3485061da546Spatrick       return pos->second;
3486061da546Spatrick   }
3487061da546Spatrick   return nullptr;
3488061da546Spatrick }
3489061da546Spatrick 
LinkDeclContextToDIE(clang::DeclContext * decl_ctx,const DWARFDIE & die)3490061da546Spatrick void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
3491061da546Spatrick                                                const DWARFDIE &die) {
3492061da546Spatrick   m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
3493061da546Spatrick   // There can be many DIEs for a single decl context
3494061da546Spatrick   // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
3495061da546Spatrick   m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
3496061da546Spatrick }
3497061da546Spatrick 
CopyUniqueClassMethodTypes(const DWARFDIE & src_class_die,const DWARFDIE & dst_class_die,lldb_private::Type * class_type,std::vector<DWARFDIE> & failures)3498061da546Spatrick bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
3499061da546Spatrick     const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die,
3500061da546Spatrick     lldb_private::Type *class_type, std::vector<DWARFDIE> &failures) {
3501061da546Spatrick   if (!class_type || !src_class_die || !dst_class_die)
3502061da546Spatrick     return false;
3503061da546Spatrick   if (src_class_die.Tag() != dst_class_die.Tag())
3504061da546Spatrick     return false;
3505061da546Spatrick 
3506061da546Spatrick   // We need to complete the class type so we can get all of the method types
3507061da546Spatrick   // parsed so we can then unique those types to their equivalent counterparts
3508061da546Spatrick   // in "dst_cu" and "dst_class_die"
3509061da546Spatrick   class_type->GetFullCompilerType();
3510061da546Spatrick 
3511*f6aab3d8Srobert   auto gather = [](DWARFDIE die, UniqueCStringMap<DWARFDIE> &map,
3512*f6aab3d8Srobert                    UniqueCStringMap<DWARFDIE> &map_artificial) {
3513*f6aab3d8Srobert     if (die.Tag() != DW_TAG_subprogram)
3514*f6aab3d8Srobert       return;
3515*f6aab3d8Srobert     // Make sure this is a declaration and not a concrete instance by looking
3516*f6aab3d8Srobert     // for DW_AT_declaration set to 1. Sometimes concrete function instances are
3517*f6aab3d8Srobert     // placed inside the class definitions and shouldn't be included in the list
3518*f6aab3d8Srobert     // of things are are tracking here.
3519*f6aab3d8Srobert     if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) != 1)
3520*f6aab3d8Srobert       return;
3521*f6aab3d8Srobert 
3522*f6aab3d8Srobert     if (const char *name = die.GetMangledName()) {
3523*f6aab3d8Srobert       ConstString const_name(name);
3524*f6aab3d8Srobert       if (die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
3525*f6aab3d8Srobert         map_artificial.Append(const_name, die);
3526*f6aab3d8Srobert       else
3527*f6aab3d8Srobert         map.Append(const_name, die);
3528*f6aab3d8Srobert     }
3529*f6aab3d8Srobert   };
3530*f6aab3d8Srobert 
3531061da546Spatrick   UniqueCStringMap<DWARFDIE> src_name_to_die;
3532061da546Spatrick   UniqueCStringMap<DWARFDIE> dst_name_to_die;
3533061da546Spatrick   UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
3534061da546Spatrick   UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
3535*f6aab3d8Srobert   for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid();
3536*f6aab3d8Srobert        src_die = src_die.GetSibling()) {
3537*f6aab3d8Srobert     gather(src_die, src_name_to_die, src_name_to_die_artificial);
3538061da546Spatrick   }
3539*f6aab3d8Srobert   for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
3540*f6aab3d8Srobert        dst_die = dst_die.GetSibling()) {
3541*f6aab3d8Srobert     gather(dst_die, dst_name_to_die, dst_name_to_die_artificial);
3542061da546Spatrick   }
3543061da546Spatrick   const uint32_t src_size = src_name_to_die.GetSize();
3544061da546Spatrick   const uint32_t dst_size = dst_name_to_die.GetSize();
3545061da546Spatrick 
3546061da546Spatrick   // Is everything kosher so we can go through the members at top speed?
3547061da546Spatrick   bool fast_path = true;
3548061da546Spatrick 
3549*f6aab3d8Srobert   if (src_size != dst_size)
3550061da546Spatrick     fast_path = false;
3551061da546Spatrick 
3552061da546Spatrick   uint32_t idx;
3553061da546Spatrick 
3554061da546Spatrick   if (fast_path) {
3555061da546Spatrick     for (idx = 0; idx < src_size; ++idx) {
3556*f6aab3d8Srobert       DWARFDIE src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
3557*f6aab3d8Srobert       DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
3558061da546Spatrick 
3559*f6aab3d8Srobert       if (src_die.Tag() != dst_die.Tag())
3560061da546Spatrick         fast_path = false;
3561061da546Spatrick 
3562061da546Spatrick       const char *src_name = src_die.GetMangledName();
3563061da546Spatrick       const char *dst_name = dst_die.GetMangledName();
3564061da546Spatrick 
3565061da546Spatrick       // Make sure the names match
3566061da546Spatrick       if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))
3567061da546Spatrick         continue;
3568061da546Spatrick 
3569061da546Spatrick       fast_path = false;
3570061da546Spatrick     }
3571061da546Spatrick   }
3572061da546Spatrick 
3573061da546Spatrick   DWARFASTParserClang *src_dwarf_ast_parser =
3574dda28197Spatrick       static_cast<DWARFASTParserClang *>(
3575*f6aab3d8Srobert           SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU()));
3576061da546Spatrick   DWARFASTParserClang *dst_dwarf_ast_parser =
3577dda28197Spatrick       static_cast<DWARFASTParserClang *>(
3578*f6aab3d8Srobert           SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU()));
3579*f6aab3d8Srobert   auto link = [&](DWARFDIE src, DWARFDIE dst) {
3580*f6aab3d8Srobert     SymbolFileDWARF::DIEToTypePtr &die_to_type =
3581*f6aab3d8Srobert         dst_class_die.GetDWARF()->GetDIEToType();
3582*f6aab3d8Srobert     clang::DeclContext *dst_decl_ctx =
3583*f6aab3d8Srobert         dst_dwarf_ast_parser->m_die_to_decl_ctx[dst.GetDIE()];
3584*f6aab3d8Srobert     if (dst_decl_ctx)
3585*f6aab3d8Srobert       src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src);
3586*f6aab3d8Srobert 
3587*f6aab3d8Srobert     if (Type *src_child_type = die_to_type[src.GetDIE()])
3588*f6aab3d8Srobert       die_to_type[dst.GetDIE()] = src_child_type;
3589*f6aab3d8Srobert   };
3590061da546Spatrick 
3591061da546Spatrick   // Now do the work of linking the DeclContexts and Types.
3592061da546Spatrick   if (fast_path) {
3593061da546Spatrick     // We can do this quickly.  Just run across the tables index-for-index
3594061da546Spatrick     // since we know each node has matching names and tags.
3595061da546Spatrick     for (idx = 0; idx < src_size; ++idx) {
3596*f6aab3d8Srobert       link(src_name_to_die.GetValueAtIndexUnchecked(idx),
3597*f6aab3d8Srobert            dst_name_to_die.GetValueAtIndexUnchecked(idx));
3598061da546Spatrick     }
3599061da546Spatrick   } else {
3600061da546Spatrick     // We must do this slowly.  For each member of the destination, look up a
3601061da546Spatrick     // member in the source with the same name, check its tag, and unique them
3602061da546Spatrick     // if everything matches up.  Report failures.
3603061da546Spatrick 
3604061da546Spatrick     if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) {
3605061da546Spatrick       src_name_to_die.Sort();
3606061da546Spatrick 
3607061da546Spatrick       for (idx = 0; idx < dst_size; ++idx) {
3608061da546Spatrick         ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx);
3609*f6aab3d8Srobert         DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
3610*f6aab3d8Srobert         DWARFDIE src_die = src_name_to_die.Find(dst_name, DWARFDIE());
3611061da546Spatrick 
3612*f6aab3d8Srobert         if (src_die && (src_die.Tag() == dst_die.Tag()))
3613*f6aab3d8Srobert           link(src_die, dst_die);
3614*f6aab3d8Srobert         else
3615061da546Spatrick           failures.push_back(dst_die);
3616061da546Spatrick       }
3617061da546Spatrick     }
3618061da546Spatrick   }
3619061da546Spatrick 
3620061da546Spatrick   const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize();
3621061da546Spatrick   const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize();
3622061da546Spatrick 
3623061da546Spatrick   if (src_size_artificial && dst_size_artificial) {
3624061da546Spatrick     dst_name_to_die_artificial.Sort();
3625061da546Spatrick 
3626061da546Spatrick     for (idx = 0; idx < src_size_artificial; ++idx) {
3627061da546Spatrick       ConstString src_name_artificial =
3628061da546Spatrick           src_name_to_die_artificial.GetCStringAtIndex(idx);
3629*f6aab3d8Srobert       DWARFDIE src_die =
3630*f6aab3d8Srobert           src_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
3631*f6aab3d8Srobert       DWARFDIE dst_die =
3632061da546Spatrick           dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());
3633061da546Spatrick 
3634061da546Spatrick       // Both classes have the artificial types, link them
3635*f6aab3d8Srobert       if (dst_die)
3636*f6aab3d8Srobert         link(src_die, dst_die);
3637061da546Spatrick     }
3638061da546Spatrick   }
3639061da546Spatrick 
3640061da546Spatrick   if (dst_size_artificial) {
3641061da546Spatrick     for (idx = 0; idx < dst_size_artificial; ++idx) {
3642*f6aab3d8Srobert       failures.push_back(
3643*f6aab3d8Srobert           dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx));
3644061da546Spatrick     }
3645061da546Spatrick   }
3646061da546Spatrick 
3647061da546Spatrick   return !failures.empty();
3648061da546Spatrick }
3649