summaryrefslogtreecommitdiff
path: root/lldb/source/Expression
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Expression
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'lldb/source/Expression')
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp297
-rw-r--r--lldb/source/Expression/DiagnosticManager.cpp4
-rw-r--r--lldb/source/Expression/Expression.cpp2
-rw-r--r--lldb/source/Expression/ExpressionVariable.cpp14
-rw-r--r--lldb/source/Expression/FunctionCaller.cpp7
-rw-r--r--lldb/source/Expression/IRExecutionUnit.cpp61
-rw-r--r--lldb/source/Expression/IRInterpreter.cpp59
-rw-r--r--lldb/source/Expression/IRMemoryMap.cpp2
-rw-r--r--lldb/source/Expression/LLVMUserExpression.cpp19
-rw-r--r--lldb/source/Expression/Materializer.cpp47
-rw-r--r--lldb/source/Expression/REPL.cpp36
-rw-r--r--lldb/source/Expression/UserExpression.cpp124
-rw-r--r--lldb/source/Expression/UtilityFunction.cpp2
13 files changed, 230 insertions, 444 deletions
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 69c84640ef93a..6050c1922564c 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1,4 +1,4 @@
-//===-- DWARFExpression.cpp -------------------------------------*- C++ -*-===//
+//===-- DWARFExpression.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -88,8 +88,7 @@ void DWARFExpression::UpdateValue(uint64_t const_value,
void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data,
lldb::DescriptionLevel level,
ABI *abi) const {
- llvm::DWARFExpression(data.GetAsLLVM(), llvm::dwarf::DWARF_VERSION,
- data.GetAddressByteSize())
+ llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize())
.print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr,
nullptr);
}
@@ -138,12 +137,15 @@ void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
m_dwarf_cu->GetLocationTable(m_data);
llvm::MCRegisterInfo *MRI = abi ? &abi->GetMCRegisterInfo() : nullptr;
-
+ llvm::DIDumpOptions DumpOpts;
+ DumpOpts.RecoverableErrorHandler = [&](llvm::Error E) {
+ s->AsRawOstream() << "error: " << toString(std::move(E));
+ };
loctable_up->dumpLocationList(
&offset, s->AsRawOstream(),
llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, MRI,
DummyDWARFObject(m_data.GetByteOrder() == eByteOrderLittle), nullptr,
- llvm::DIDumpOptions(), s->GetIndentLevel() + 2);
+ DumpOpts, s->GetIndentLevel() + 2);
} else {
// We have a normal location that contains DW_OP location opcodes
DumpLocation(s, m_data, level, abi);
@@ -394,6 +396,7 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
return offset - data_offset;
}
+ case DW_OP_GNU_entry_value:
case DW_OP_entry_value: // 0xa3 ULEB128 size + variable-length block
{
uint64_t subexpr_len = data.GetULEB128(&offset);
@@ -933,7 +936,7 @@ bool DWARFExpression::Evaluate(
Value tmp;
uint32_t reg_num;
- /// Insertion point for evaluating multi-piece expression.
+ /// Insertion point for evaluating multi-piece expression.
uint64_t op_piece_offset = 0;
Value pieces; // Used for DW_OP_piece
@@ -1183,7 +1186,7 @@ bool DWARFExpression::Evaluate(
break;
default:
stack.back().GetScalar() =
- addr_data.GetPointer(&addr_data_offset);
+ addr_data.GetAddress(&addr_data_offset);
}
stack.back().ClearContext();
} else {
@@ -2071,6 +2074,10 @@ bool DWARFExpression::Evaluate(
// not available. Fill with zeros for now by resizing the data and
// appending it
curr_piece.ResizeData(piece_byte_size);
+ // Note that "0" is not a correct value for the unknown bits.
+ // It would be better to also return a mask of valid bits together
+ // with the expression result, so the debugger can print missing
+ // members as "<optimized out>" or something.
::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
pieces.AppendDataToHostBuffer(curr_piece);
} else {
@@ -2128,7 +2135,8 @@ bool DWARFExpression::Evaluate(
case Value::eValueTypeScalar: {
uint32_t bit_size = piece_byte_size * 8;
uint32_t bit_offset = 0;
- if (!curr_piece_source_value.GetScalar().ExtractBitfield(
+ Scalar &scalar = curr_piece_source_value.GetScalar();
+ if (!scalar.ExtractBitfield(
bit_size, bit_offset)) {
if (error_ptr)
error_ptr->SetErrorStringWithFormat(
@@ -2139,7 +2147,14 @@ bool DWARFExpression::Evaluate(
.GetByteSize());
return false;
}
- curr_piece = curr_piece_source_value;
+ // Create curr_piece with bit_size. By default Scalar
+ // grows to the nearest host integer type.
+ llvm::APInt fail_value(1, 0, false);
+ llvm::APInt ap_int = scalar.UInt128(fail_value);
+ assert(ap_int.getBitWidth() >= bit_size);
+ llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
+ ap_int.getNumWords()};
+ curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
} break;
case Value::eValueTypeVector: {
@@ -2161,7 +2176,7 @@ bool DWARFExpression::Evaluate(
if (op_piece_offset == 0) {
// This is the first piece, we should push it back onto the stack
// so subsequent pieces will be able to access this piece and add
- // to it
+ // to it.
if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
if (error_ptr)
error_ptr->SetErrorString("failed to append piece data");
@@ -2169,7 +2184,7 @@ bool DWARFExpression::Evaluate(
}
} else {
// If this is the second or later piece there should be a value on
- // the stack
+ // the stack.
if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
if (error_ptr)
error_ptr->SetErrorStringWithFormat(
@@ -2185,8 +2200,8 @@ bool DWARFExpression::Evaluate(
return false;
}
}
- op_piece_offset += piece_byte_size;
}
+ op_piece_offset += piece_byte_size;
}
} break;
@@ -2307,6 +2322,12 @@ bool DWARFExpression::Evaluate(
// rather is a constant value. The value from the top of the stack is the
// value to be used. This is the actual object value and not the location.
case DW_OP_stack_value:
+ if (stack.empty()) {
+ if (error_ptr)
+ error_ptr->SetErrorString(
+ "Expression stack needs at least 1 item for DW_OP_stack_value.");
+ return false;
+ }
stack.back().SetValueType(Value::eValueTypeScalar);
break;
@@ -2325,8 +2346,8 @@ bool DWARFExpression::Evaluate(
return false;
}
const uint64_t die_offset = opcodes.GetULEB128(&offset);
- Scalar::Type type = Scalar::e_void;
uint64_t bit_size;
+ bool sign;
if (die_offset == 0) {
// The generic type has the size of an address on the target
// machine and an unspecified signedness. Scalar has no
@@ -2336,13 +2357,13 @@ bool DWARFExpression::Evaluate(
error_ptr->SetErrorString("No module");
return false;
}
+ sign = false;
bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
if (!bit_size) {
if (error_ptr)
error_ptr->SetErrorString("unspecified architecture");
return false;
}
- type = Scalar::GetBestTypeForBitSize(bit_size, false);
} else {
// Retrieve the type DIE that the value is being converted to.
// FIXME: the constness has annoying ripple effects.
@@ -2365,11 +2386,11 @@ bool DWARFExpression::Evaluate(
switch (encoding) {
case DW_ATE_signed:
case DW_ATE_signed_char:
- type = Scalar::GetBestTypeForBitSize(bit_size, true);
+ sign = true;
break;
case DW_ATE_unsigned:
case DW_ATE_unsigned_char:
- type = Scalar::GetBestTypeForBitSize(bit_size, false);
+ sign = false;
break;
default:
if (error_ptr)
@@ -2377,13 +2398,8 @@ bool DWARFExpression::Evaluate(
return false;
}
}
- if (type == Scalar::e_void) {
- if (error_ptr)
- error_ptr->SetErrorString("Unsupported pointer size");
- return false;
- }
Scalar &top = stack.back().ResolveValue(exe_ctx);
- top.TruncOrExtendTo(type, bit_size);
+ top.TruncOrExtendTo(bit_size, sign);
break;
}
@@ -2502,6 +2518,7 @@ bool DWARFExpression::Evaluate(
stack.push_back(Scalar(value));
} break;
+ case DW_OP_GNU_entry_value:
case DW_OP_entry_value: {
if (!Evaluate_DW_OP_entry_value(stack, exe_ctx, reg_ctx, opcodes, offset,
error_ptr, log)) {
@@ -2513,9 +2530,10 @@ bool DWARFExpression::Evaluate(
}
default:
- LLDB_LOGF(log, "Unhandled opcode %s in DWARFExpression.",
- DW_OP_value_to_name(op));
- break;
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormatv(
+ "Unhandled opcode {0} in DWARFExpression", LocationAtom(op));
+ return false;
}
}
@@ -2546,235 +2564,6 @@ bool DWARFExpression::Evaluate(
return true; // Return true on success
}
-static bool print_dwarf_exp_op(Stream &s, const DataExtractor &data,
- lldb::offset_t *offset_ptr, int address_size,
- int dwarf_ref_size) {
- uint8_t opcode = data.GetU8(offset_ptr);
- DRC_class opcode_class;
- uint64_t uint;
- int64_t sint;
-
- int size;
-
- opcode_class = DW_OP_value_to_class(opcode) & (~DRC_DWARFv3);
-
- s.Printf("%s ", DW_OP_value_to_name(opcode));
-
- /* Does this take zero parameters? If so we can shortcut this function. */
- if (opcode_class == DRC_ZEROOPERANDS)
- return true;
-
- if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) {
- uint = data.GetULEB128(offset_ptr);
- sint = data.GetSLEB128(offset_ptr);
- s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
- return true;
- }
- if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_entry_value) {
- uint = data.GetULEB128(offset_ptr);
- s.Printf("%" PRIu64 " ", uint);
- return true;
- }
- if (opcode_class != DRC_ONEOPERAND) {
- s.Printf("UNKNOWN OP %u", opcode);
- return false;
- }
-
- switch (opcode) {
- case DW_OP_addr:
- size = address_size;
- break;
- case DW_OP_const1u:
- size = 1;
- break;
- case DW_OP_const1s:
- size = -1;
- break;
- case DW_OP_const2u:
- size = 2;
- break;
- case DW_OP_const2s:
- size = -2;
- break;
- case DW_OP_const4u:
- size = 4;
- break;
- case DW_OP_const4s:
- size = -4;
- break;
- case DW_OP_const8u:
- size = 8;
- break;
- case DW_OP_const8s:
- size = -8;
- break;
- case DW_OP_constu:
- size = 128;
- break;
- case DW_OP_consts:
- size = -128;
- break;
- case DW_OP_fbreg:
- size = -128;
- break;
- case DW_OP_breg0:
- case DW_OP_breg1:
- case DW_OP_breg2:
- case DW_OP_breg3:
- case DW_OP_breg4:
- case DW_OP_breg5:
- case DW_OP_breg6:
- case DW_OP_breg7:
- case DW_OP_breg8:
- case DW_OP_breg9:
- case DW_OP_breg10:
- case DW_OP_breg11:
- case DW_OP_breg12:
- case DW_OP_breg13:
- case DW_OP_breg14:
- case DW_OP_breg15:
- case DW_OP_breg16:
- case DW_OP_breg17:
- case DW_OP_breg18:
- case DW_OP_breg19:
- case DW_OP_breg20:
- case DW_OP_breg21:
- case DW_OP_breg22:
- case DW_OP_breg23:
- case DW_OP_breg24:
- case DW_OP_breg25:
- case DW_OP_breg26:
- case DW_OP_breg27:
- case DW_OP_breg28:
- case DW_OP_breg29:
- case DW_OP_breg30:
- case DW_OP_breg31:
- size = -128;
- break;
- case DW_OP_pick:
- case DW_OP_deref_size:
- case DW_OP_xderef_size:
- size = 1;
- break;
- case DW_OP_skip:
- case DW_OP_bra:
- size = -2;
- break;
- case DW_OP_call2:
- size = 2;
- break;
- case DW_OP_call4:
- size = 4;
- break;
- case DW_OP_call_ref:
- size = dwarf_ref_size;
- break;
- case DW_OP_addrx:
- case DW_OP_piece:
- case DW_OP_plus_uconst:
- case DW_OP_regx:
- case DW_OP_GNU_addr_index:
- case DW_OP_GNU_const_index:
- case DW_OP_entry_value:
- size = 128;
- break;
- default:
- s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode);
- return false;
- }
-
- switch (size) {
- case -1:
- sint = (int8_t)data.GetU8(offset_ptr);
- s.Printf("%+" PRIi64, sint);
- break;
- case -2:
- sint = (int16_t)data.GetU16(offset_ptr);
- s.Printf("%+" PRIi64, sint);
- break;
- case -4:
- sint = (int32_t)data.GetU32(offset_ptr);
- s.Printf("%+" PRIi64, sint);
- break;
- case -8:
- sint = (int64_t)data.GetU64(offset_ptr);
- s.Printf("%+" PRIi64, sint);
- break;
- case -128:
- sint = data.GetSLEB128(offset_ptr);
- s.Printf("%+" PRIi64, sint);
- break;
- case 1:
- uint = data.GetU8(offset_ptr);
- s.Printf("0x%2.2" PRIx64, uint);
- break;
- case 2:
- uint = data.GetU16(offset_ptr);
- s.Printf("0x%4.4" PRIx64, uint);
- break;
- case 4:
- uint = data.GetU32(offset_ptr);
- s.Printf("0x%8.8" PRIx64, uint);
- break;
- case 8:
- uint = data.GetU64(offset_ptr);
- s.Printf("0x%16.16" PRIx64, uint);
- break;
- case 128:
- uint = data.GetULEB128(offset_ptr);
- s.Printf("0x%" PRIx64, uint);
- break;
- }
-
- return true;
-}
-
-bool DWARFExpression::PrintDWARFExpression(Stream &s, const DataExtractor &data,
- int address_size, int dwarf_ref_size,
- bool location_expression) {
- int op_count = 0;
- lldb::offset_t offset = 0;
- while (data.ValidOffset(offset)) {
- if (location_expression && op_count > 0)
- return false;
- if (op_count > 0)
- s.PutCString(", ");
- if (!print_dwarf_exp_op(s, data, &offset, address_size, dwarf_ref_size))
- return false;
- op_count++;
- }
-
- return true;
-}
-
-void DWARFExpression::PrintDWARFLocationList(
- Stream &s, const DWARFUnit *cu, const DataExtractor &debug_loc_data,
- lldb::offset_t offset) {
- uint64_t start_addr, end_addr;
- uint32_t addr_size = DWARFUnit::GetAddressByteSize(cu);
- s.SetAddressByteSize(DWARFUnit::GetAddressByteSize(cu));
- dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- while (debug_loc_data.ValidOffset(offset)) {
- start_addr = debug_loc_data.GetMaxU64(&offset, addr_size);
- end_addr = debug_loc_data.GetMaxU64(&offset, addr_size);
-
- if (start_addr == 0 && end_addr == 0)
- break;
-
- s.PutCString("\n ");
- s.Indent();
- if (cu)
- DumpAddressRange(s.AsRawOstream(), start_addr + base_addr,
- end_addr + base_addr, cu->GetAddressByteSize(), nullptr,
- ": ");
- uint32_t loc_length = debug_loc_data.GetU16(&offset);
-
- DataExtractor locationData(debug_loc_data, offset, loc_length);
- PrintDWARFExpression(s, locationData, addr_size, 4, false);
- offset += loc_length;
- }
-}
-
static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
ByteOrder byte_order, uint32_t addr_size) {
auto buffer_sp =
diff --git a/lldb/source/Expression/DiagnosticManager.cpp b/lldb/source/Expression/DiagnosticManager.cpp
index 48eba3586d30a..08977066e3330 100644
--- a/lldb/source/Expression/DiagnosticManager.cpp
+++ b/lldb/source/Expression/DiagnosticManager.cpp
@@ -1,4 +1,4 @@
-//===-- DiagnosticManager.cpp -----------------------------------*- C++ -*-===//
+//===-- DiagnosticManager.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -49,7 +49,7 @@ std::string DiagnosticManager::GetString(char separator) {
for (const auto &diagnostic : Diagnostics()) {
ret.append(StringForSeverity(diagnostic->GetSeverity()));
- ret.append(diagnostic->GetMessage());
+ ret.append(std::string(diagnostic->GetMessage()));
ret.push_back(separator);
}
diff --git a/lldb/source/Expression/Expression.cpp b/lldb/source/Expression/Expression.cpp
index 71369d0b9eec3..93f585edfce3d 100644
--- a/lldb/source/Expression/Expression.cpp
+++ b/lldb/source/Expression/Expression.cpp
@@ -1,4 +1,4 @@
-//===-- Expression.cpp ------------------------------------------*- C++ -*-===//
+//===-- Expression.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Expression/ExpressionVariable.cpp b/lldb/source/Expression/ExpressionVariable.cpp
index ed8da0ad8675b..d95f0745cf4ba 100644
--- a/lldb/source/Expression/ExpressionVariable.cpp
+++ b/lldb/source/Expression/ExpressionVariable.cpp
@@ -1,4 +1,4 @@
-//===-- ExpressionVariable.cpp ----------------------------------*- C++ -*-===//
+//===-- ExpressionVariable.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -69,20 +69,10 @@ void PersistentExpressionState::RegisterExecutionUnit(
// of the demangled name will find the mangled one (needed for looking up
// metadata pointers.)
Mangled mangler(global_var.m_name);
- mangler.GetDemangledName(lldb::eLanguageTypeUnknown);
+ mangler.GetDemangledName();
m_symbol_map[global_var.m_name.GetCString()] = global_var.m_remote_addr;
LLDB_LOGF(log, " Symbol: %s at 0x%" PRIx64 ".",
global_var.m_name.GetCString(), global_var.m_remote_addr);
}
}
}
-
-ConstString PersistentExpressionState::GetNextPersistentVariableName(
- Target &target, llvm::StringRef Prefix) {
- llvm::SmallString<64> name;
- {
- llvm::raw_svector_ostream os(name);
- os << Prefix << target.GetNextPersistentVariableIndex();
- }
- return ConstString(name);
-}
diff --git a/lldb/source/Expression/FunctionCaller.cpp b/lldb/source/Expression/FunctionCaller.cpp
index dc80c8169d7d2..26ab4bfaff539 100644
--- a/lldb/source/Expression/FunctionCaller.cpp
+++ b/lldb/source/Expression/FunctionCaller.cpp
@@ -1,4 +1,4 @@
-//===-- FunctionCaller.cpp ---------------------------------------*- C++-*-===//
+//===-- FunctionCaller.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -364,8 +364,9 @@ lldb::ExpressionResults FunctionCaller::ExecuteFunction(
if (return_value != lldb::eExpressionCompleted) {
LLDB_LOGF(log,
"== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
- "completed abnormally ==",
- m_name.c_str());
+ "completed abnormally: %s ==",
+ m_name.c_str(),
+ Process::ExecutionResultAsCString(return_value));
} else {
LLDB_LOGF(log,
"== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp
index e033b90cfd8bf..e3c9c1d7fdf54 100644
--- a/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/lldb/source/Expression/IRExecutionUnit.cpp
@@ -1,4 +1,4 @@
-//===-- IRExecutionUnit.cpp -------------------------------------*- C++ -*-===//
+//===-- IRExecutionUnit.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -265,11 +265,9 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
builder.setEngineKind(llvm::EngineKind::JIT)
.setErrorStr(&error_string)
- .setRelocationModel(triple.isOSBinFormatMachO()
- ? llvm::Reloc::PIC_
- : llvm::Reloc::Static)
- .setMCJITMemoryManager(
- std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
+ .setRelocationModel(triple.isOSBinFormatMachO() ? llvm::Reloc::PIC_
+ : llvm::Reloc::Static)
+ .setMCJITMemoryManager(std::make_unique<MemoryManager>(*this))
.setOptLevel(llvm::CodeGenOpt::Less);
llvm::StringRef mArch;
@@ -404,9 +402,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
ss.PutCString("\n");
emitNewLine = true;
ss.PutCString(" ");
- ss.PutCString(Mangled(failed_lookup)
- .GetDemangledName(lldb::eLanguageTypeObjC_plus_plus)
- .AsCString());
+ ss.PutCString(Mangled(failed_lookup).GetDemangledName().GetStringRef());
}
m_failed_lookups.clear();
@@ -645,10 +641,8 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection(
return return_value;
}
-static ConstString
-FindBestAlternateMangledName(ConstString demangled,
- const lldb::LanguageType &lang_type,
- const SymbolContext &sym_ctx) {
+static ConstString FindBestAlternateMangledName(ConstString demangled,
+ const SymbolContext &sym_ctx) {
CPlusPlusLanguage::MethodName cpp_name(demangled);
std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
@@ -670,7 +664,7 @@ FindBestAlternateMangledName(ConstString demangled,
for (size_t i = 0; i < alternates.size(); i++) {
ConstString alternate_mangled_name = alternates[i];
Mangled mangled(alternate_mangled_name);
- ConstString demangled = mangled.GetDemangledName(lang_type);
+ ConstString demangled = mangled.GetDemangledName();
CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
if (!cpp_name.IsValid())
@@ -718,12 +712,11 @@ void IRExecutionUnit::CollectCandidateCPlusPlusNames(
if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
Mangled mangled(name);
- ConstString demangled =
- mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
+ ConstString demangled = mangled.GetDemangledName();
if (demangled) {
- ConstString best_alternate_mangled_name = FindBestAlternateMangledName(
- demangled, lldb::eLanguageTypeC_plus_plus, sc);
+ ConstString best_alternate_mangled_name =
+ FindBestAlternateMangledName(demangled, sc);
if (best_alternate_mangled_name) {
CPP_specs.push_back(best_alternate_mangled_name);
@@ -746,20 +739,22 @@ void IRExecutionUnit::CollectFallbackNames(
for (const SearchSpec &C_spec : C_specs) {
ConstString name = C_spec.name;
- if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
- Mangled mangled_name(name);
- ConstString demangled_name =
- mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
- if (!demangled_name.IsEmpty()) {
- const char *demangled_cstr = demangled_name.AsCString();
- const char *lparen_loc = strchr(demangled_cstr, '(');
- if (lparen_loc) {
- llvm::StringRef base_name(demangled_cstr,
- lparen_loc - demangled_cstr);
- fallback_specs.push_back(ConstString(base_name));
- }
- }
- }
+ if (!CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
+ continue;
+
+ Mangled mangled_name(name);
+ ConstString demangled_name = mangled_name.GetDemangledName();
+ if (demangled_name.IsEmpty())
+ continue;
+
+ const char *demangled_cstr = demangled_name.AsCString();
+ const char *lparen_loc = strchr(demangled_cstr, '(');
+ if (!lparen_loc)
+ continue;
+
+ llvm::StringRef base_name(demangled_cstr,
+ lparen_loc - demangled_cstr);
+ fallback_specs.push_back(ConstString(base_name));
}
}
@@ -849,7 +844,7 @@ lldb::addr_t IRExecutionUnit::FindInSymbols(
};
if (sc.module_sp) {
- sc.module_sp->FindFunctions(spec.name, nullptr, spec.mask,
+ sc.module_sp->FindFunctions(spec.name, CompilerDeclContext(), spec.mask,
true, // include_symbols
false, // include_inlines
sc_list);
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index b2e4be5e40fd7..4c7a656265981 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -1,4 +1,4 @@
-//===-- IRInterpreter.cpp ---------------------------------------*- C++ -*-===//
+//===-- IRInterpreter.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -144,10 +144,10 @@ public:
ss.Printf(" 0x%llx", (unsigned long long)addr);
}
- return ss.GetString();
+ return std::string(ss.GetString());
}
- bool AssignToMatchType(lldb_private::Scalar &scalar, uint64_t u64value,
+ bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,
Type *type) {
size_t type_size = m_target_data.getTypeStoreSize(type);
@@ -157,7 +157,7 @@ public:
if (type_size != 1)
type_size = PowerOf2Ceil(type_size);
- scalar = llvm::APInt(type_size*8, u64value);
+ scalar = value.zextOrTrunc(type_size * 8);
return true;
}
@@ -171,32 +171,32 @@ public:
if (!ResolveConstantValue(value_apint, constant))
return false;
- return AssignToMatchType(scalar, value_apint.getLimitedValue(),
- value->getType());
- } else {
- lldb::addr_t process_address = ResolveValue(value, module);
- size_t value_size = m_target_data.getTypeStoreSize(value->getType());
+ return AssignToMatchType(scalar, value_apint, value->getType());
+ }
- lldb_private::DataExtractor value_extractor;
- lldb_private::Status extract_error;
+ lldb::addr_t process_address = ResolveValue(value, module);
+ size_t value_size = m_target_data.getTypeStoreSize(value->getType());
- m_execution_unit.GetMemoryData(value_extractor, process_address,
- value_size, extract_error);
+ lldb_private::DataExtractor value_extractor;
+ lldb_private::Status extract_error;
- if (!extract_error.Success())
- return false;
+ m_execution_unit.GetMemoryData(value_extractor, process_address,
+ value_size, extract_error);
- lldb::offset_t offset = 0;
- if (value_size <= 8) {
- uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
- return AssignToMatchType(scalar, u64value, value->getType());
- }
+ if (!extract_error.Success())
+ return false;
+
+ lldb::offset_t offset = 0;
+ if (value_size <= 8) {
+ uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
+ return AssignToMatchType(scalar, llvm::APInt(64, u64value),
+ value->getType());
}
return false;
}
- bool AssignValue(const Value *value, lldb_private::Scalar &scalar,
+ bool AssignValue(const Value *value, lldb_private::Scalar scalar,
Module &module) {
lldb::addr_t process_address = ResolveValue(value, module);
@@ -205,7 +205,9 @@ public:
lldb_private::Scalar cast_scalar;
- if (!AssignToMatchType(cast_scalar, scalar.ULongLong(), value->getType()))
+ scalar.MakeUnsigned();
+ if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
+ value->getType()))
return false;
size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
@@ -403,7 +405,7 @@ public:
ss.Printf("%02hhx ", buf.GetBytes()[i]);
}
- return ss.GetString();
+ return std::string(ss.GetString());
}
lldb::addr_t ResolveValue(const Value *value, Module &module) {
@@ -433,8 +435,6 @@ static const char *unsupported_opcode_error =
"Interpreter doesn't handle one of the expression's opcodes";
static const char *unsupported_operand_error =
"Interpreter doesn't handle one of the expression's operands";
-// static const char *interpreter_initialization_error = "Interpreter couldn't
-// be initialized";
static const char *interpreter_internal_error =
"Interpreter encountered an internal error";
static const char *bad_value_error =
@@ -444,8 +444,6 @@ static const char *memory_allocation_error =
static const char *memory_write_error = "Interpreter couldn't write to memory";
static const char *memory_read_error = "Interpreter couldn't read from memory";
static const char *infinite_loop_error = "Interpreter ran for too many cycles";
-// static const char *bad_result_error = "Result of expression
-// is in bad memory";
static const char *too_many_functions_error =
"Interpreter doesn't handle modules with multiple function bodies.";
@@ -597,7 +595,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
switch (operand_type->getTypeID()) {
default:
break;
- case Type::VectorTyID: {
+ case Type::FixedVectorTyID:
+ case Type::ScalableVectorTyID: {
LLDB_LOGF(log, "Unsupported operand type: %s",
PrintType(operand_type).c_str());
error.SetErrorString(unsupported_operand_error);
@@ -1370,7 +1369,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
// Find the address of the callee function
lldb_private::Scalar I;
- const llvm::Value *val = call_inst->getCalledValue();
+ const llvm::Value *val = call_inst->getCalledOperand();
if (!frame.EvaluateValue(I, val, module)) {
error.SetErrorToGenericError();
@@ -1510,7 +1509,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
lldb_private::ValueObject *vobj = retVal.get();
// Check if the return value is valid
- if (vobj == nullptr || retVal.empty()) {
+ if (vobj == nullptr || !retVal) {
error.SetErrorToGenericError();
error.SetErrorStringWithFormat("unable to get the return value");
return false;
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 02a875ec833ba..6b1e4c313a391 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -1,4 +1,4 @@
-//===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===//
+//===-- IRMemoryMap.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lldb/source/Expression/LLVMUserExpression.cpp b/lldb/source/Expression/LLVMUserExpression.cpp
index 1fc878bbd6163..187b427e66aa9 100644
--- a/lldb/source/Expression/LLVMUserExpression.cpp
+++ b/lldb/source/Expression/LLVMUserExpression.cpp
@@ -1,4 +1,4 @@
-//===-- LLVMUserExpression.cpp ----------------------------------*- C++ -*-===//
+//===-- LLVMUserExpression.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -134,6 +134,10 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
return lldb::eExpressionSetupError;
}
+ // Store away the thread ID for error reporting, in case it exits
+ // during execution:
+ lldb::tid_t expr_thread_id = exe_ctx.GetThreadRef().GetID();
+
Address wrapper_address(m_jit_start_addr);
std::vector<lldb::addr_t> args;
@@ -223,6 +227,14 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
"Use \"thread return -x\" to return to the state before expression "
"evaluation.");
return execution_result;
+ } else if (execution_result == lldb::eExpressionThreadVanished) {
+ diagnostic_manager.Printf(
+ eDiagnosticSeverityError,
+ "Couldn't complete execution; the thread "
+ "on which the expression was being run: 0x%" PRIx64
+ " exited during its execution.",
+ expr_thread_id);
+ return execution_result;
} else if (execution_result != lldb::eExpressionCompleted) {
diagnostic_manager.Printf(
eDiagnosticSeverityError, "Couldn't execute function; result was %s",
@@ -357,8 +369,3 @@ bool LLVMUserExpression::PrepareToExecuteJITExpression(
return true;
}
-lldb::ModuleSP LLVMUserExpression::GetJITModule() {
- if (m_execution_unit_sp)
- return m_execution_unit_sp->GetJITModule();
- return lldb::ModuleSP();
-}
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index cd332484debbc..f33462053f22a 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -1,4 +1,4 @@
-//===-- Materializer.cpp ----------------------------------------*- C++ -*-===//
+//===-- Materializer.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -399,7 +399,8 @@ uint32_t Materializer::AddPersistentVariable(
lldb::ExpressionVariableSP &persistent_variable_sp,
PersistentVariableDelegate *delegate, Status &err) {
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
- iter->reset(new EntityPersistentVariable(persistent_variable_sp, delegate));
+ *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
+ delegate);
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
@@ -698,7 +699,7 @@ public:
lldb::offset_t offset;
- ptr = extractor.GetPointer(&offset);
+ ptr = extractor.GetAddress(&offset);
dump_stream.PutChar('\n');
}
@@ -752,7 +753,7 @@ private:
uint32_t Materializer::AddVariable(lldb::VariableSP &variable_sp, Status &err) {
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
- iter->reset(new EntityVariable(variable_sp));
+ *iter = std::make_unique<EntityVariable>(variable_sp);
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
@@ -784,7 +785,9 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
- ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
+ ExecutionContextScope *exe_scope = frame_sp.get();
+ if (!exe_scope)
+ exe_scope = map.GetBestExecutionContextScope();
llvm::Optional<uint64_t> byte_size = m_type.GetByteSize(exe_scope);
if (!byte_size) {
@@ -834,7 +837,9 @@ public:
lldb::addr_t frame_bottom, Status &err) override {
err.Clear();
- ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
+ ExecutionContextScope *exe_scope = frame_sp.get();
+ if (!exe_scope)
+ exe_scope = map.GetBestExecutionContextScope();
if (!exe_scope) {
err.SetErrorString("Couldn't dematerialize a result variable: invalid "
@@ -881,11 +886,9 @@ public:
return;
}
- ConstString name =
- m_delegate
- ? m_delegate->GetName()
- : persistent_state->GetNextPersistentVariableName(
- *target_sp, persistent_state->GetPersistentVariablePrefix());
+ ConstString name = m_delegate
+ ? m_delegate->GetName()
+ : persistent_state->GetNextPersistentVariableName();
lldb::ExpressionVariableSP ret = persistent_state->CreatePersistentVariable(
exe_scope, name, m_type, map.GetByteOrder(), map.GetAddressByteSize());
@@ -972,7 +975,7 @@ public:
lldb::offset_t offset;
- ptr = extractor.GetPointer(&offset);
+ ptr = extractor.GetAddress(&offset);
dump_stream.PutChar('\n');
}
@@ -1032,8 +1035,8 @@ uint32_t Materializer::AddResultVariable(const CompilerType &type,
PersistentVariableDelegate *delegate,
Status &err) {
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
- iter->reset(new EntityResultVariable(type, is_program_reference,
- keep_in_memory, delegate));
+ *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
+ keep_in_memory, delegate);
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
@@ -1062,7 +1065,9 @@ public:
const Address sym_address = m_symbol.GetAddress();
- ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
+ ExecutionContextScope *exe_scope = frame_sp.get();
+ if (!exe_scope)
+ exe_scope = map.GetBestExecutionContextScope();
lldb::TargetSP target_sp;
@@ -1149,7 +1154,7 @@ private:
uint32_t Materializer::AddSymbol(const Symbol &symbol_sp, Status &err) {
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
- iter->reset(new EntitySymbol(symbol_sp));
+ *iter = std::make_unique<EntitySymbol>(symbol_sp);
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
@@ -1326,15 +1331,12 @@ private:
uint32_t Materializer::AddRegister(const RegisterInfo &register_info,
Status &err) {
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
- iter->reset(new EntityRegister(register_info));
+ *iter = std::make_unique<EntityRegister>(register_info);
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
-Materializer::Materializer()
- : m_dematerializer_wp(), m_current_offset(0), m_struct_alignment(8) {}
-
Materializer::~Materializer() {
DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
@@ -1346,7 +1348,6 @@ Materializer::DematerializerSP
Materializer::Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
lldb::addr_t process_address, Status &error) {
ExecutionContextScope *exe_scope = frame_sp.get();
-
if (!exe_scope)
exe_scope = map.GetBestExecutionContextScope();
@@ -1397,7 +1398,9 @@ void Materializer::Dematerializer::Dematerialize(Status &error,
if (thread_sp)
frame_sp = thread_sp->GetFrameWithStackID(m_stack_id);
- ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope();
+ ExecutionContextScope *exe_scope = frame_sp.get();
+ if (!exe_scope)
+ exe_scope = m_map->GetBestExecutionContextScope();
if (!IsValid()) {
error.SetErrorToGenericError();
diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp
index fcd0836847389..fd7c39686921d 100644
--- a/lldb/source/Expression/REPL.cpp
+++ b/lldb/source/Expression/REPL.cpp
@@ -1,4 +1,4 @@
-//===-- REPL.cpp ------------------------------------------------*- C++ -*-===//
+//===-- REPL.cpp ----------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -53,11 +53,11 @@ std::string REPL::GetSourcePath() {
ConstString file_basename = GetSourceFileBasename();
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
if (tmpdir_file_spec) {
- tmpdir_file_spec.GetFilename().SetCString(file_basename.AsCString());
+ tmpdir_file_spec.GetFilename() = file_basename;
m_repl_source_path = tmpdir_file_spec.GetPath();
} else {
tmpdir_file_spec = FileSpec("/tmp");
- tmpdir_file_spec.AppendPathComponent(file_basename.AsCString());
+ tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef());
}
return tmpdir_file_spec.GetPath();
@@ -216,7 +216,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
ci.SetPromptOnQuit(false);
// Execute the command
- CommandReturnObject result;
+ CommandReturnObject result(debugger.GetUseColor());
result.SetImmediateOutputStream(output_sp);
result.SetImmediateErrorStream(error_sp);
ci.HandleCommand(code.c_str(), eLazyBoolNo, result);
@@ -252,7 +252,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
if (io_handler_sp) {
io_handler_sp->SetIsDone(false);
- debugger.PushIOHandler(ci.GetIOHandler());
+ debugger.RunIOHandlerAsync(ci.GetIOHandler());
}
}
}
@@ -291,12 +291,10 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
const char *expr_prefix = nullptr;
lldb::ValueObjectSP result_valobj_sp;
Status error;
- lldb::ModuleSP jit_module_sp;
lldb::ExpressionResults execution_results =
UserExpression::Evaluate(exe_ctx, expr_options, code.c_str(),
expr_prefix, result_valobj_sp, error,
- nullptr, // Fixed Expression
- &jit_module_sp);
+ nullptr); // fixed expression
// CommandInterpreter &ci = debugger.GetCommandInterpreter();
@@ -370,7 +368,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
lldb::IOHandlerSP io_handler_sp(ci.GetIOHandler());
if (io_handler_sp) {
io_handler_sp->SetIsDone(false);
- debugger.PushIOHandler(ci.GetIOHandler());
+ debugger.RunIOHandlerAsync(ci.GetIOHandler());
}
}
break;
@@ -390,6 +388,11 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
error_sp->Printf("error: stopped for debug -- %s\n",
error.AsCString());
break;
+ case lldb::eExpressionThreadVanished:
+ // Shoulnd't happen???
+ error_sp->Printf("error: expression thread vanished -- %s\n",
+ error.AsCString());
+ break;
}
}
@@ -454,6 +457,10 @@ void REPL::IOHandlerComplete(IOHandler &io_handler,
debugger.GetCommandInterpreter().HandleCompletion(sub_request);
StringList matches, descriptions;
sub_result.GetMatches(matches);
+ // Prepend command prefix that was excluded in the completion request.
+ if (request.GetCursorIndex() == 0)
+ for (auto &match : matches)
+ match.insert(0, 1, ':');
sub_result.GetDescriptions(descriptions);
request.AddCompletions(matches, descriptions);
return;
@@ -488,14 +495,7 @@ void REPL::IOHandlerComplete(IOHandler &io_handler,
current_code.append("\n");
current_code += request.GetRawLine();
- StringList matches;
- int result = CompleteCode(current_code, matches);
- if (result == -2) {
- assert(matches.GetSize() == 1);
- request.AddCompletion(matches.GetStringAtIndex(0), "",
- CompletionMode::RewriteLine);
- } else
- request.AddCompletions(matches);
+ CompleteCode(current_code, request);
}
bool QuitCommandOverrideCallback(void *baton, const char **argv) {
@@ -530,7 +530,7 @@ Status REPL::RunLoop() {
save_default_line);
}
- debugger.PushIOHandler(io_handler_sp);
+ debugger.RunIOHandlerAsync(io_handler_sp);
// Check if we are in dedicated REPL mode where LLDB was start with the "--
// repl" option from the command line. Currently we know this by checking if
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp
index 3b507da8e4ab4..47d13f052bfb1 100644
--- a/lldb/source/Expression/UserExpression.cpp
+++ b/lldb/source/Expression/UserExpression.cpp
@@ -1,4 +1,4 @@
-//===-- UserExpression.cpp ---------------------------------*- C++ -*-===//
+//===-- UserExpression.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -53,8 +53,9 @@ UserExpression::UserExpression(ExecutionContextScope &exe_scope,
lldb::LanguageType language,
ResultType desired_type,
const EvaluateExpressionOptions &options)
- : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix),
- m_language(language), m_desired_type(desired_type), m_options(options) {}
+ : Expression(exe_scope), m_expr_text(std::string(expr)),
+ m_expr_prefix(std::string(prefix)), m_language(language),
+ m_desired_type(desired_type), m_options(options) {}
UserExpression::~UserExpression() {}
@@ -116,7 +117,7 @@ lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp,
lldb::ValueObjectSP valobj_sp;
valobj_sp = frame_sp->GetValueForVariableExpressionPath(
- object_name.AsCString(), lldb::eNoDynamicValues,
+ object_name.GetStringRef(), lldb::eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
StackFrame::eExpressionPathOptionsNoSyntheticChildren |
@@ -138,12 +139,12 @@ lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp,
return ret;
}
-lldb::ExpressionResults UserExpression::Evaluate(
- ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
- llvm::StringRef expr, llvm::StringRef prefix,
- lldb::ValueObjectSP &result_valobj_sp, Status &error,
- std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr,
- ValueObject *ctx_obj) {
+lldb::ExpressionResults
+UserExpression::Evaluate(ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options,
+ llvm::StringRef expr, llvm::StringRef prefix,
+ lldb::ValueObjectSP &result_valobj_sp, Status &error,
+ std::string *fixed_expression, ValueObject *ctx_obj) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
LIBLLDB_LOG_STEP));
@@ -167,8 +168,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
Target *target = exe_ctx.GetTargetPtr();
if (!target) {
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Passed a NULL target, can't "
- "run expressions.");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a NULL target, can't "
+ "run expressions.");
error.SetErrorString("expression passed a null target");
return lldb::eExpressionSetupError;
}
@@ -177,9 +178,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
if (process == nullptr || process->GetState() != lldb::eStateStopped) {
if (execution_policy == eExecutionPolicyAlways) {
- LLDB_LOGF(log,
- "== [UserExpression::Evaluate] Expression may not run, but "
- "is not constant ==");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Expression may not run, but "
+ "is not constant ==");
error.SetErrorString("expression needed to run but couldn't");
@@ -201,8 +201,8 @@ lldb::ExpressionResults UserExpression::Evaluate(
llvm::StringRef option_prefix(options.GetPrefix());
std::string full_prefix_storage;
if (!prefix.empty() && !option_prefix.empty()) {
- full_prefix_storage = prefix;
- full_prefix_storage.append(option_prefix);
+ full_prefix_storage = std::string(prefix);
+ full_prefix_storage.append(std::string(option_prefix));
full_prefix = full_prefix_storage;
} else if (!prefix.empty())
full_prefix = prefix;
@@ -224,15 +224,13 @@ lldb::ExpressionResults UserExpression::Evaluate(
desired_type, options, ctx_obj,
error));
if (error.Fail()) {
- if (log)
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Getting expression: %s ==",
- error.AsCString());
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Getting expression: {0} ==",
+ error.AsCString());
return lldb::eExpressionSetupError;
}
- if (log)
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Parsing expression %s ==",
- expr.str().c_str());
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Parsing expression {0} ==",
+ expr.str());
const bool keep_expression_in_memory = true;
const bool generate_debug_info = options.GetGenerateDebugInfo();
@@ -261,25 +259,40 @@ lldb::ExpressionResults UserExpression::Evaluate(
// If there is a fixed expression, try to parse it:
if (!parse_success) {
+ // Delete the expression that failed to parse before attempting to parse
+ // the next expression.
+ user_expression_sp.reset();
+
execution_results = lldb::eExpressionParseError;
if (fixed_expression && !fixed_expression->empty() &&
options.GetAutoApplyFixIts()) {
- lldb::UserExpressionSP fixed_expression_sp(
- target->GetUserExpressionForLanguage(fixed_expression->c_str(),
- full_prefix, language,
- desired_type, options, ctx_obj,
- error));
- DiagnosticManager fixed_diagnostic_manager;
- parse_success = fixed_expression_sp->Parse(
- fixed_diagnostic_manager, exe_ctx, execution_policy,
- keep_expression_in_memory, generate_debug_info);
- if (parse_success) {
- diagnostic_manager.Clear();
- user_expression_sp = fixed_expression_sp;
- } else {
- // If the fixed expression failed to parse, don't tell the user about,
- // that won't help.
- fixed_expression->clear();
+ const uint64_t max_fix_retries = options.GetRetriesWithFixIts();
+ for (uint64_t i = 0; i < max_fix_retries; ++i) {
+ // Try parsing the fixed expression.
+ lldb::UserExpressionSP fixed_expression_sp(
+ target->GetUserExpressionForLanguage(
+ fixed_expression->c_str(), full_prefix, language, desired_type,
+ options, ctx_obj, error));
+ DiagnosticManager fixed_diagnostic_manager;
+ parse_success = fixed_expression_sp->Parse(
+ fixed_diagnostic_manager, exe_ctx, execution_policy,
+ keep_expression_in_memory, generate_debug_info);
+ if (parse_success) {
+ diagnostic_manager.Clear();
+ user_expression_sp = fixed_expression_sp;
+ break;
+ } else {
+ // The fixed expression also didn't parse. Let's check for any new
+ // Fix-Its we could try.
+ if (fixed_expression_sp->GetFixedText()) {
+ *fixed_expression = fixed_expression_sp->GetFixedText();
+ } else {
+ // Fixed expression didn't compile without a fixit, don't retry and
+ // don't tell the user about it.
+ fixed_expression->clear();
+ break;
+ }
+ }
}
}
@@ -301,19 +314,12 @@ lldb::ExpressionResults UserExpression::Evaluate(
}
if (parse_success) {
- // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module
- // if one was created
- if (jit_module_sp_ptr)
- *jit_module_sp_ptr = user_expression_sp->GetJITModule();
-
lldb::ExpressionVariableSP expr_result;
if (execution_policy == eExecutionPolicyNever &&
!user_expression_sp->CanInterpret()) {
- if (log)
- LLDB_LOGF(log,
- "== [UserExpression::Evaluate] Expression may not run, but "
- "is not constant ==");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Expression may not run, but "
+ "is not constant ==");
if (!diagnostic_manager.Diagnostics().size())
error.SetExpressionError(lldb::eExpressionSetupError,
@@ -333,17 +339,15 @@ lldb::ExpressionResults UserExpression::Evaluate(
diagnostic_manager.Clear();
- if (log)
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Executing expression ==");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Executing expression ==");
execution_results =
user_expression_sp->Execute(diagnostic_manager, exe_ctx, options,
user_expression_sp, expr_result);
if (execution_results != lldb::eExpressionCompleted) {
- if (log)
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed "
- "abnormally ==");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed "
+ "abnormally ==");
if (!diagnostic_manager.Diagnostics().size())
error.SetExpressionError(
@@ -355,15 +359,13 @@ lldb::ExpressionResults UserExpression::Evaluate(
if (expr_result) {
result_valobj_sp = expr_result->GetValueObject();
- if (log)
- LLDB_LOGF(log,
- "== [UserExpression::Evaluate] Execution completed "
- "normally with result %s ==",
- result_valobj_sp->GetValueAsCString());
+ LLDB_LOG(log,
+ "== [UserExpression::Evaluate] Execution completed "
+ "normally with result %s ==",
+ result_valobj_sp->GetValueAsCString());
} else {
- if (log)
- LLDB_LOGF(log, "== [UserExpression::Evaluate] Execution completed "
- "normally with no result ==");
+ LLDB_LOG(log, "== [UserExpression::Evaluate] Execution completed "
+ "normally with no result ==");
error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
}
diff --git a/lldb/source/Expression/UtilityFunction.cpp b/lldb/source/Expression/UtilityFunction.cpp
index 2dbc0e9d73edc..3de2ee2acbbf1 100644
--- a/lldb/source/Expression/UtilityFunction.cpp
+++ b/lldb/source/Expression/UtilityFunction.cpp
@@ -1,4 +1,4 @@
-//===-- UtilityFunction.cpp -------------------------------------*- C++ -*-===//
+//===-- UtilityFunction.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.