aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp123
1 files changed, 42 insertions, 81 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 188a667ca564..46015f7b43b1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdlib.h>
+#include <cstdlib>
#include "DWARFASTParserClang.h"
#include "DWARFDebugInfo.h"
@@ -49,7 +49,7 @@
//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
@@ -60,7 +60,7 @@ using namespace lldb_private;
DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
: m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
-DWARFASTParserClang::~DWARFASTParserClang() {}
+DWARFASTParserClang::~DWARFASTParserClang() = default;
static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) {
switch (dwarf_accessibility) {
@@ -157,7 +157,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// The type in the Clang module must have the same language as the current CU.
LanguageSet languages;
- languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU()));
+ languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
llvm::DenseSet<SymbolFile *> searched_symbol_files;
clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
searched_symbol_files, pcm_types);
@@ -666,8 +666,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
// Blocks have a __FuncPtr inside them which is a pointer to a
// function of the proper type.
- for (DWARFDIE child_die = target_die.GetFirstChild();
- child_die.IsValid(); child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : target_die.children()) {
if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
"__FuncPtr")) {
DWARFDIE function_pointer_type =
@@ -1226,6 +1225,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
if (!function_decl) {
+ char *name_buf = nullptr;
llvm::StringRef name = attrs.name.GetStringRef();
// We currently generate function templates with template parameters in
@@ -1233,8 +1233,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
// we want to strip these from the name when creating the AST.
if (attrs.mangled_name) {
llvm::ItaniumPartialDemangler D;
- if (!D.partialDemangle(attrs.mangled_name))
- name = D.getFunctionBaseName(nullptr, nullptr);
+ if (!D.partialDemangle(attrs.mangled_name)) {
+ name_buf = D.getFunctionBaseName(nullptr, nullptr);
+ name = name_buf;
+ }
}
// We just have a function that isn't part of a class
@@ -1243,6 +1245,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
: containing_decl_ctx,
GetOwningClangModule(die), name, clang_type, attrs.storage,
attrs.is_inline);
+ std::free(name_buf);
if (has_template_params) {
TypeSystemClang::TemplateParameterInfos template_param_infos;
@@ -1266,13 +1269,10 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
LinkDeclContextToDIE(function_decl, die);
if (!function_param_decls.empty()) {
- m_ast.SetFunctionParameters(function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ m_ast.SetFunctionParameters(function_decl, function_param_decls);
if (template_function_decl)
m_ast.SetFunctionParameters(template_function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
+ function_param_decls);
}
ClangASTMetadata metadata;
@@ -1357,7 +1357,7 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
- CompilerType class_clang_type = class_type->GetLayoutCompilerType();
+ CompilerType class_clang_type = class_type->GetForwardCompilerType();
CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(
class_clang_type, pointee_clang_type);
@@ -1684,14 +1684,18 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
die.GetOffset(), attrs.name.GetCString());
}
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
+ // If the byte size of the record is specified then overwrite the size
+ // that would be computed by Clang. This is only needed as LLDB's
+ // TypeSystemClang is always in C++ mode, but some compilers such as
+ // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
+ // the size of 1 for empty structs that would be computed in C++ mode).
+ if (attrs.byte_size) {
clang::RecordDecl *record_decl =
TypeSystemClang::GetAsRecordDecl(clang_type);
-
if (record_decl) {
- GetClangASTImporter().SetRecordLayout(
- record_decl, ClangASTImporter::LayoutInfo());
+ ClangASTImporter::LayoutInfo layout;
+ layout.bit_size = *attrs.byte_size * 8;
+ GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
} else if (clang_type_was_created) {
@@ -1822,8 +1826,7 @@ bool DWARFASTParserClang::ParseTemplateDIE(
case DW_TAG_GNU_template_parameter_pack: {
template_param_infos.packed_args =
std::make_unique<TypeSystemClang::TemplateParameterInfos>();
- for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
- child_die = child_die.GetSibling()) {
+ for (DWARFDIE child_die : die.children()) {
if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
return false;
}
@@ -1928,8 +1931,7 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
if (!parent_die)
return false;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
switch (tag) {
@@ -1978,15 +1980,12 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
}
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
- std::vector<int> member_accessibilities;
- bool is_a_class = false;
// Parse members and base classes first
std::vector<DWARFDIE> member_function_dies;
DelayedPropertyList delayed_properties;
- ParseChildMembers(die, clang_type, bases, member_accessibilities,
- member_function_dies, delayed_properties,
- default_accessibility, is_a_class, layout_info);
+ ParseChildMembers(die, clang_type, bases, member_function_dies,
+ delayed_properties, default_accessibility, layout_info);
// Now parse any methods if there were any...
for (const DWARFDIE &die : member_function_dies)
@@ -2007,31 +2006,6 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
}
}
- // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
- // need to tell the clang type it is actually a class.
- if (!type_is_objc_object_or_interface) {
- if (is_a_class && tag_decl_kind != clang::TTK_Class)
- m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
- clang::TTK_Class);
- }
-
- // Since DW_TAG_structure_type gets used for both classes and
- // structures, we may need to set any DW_TAG_member fields to have a
- // "private" access if none was specified. When we parsed the child
- // members we tracked that actual accessibility value for each
- // DW_TAG_member in the "member_accessibilities" array. If the value
- // for the member is zero, then it was set to the
- // "default_accessibility" which for structs was "public". Below we
- // correct this by setting any fields to "private" that weren't
- // correctly set.
- if (is_a_class && !member_accessibilities.empty()) {
- // This is a class and all members that didn't have their access
- // specified are private.
- m_ast.SetDefaultAccessForRecordFields(
- m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
- &member_accessibilities.front(), member_accessibilities.size());
- }
-
if (!bases.empty()) {
// Make sure all base classes refer to complete types and not forward
// declarations. If we don't do this, clang will crash with an
@@ -2131,8 +2105,7 @@ void DWARFASTParserClang::EnsureAllDIEsInDeclContextHaveBeenParsed(
for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
it = m_decl_ctx_to_die.erase(it))
- for (DWARFDIE decl = it->second.GetFirstChild(); decl;
- decl = decl.GetSibling())
+ for (DWARFDIE decl : it->second.children())
GetClangDeclForDIE(decl);
}
@@ -2168,8 +2141,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
size_t enumerators_added = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
if (tag == DW_TAG_enumerator) {
DWARFAttributes attributes;
@@ -2201,7 +2173,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
case DW_AT_description:
default:
case DW_AT_decl_file:
- decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
+ decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile(
+ form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -2343,7 +2316,6 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
void DWARFASTParserClang::ParseSingleMember(
const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
- std::vector<int> &member_accessibilities,
lldb::AccessType default_accessibility,
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
@@ -2533,7 +2505,7 @@ void DWARFASTParserClang::ParseSingleMember(
if (accessibility == eAccessNone)
accessibility = eAccessPublic;
TypeSystemClang::AddVariableToRecordType(
- class_clang_type, name, var_type->GetLayoutCompilerType(),
+ class_clang_type, name, var_type->GetForwardCompilerType(),
accessibility);
}
return;
@@ -2551,7 +2523,6 @@ void DWARFASTParserClang::ParseSingleMember(
if (accessibility == eAccessNone)
accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
uint64_t field_bit_offset =
(member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
@@ -2666,7 +2637,7 @@ void DWARFASTParserClang::ParseSingleMember(
last_field_info.bit_offset = field_bit_offset;
if (llvm::Optional<uint64_t> clang_type_size =
- member_clang_type.GetByteSize(nullptr)) {
+ member_type->GetByteSize(nullptr)) {
last_field_info.bit_size = *clang_type_size * character_width;
}
@@ -2761,10 +2732,9 @@ void DWARFASTParserClang::ParseSingleMember(
bool DWARFASTParserClang::ParseChildMembers(
const DWARFDIE &parent_die, CompilerType &class_clang_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<int> &member_accessibilities,
std::vector<DWARFDIE> &member_function_dies,
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
- bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
+ ClangASTImporter::LayoutInfo &layout_info) {
if (!parent_die)
return false;
@@ -2776,16 +2746,15 @@ bool DWARFASTParserClang::ParseChildMembers(
if (ast == nullptr)
return false;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
dw_tag_t tag = die.Tag();
switch (tag) {
case DW_TAG_member:
case DW_TAG_APPLE_property:
ParseSingleMember(die, parent_die, class_clang_type,
- member_accessibilities, default_accessibility,
- delayed_properties, layout_info, last_field_info);
+ default_accessibility, delayed_properties, layout_info,
+ last_field_info);
break;
case DW_TAG_subprogram:
@@ -2794,9 +2763,6 @@ bool DWARFASTParserClang::ParseChildMembers(
break;
case DW_TAG_inheritance: {
- is_a_class = true;
- if (default_accessibility == eAccessNone)
- default_accessibility = eAccessPrivate;
// TODO: implement DW_TAG_inheritance type parsing
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
@@ -2926,8 +2892,7 @@ size_t DWARFASTParserClang::ParseChildParameters(
return 0;
size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
switch (tag) {
case DW_TAG_formal_parameter: {
@@ -3046,8 +3011,7 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
if (!parent_die)
return llvm::None;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
+ for (DWARFDIE die : parent_die.children()) {
const dw_tag_t tag = die.Tag();
if (tag != DW_TAG_subrange_type)
continue;
@@ -3349,8 +3313,7 @@ static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {
}
static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
- for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid();
- candidate = candidate.GetSibling()) {
+ for (DWARFDIE candidate : context.children()) {
if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
return candidate;
}
@@ -3514,8 +3477,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
UniqueCStringMap<DWARFDIE> dst_name_to_die;
UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
- for (src_die = src_class_die.GetFirstChild(); src_die.IsValid();
- src_die = src_die.GetSibling()) {
+ for (DWARFDIE src_die : src_class_die.children()) {
if (src_die.Tag() == DW_TAG_subprogram) {
// Make sure this is a declaration and not a concrete instance by looking
// for DW_AT_declaration set to 1. Sometimes concrete function instances
@@ -3533,8 +3495,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
}
}
}
- for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
- dst_die = dst_die.GetSibling()) {
+ for (DWARFDIE dst_die : dst_class_die.children()) {
if (dst_die.Tag() == DW_TAG_subprogram) {
// Make sure this is a declaration and not a concrete instance by looking
// for DW_AT_declaration set to 1. Sometimes concrete function instances