Skip to content

Cherry-pick & resolve merge conflict #1956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lldb/include/lldb/Symbol/Variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope,
SymbolContextScope *owner_scope, const RangeList &scope_range,
Declaration *decl, const DWARFExpression &location, bool external,
bool artificial, bool static_member, bool constant);
bool artificial, bool location_is_constant_data, bool static_member,
bool constant);

virtual ~Variable();

Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class DWARFFormValue {
DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {}
DWARFFormValue(const DWARFUnit *unit, dw_form_t form)
: m_unit(unit), m_form(form) {}
const DWARFUnit *GetUnit() const { return m_unit; }
void SetUnit(const DWARFUnit *unit) { m_unit = unit; }
dw_form_t Form() const { return m_form; }
dw_form_t& FormRef() { return m_form; }
Expand Down
152 changes: 74 additions & 78 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,6 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
return support_files;
}

static inline bool IsSwiftLanguage(LanguageType language) {
return language == eLanguageTypePLI || language == eLanguageTypeSwift ||
((uint32_t)language == (uint32_t)llvm::dwarf::DW_LANG_Swift);
}

void SymbolFileDWARF::Initialize() {
LogChannelDWARF::Initialize();
PluginManager::RegisterPlugin(GetPluginNameStatic(),
Expand Down Expand Up @@ -974,7 +969,7 @@ bool SymbolFileDWARF::ParseImportedModules(
return false;
auto lang = sc.comp_unit->GetLanguage();
if (!ClangModulesDeclVendor::LanguageSupportsClangModules(lang) &&
!IsSwiftLanguage(lang))
lang != eLanguageTypeSwift)
return false;
UpdateExternalModuleListIfNeeded();

Expand Down Expand Up @@ -3185,18 +3180,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
const char *name = nullptr;
const char *mangled = nullptr;
Declaration decl;
uint32_t i;
DWARFFormValue type_die_form;
DWARFExpression location;
bool is_external = false;
bool is_artificial = false;
bool location_is_const_value_data = false;
bool has_explicit_location = false;
DWARFFormValue const_value;
DWARFFormValue const_value_form, location_form;
Variable::RangeList scope_ranges;
// AccessType accessibility = eAccessNone;

for (i = 0; i < num_attributes; ++i) {
for (size_t i = 0; i < num_attributes; ++i) {
dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;

Expand Down Expand Up @@ -3226,65 +3218,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
is_external = form_value.Boolean();
break;
case DW_AT_const_value:
// If we have already found a DW_AT_location attribute, ignore this
// attribute.
if (!has_explicit_location) {
location_is_const_value_data = true;
// The constant value will be either a block, a data value or a
// string.
auto debug_info_data = die.GetData();
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
// Retrieve the value as a block expression.
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
location = DWARFExpression(
module,
DataExtractor(debug_info_data, block_offset, block_length),
die.GetCU());
} else if (DWARFFormValue::IsDataForm(form_value.Form())) {
// Constant value size does not have to match the size of the
// variable. We will fetch the size of the type after we create
// it.
const_value = form_value;
} else if (const char *str = form_value.AsCString()) {
uint32_t string_length = strlen(str) + 1;
location = DWARFExpression(
module,
DataExtractor(str, string_length,
die.GetCU()->GetByteOrder(),
die.GetCU()->GetAddressByteSize()),
die.GetCU());
}
}
const_value_form = form_value;
break;
case DW_AT_location:
location_form = form_value;
break;
case DW_AT_location: {
location_is_const_value_data = false;
has_explicit_location = true;
if (DWARFFormValue::IsBlockForm(form_value.Form())) {
auto data = die.GetData();

uint32_t block_offset =
form_value.BlockData() - data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
location = DWARFExpression(
module, DataExtractor(data, block_offset, block_length),
die.GetCU());
} else {
DataExtractor data = die.GetCU()->GetLocationData();
dw_offset_t offset = form_value.Unsigned();
if (form_value.Form() == DW_FORM_loclistx)
offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1);
if (data.ValidOffset(offset)) {
data = DataExtractor(data, offset, data.GetByteSize() - offset);
location = DWARFExpression(module, data, die.GetCU());
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListAddresses(
attributes.CompileUnitAtIndex(i)->GetBaseAddress(),
func_low_pc);
}
}
} break;
case DW_AT_specification:
spec_die = form_value.Reference();
break;
Expand All @@ -3311,9 +3249,69 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}

if (tag == DW_TAG_variable && mangled &&
IsSwiftLanguage(sc.comp_unit->GetLanguage()))
sc.comp_unit->GetLanguage() == eLanguageTypeSwift)
mangled = NULL;

// Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
// for static constexpr member variables -- DW_AT_const_value will be
// present in the class declaration and DW_AT_location in the DIE defining
// the member.
bool location_is_const_value_data = false;
bool has_explicit_location = false;
bool use_type_size_for_value = false;
if (location_form.IsValid()) {
has_explicit_location = true;
if (DWARFFormValue::IsBlockForm(location_form.Form())) {
const DWARFDataExtractor &data = die.GetData();

uint32_t block_offset =
location_form.BlockData() - data.GetDataStart();
uint32_t block_length = location_form.Unsigned();
location = DWARFExpression(
module, DataExtractor(data, block_offset, block_length),
die.GetCU());
} else {
DataExtractor data = die.GetCU()->GetLocationData();
dw_offset_t offset = location_form.Unsigned();
if (location_form.Form() == DW_FORM_loclistx)
offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1);
if (data.ValidOffset(offset)) {
data = DataExtractor(data, offset, data.GetByteSize() - offset);
location = DWARFExpression(module, data, die.GetCU());
assert(func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListAddresses(
location_form.GetUnit()->GetBaseAddress(), func_low_pc);
}
}
} else if (const_value_form.IsValid()) {
location_is_const_value_data = true;
// The constant value will be either a block, a data value or a
// string.
const DWARFDataExtractor &debug_info_data = die.GetData();
if (DWARFFormValue::IsBlockForm(const_value_form.Form())) {
// Retrieve the value as a block expression.
uint32_t block_offset =
const_value_form.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = const_value_form.Unsigned();
location = DWARFExpression(
module,
DataExtractor(debug_info_data, block_offset, block_length),
die.GetCU());
} else if (DWARFFormValue::IsDataForm(const_value_form.Form())) {
// Constant value size does not have to match the size of the
// variable. We will fetch the size of the type after we create
// it.
use_type_size_for_value = true;
} else if (const char *str = const_value_form.AsCString()) {
uint32_t string_length = strlen(str) + 1;
location = DWARFExpression(
module,
DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
die.GetCU()->GetAddressByteSize()),
die.GetCU());
}
}

const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
const dw_tag_t parent_tag = die.GetParent().Tag();
bool is_static_member =
Expand Down Expand Up @@ -3493,18 +3491,18 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}

if (symbol_context_scope) {
SymbolFileTypeSP type_sp(
new SymbolFileType(*this, GetUID(type_die_form.Reference())));
auto type_sp = std::make_shared<SymbolFileType>(
*this, GetUID(type_die_form.Reference()));

if (const_value.Form() && type_sp && type_sp->GetType())
if (use_type_size_for_value && type_sp->GetType())
location.UpdateValue(
const_value.Unsigned(),
const_value_form.Unsigned(),
type_sp->GetType()->GetByteSize(nullptr).getValueOr(0),
die.GetCU()->GetAddressByteSize());

// Swift let-bindings are marked by a DW_TAG_const_type.
bool is_constant = false;
if (IsSwiftLanguage(sc.comp_unit->GetLanguage())) {
if (sc.comp_unit->GetLanguage() == eLanguageTypeSwift) {
DWARFDIE type_die = die.GetReferencedDIE(llvm::dwarf::DW_AT_type);
if (type_die && type_die.Tag() == llvm::dwarf::DW_TAG_const_type)
is_constant = true;
Expand All @@ -3513,9 +3511,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
var_sp = std::make_shared<Variable>(
die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
scope_ranges, &decl, location, is_external, is_artificial,
is_static_member, is_constant);

var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
location_is_const_value_data, is_static_member, is_constant);
} else {
// Not ready to parse this variable yet. It might be a global or static
// variable that is in a function scope and the function in the symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -812,8 +812,7 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
scope, comp_unit.get(), ranges, &decl, location, is_external, false,
false, false);
var_sp->SetLocationIsConstantValueData(false);
false, false, false);

return var_sp;
}
Expand All @@ -840,8 +839,7 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
false, false, false, true);
var_sp->SetLocationIsConstantValueData(true);
false, false, true, false, true);
return var_sp;
}

Expand Down Expand Up @@ -1346,7 +1344,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false,
false, false, false);
false, false, false, false);

if (!is_param)
m_ast->GetOrCreateVariableDecl(scope_id, var_id);
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,9 +1020,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(

var_sp = std::make_shared<Variable>(
var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
ranges, &decl, location, is_external, is_artificial, is_static_member,
is_constant);
var_sp->SetLocationIsConstantValueData(is_constant);
ranges, &decl, location, is_external, is_artificial, is_constant,
is_static_member, is_constant);

m_variables.insert(std::make_pair(var_uid, var_sp));
return var_sp;
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Symbol/Variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
ValueType scope, SymbolContextScope *context,
const RangeList &scope_range, Declaration *decl_ptr,
const DWARFExpression &location, bool external,
bool artificial, bool static_member, bool constant)
bool artificial, bool location_is_constant_data,
bool static_member, bool constant)
: UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
m_symfile_type_sp(symfile_type_sp), m_scope(scope),
m_owner_scope(context), m_scope_range(scope_range),
m_declaration(decl_ptr), m_location(location), m_external(external),
m_artificial(artificial), m_loc_is_const_data(false),
m_artificial(artificial), m_loc_is_const_data(location_is_constant_data),
m_static_member(static_member), m_constant(constant) {}

Variable::~Variable() {}
Expand Down
Loading