forked from OSchip/llvm-project
Re-organized the contents of RangeMap.h to be more concise and also allow for a Range, RangeArray, RangeData (range + data), or a RangeDataArray. We have many range implementations in LLDB and I will be converting over to using the classes in RangeMap.h so we can have one set of code that does ranges and searching of ranges.
Fixed up DWARFDebugAranges to use the new range classes. Fixed the enumeration parsing to take a lldb_private::Error to avoid a lot of duplicated code. Now when an invalid enumeration is supplied, an error will be returned and that error will contain a list of the valid enumeration values. llvm-svn: 141382
This commit is contained in:
parent
08d0491006
commit
cf0e4f0daf
|
@ -15,22 +15,24 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A vm address range. These can represent offsets ranges or actual
|
||||
// addresses.
|
||||
//----------------------------------------------------------------------
|
||||
template <typename B, typename S, class T>
|
||||
class RangeMap
|
||||
{
|
||||
public:
|
||||
typedef B RangeBaseType;
|
||||
typedef S RangeSizeType;
|
||||
typedef T EntryDataType;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Templatized classes for dealing with generic ranges and also
|
||||
// collections of ranges, or collections of ranges that have associated
|
||||
// data.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A simple range class where you get to define the type of the range
|
||||
// base "B", and the type used for the range byte size "S".
|
||||
//----------------------------------------------------------------------
|
||||
template <typename B, typename S>
|
||||
struct Range
|
||||
{
|
||||
RangeBaseType base;
|
||||
RangeSizeType size;
|
||||
typedef B BaseType;
|
||||
typedef S SizeType;
|
||||
|
||||
BaseType base;
|
||||
SizeType size;
|
||||
|
||||
Range () :
|
||||
base (0),
|
||||
|
@ -38,33 +40,33 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
Range (RangeBaseType b, RangeSizeType s) :
|
||||
Range (BaseType b, SizeType s) :
|
||||
base (b),
|
||||
size (s)
|
||||
{
|
||||
}
|
||||
|
||||
// Set the start value for the range, and keep the same size
|
||||
RangeBaseType
|
||||
GetBase () const
|
||||
BaseType
|
||||
GetRangeBase () const
|
||||
{
|
||||
return base;
|
||||
}
|
||||
|
||||
void
|
||||
SetBase (RangeBaseType b)
|
||||
SetRangeBase (BaseType b)
|
||||
{
|
||||
base = b;
|
||||
}
|
||||
|
||||
RangeBaseType
|
||||
GetEnd () const
|
||||
BaseType
|
||||
GetRangeEnd () const
|
||||
{
|
||||
return base + size;
|
||||
}
|
||||
|
||||
void
|
||||
SetEnd (RangeBaseType end)
|
||||
SetRangeEnd (BaseType end)
|
||||
{
|
||||
if (end > base)
|
||||
size = end - base;
|
||||
|
@ -72,14 +74,14 @@ public:
|
|||
size = 0;
|
||||
}
|
||||
|
||||
RangeSizeType
|
||||
GetSize () const
|
||||
SizeType
|
||||
GetByteSize () const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
SetSize (RangeSizeType s)
|
||||
SetByteSize (SizeType s)
|
||||
{
|
||||
size = s;
|
||||
}
|
||||
|
@ -91,21 +93,21 @@ public:
|
|||
}
|
||||
|
||||
bool
|
||||
Contains (RangeBaseType r) const
|
||||
Contains (BaseType r) const
|
||||
{
|
||||
return (GetBase() <= r) && (r < GetEnd());
|
||||
return (GetRangeBase() <= r) && (r < GetRangeEnd());
|
||||
}
|
||||
|
||||
bool
|
||||
ContainsEndInclusive (RangeBaseType r) const
|
||||
ContainsEndInclusive (BaseType r) const
|
||||
{
|
||||
return (GetBase() <= r) && (r <= GetEnd());
|
||||
return (GetRangeBase() <= r) && (r <= GetRangeEnd());
|
||||
}
|
||||
|
||||
bool
|
||||
Contains (const Range& range) const
|
||||
{
|
||||
return Contains(range.GetBase()) && ContainsEndInclusive(range.GetEnd());
|
||||
return Contains(range.GetRangeBase()) && ContainsEndInclusive(range.GetRangeEnd());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -128,179 +130,318 @@ public:
|
|||
return base != rhs.base || size != rhs.size;
|
||||
}
|
||||
};
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Range range;
|
||||
EntryDataType data;
|
||||
|
||||
Entry () :
|
||||
range (),
|
||||
data ()
|
||||
{
|
||||
}
|
||||
|
||||
Entry (RangeBaseType base, RangeSizeType size, EntryDataType d) :
|
||||
range (base, size),
|
||||
data (d)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
operator < (const Entry &rhs) const
|
||||
{
|
||||
const RangeBaseType lhs_base = range.GetBase();
|
||||
const RangeBaseType rhs_base = rhs.range.GetBase();
|
||||
if (lhs_base == rhs_base)
|
||||
{
|
||||
const RangeBaseType lhs_size = range.GetSize();
|
||||
const RangeBaseType rhs_size = rhs.range.GetSize();
|
||||
if (lhs_size == rhs_size)
|
||||
return data < rhs.data;
|
||||
else
|
||||
return lhs_size < rhs_size;
|
||||
}
|
||||
return lhs_base < rhs_base;
|
||||
}
|
||||
|
||||
bool
|
||||
operator == (const Entry &rhs) const
|
||||
{
|
||||
return range.GetBase() == rhs.range.GetBase() &&
|
||||
range.GetSize() == rhs.range.GetSize() &&
|
||||
data == rhs.data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator != (const Entry &rhs) const
|
||||
//----------------------------------------------------------------------
|
||||
// A range array class where you get to define the type of the ranges
|
||||
// that the collection contains.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
template <typename B, typename S>
|
||||
class RangeArray
|
||||
{
|
||||
typedef Range<B,S> Entry;
|
||||
|
||||
RangeArray ()
|
||||
{
|
||||
return range.GetBase() != rhs.range.GetBase() ||
|
||||
range.GetSize() != rhs.range.GetSize() ||
|
||||
data != rhs.data;
|
||||
}
|
||||
};
|
||||
|
||||
RangeMap ()
|
||||
{
|
||||
}
|
||||
|
||||
~RangeMap()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Append (const Entry &entry)
|
||||
{
|
||||
m_entries.push_back (entry);
|
||||
}
|
||||
|
||||
void
|
||||
Sort ()
|
||||
{
|
||||
if (m_entries.size() > 1)
|
||||
std::stable_sort (m_entries.begin(), m_entries.end());
|
||||
}
|
||||
|
||||
void
|
||||
CombineConsecutiveEntriesWithEqualData ()
|
||||
{
|
||||
typename std::vector<Entry>::iterator pos;
|
||||
typename std::vector<Entry>::iterator end;
|
||||
typename std::vector<Entry>::iterator prev;
|
||||
bool can_combine = false;
|
||||
// First we determine if we can combine any of the Entry objects so we
|
||||
// don't end up allocating and making a new collection for no reason
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
|
||||
{
|
||||
if (prev != end && prev->data == pos->data)
|
||||
{
|
||||
can_combine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We we can combine at least one entry, then we make a new collection
|
||||
// and populate it accordingly, and then swap it into place.
|
||||
if (can_combine)
|
||||
~RangeArray()
|
||||
{
|
||||
std::vector<Entry> minimal_ranges;
|
||||
}
|
||||
|
||||
void
|
||||
Append (const Entry &entry)
|
||||
{
|
||||
m_entries.push_back (entry);
|
||||
}
|
||||
|
||||
void
|
||||
Sort ()
|
||||
{
|
||||
if (m_entries.size() > 1)
|
||||
std::stable_sort (m_entries.begin(), m_entries.end());
|
||||
}
|
||||
|
||||
void
|
||||
CombineConsecutiveEntriesWithEqualData ()
|
||||
{
|
||||
typename std::vector<Entry>::iterator pos;
|
||||
typename std::vector<Entry>::iterator end;
|
||||
typename std::vector<Entry>::iterator prev;
|
||||
bool can_combine = false;
|
||||
// First we determine if we can combine any of the Entry objects so we
|
||||
// don't end up allocating and making a new collection for no reason
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
|
||||
{
|
||||
if (prev != end && prev->data == pos->data)
|
||||
minimal_ranges.back().range.SetEnd (pos->range.GetEnd());
|
||||
else
|
||||
minimal_ranges.push_back (*pos);
|
||||
{
|
||||
can_combine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap (minimal_ranges);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
IsEmpty () const
|
||||
{
|
||||
return m_entries.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
GetNumEntries () const
|
||||
{
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
GetEntryAtIndex (uint32_t i) const
|
||||
{
|
||||
if (i<m_entries.size())
|
||||
return &m_entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
BaseLessThan (const Entry& lhs, const Entry& rhs)
|
||||
{
|
||||
return lhs.range.GetBase() < rhs.range.GetBase();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
FindEntryThatContains (RangeBaseType addr) const
|
||||
{
|
||||
if ( !m_entries.empty() )
|
||||
{
|
||||
Entry entry;
|
||||
entry.range.SetBase(addr);
|
||||
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
|
||||
typename std::vector<Entry>::const_iterator end = m_entries.end();
|
||||
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
|
||||
|
||||
if ((pos != end) && (pos->range.GetBase() <= addr && addr < pos->range.GetEnd()))
|
||||
// We we can combine at least one entry, then we make a new collection
|
||||
// and populate it accordingly, and then swap it into place.
|
||||
if (can_combine)
|
||||
{
|
||||
return &(*pos);
|
||||
std::vector<Entry> minimal_ranges;
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
|
||||
{
|
||||
if (prev != end && prev->data == pos->data)
|
||||
minimal_ranges.back().range.SetEnd (pos->range.GetRangeEnd());
|
||||
else
|
||||
minimal_ranges.push_back (*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap (minimal_ranges);
|
||||
}
|
||||
else if (pos != begin)
|
||||
}
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
IsEmpty () const
|
||||
{
|
||||
return m_entries.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
GetNumEntries () const
|
||||
{
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
GetEntryAtIndex (uint32_t i) const
|
||||
{
|
||||
if (i<m_entries.size())
|
||||
return &m_entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
BaseLessThan (const Entry& lhs, const Entry& rhs)
|
||||
{
|
||||
return lhs.GetRangeBase() < rhs.GetRangeBase();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
FindEntryThatContains (B addr) const
|
||||
{
|
||||
if ( !m_entries.empty() )
|
||||
{
|
||||
--pos;
|
||||
if ((pos->range.GetBase() <= addr) && (addr < pos->range.GetEnd()))
|
||||
Entry entry (addr, 1);
|
||||
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
|
||||
typename std::vector<Entry>::const_iterator end = m_entries.end();
|
||||
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
|
||||
|
||||
if (pos != end && pos->Contains(addr))
|
||||
{
|
||||
return &(*pos);
|
||||
}
|
||||
else if (pos != begin)
|
||||
{
|
||||
--pos;
|
||||
if (pos->Contains(addr))
|
||||
{
|
||||
return &(*pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<Entry> m_entries;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A simple range with data class where you get to define the type of
|
||||
// the range base "B", the type used for the range byte size "S", and
|
||||
// the type for the associated data "T".
|
||||
//----------------------------------------------------------------------
|
||||
template <typename B, typename S, typename T>
|
||||
struct RangeData : public Range<B,S>
|
||||
{
|
||||
typedef T DataType;
|
||||
|
||||
DataType data;
|
||||
|
||||
RangeData () :
|
||||
Range<B,S> (),
|
||||
data ()
|
||||
{
|
||||
}
|
||||
|
||||
RangeData (B base, S size, DataType d) :
|
||||
Range<B,S> (base, size),
|
||||
data (d)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
operator < (const RangeData &rhs) const
|
||||
{
|
||||
if (this->base == rhs.base)
|
||||
{
|
||||
if (this->size == rhs.size)
|
||||
return this->data < rhs.data;
|
||||
else
|
||||
return this->size < rhs.size;
|
||||
}
|
||||
return this->base < rhs.base;
|
||||
}
|
||||
|
||||
bool
|
||||
operator == (const RangeData &rhs) const
|
||||
{
|
||||
return this->GetRangeBase() == rhs.GetRangeBase() &&
|
||||
this->GetByteSize() == rhs.GetByteSize() &&
|
||||
this->data == rhs.data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator != (const RangeData &rhs) const
|
||||
{
|
||||
return this->GetRangeBase() != rhs.GetRangeBase() ||
|
||||
this->GetByteSize() != rhs.GetByteSize() ||
|
||||
this->data != rhs.data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename B, typename S, typename T>
|
||||
class RangeDataArray
|
||||
{
|
||||
public:
|
||||
typedef RangeData<B,S,T> Entry;
|
||||
|
||||
RangeDataArray ()
|
||||
{
|
||||
}
|
||||
|
||||
~RangeDataArray()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Append (const Entry &entry)
|
||||
{
|
||||
m_entries.push_back (entry);
|
||||
}
|
||||
|
||||
void
|
||||
Sort ()
|
||||
{
|
||||
if (m_entries.size() > 1)
|
||||
std::stable_sort (m_entries.begin(), m_entries.end());
|
||||
}
|
||||
|
||||
void
|
||||
CombineConsecutiveEntriesWithEqualData ()
|
||||
{
|
||||
typename std::vector<Entry>::iterator pos;
|
||||
typename std::vector<Entry>::iterator end;
|
||||
typename std::vector<Entry>::iterator prev;
|
||||
bool can_combine = false;
|
||||
// First we determine if we can combine any of the Entry objects so we
|
||||
// don't end up allocating and making a new collection for no reason
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
|
||||
{
|
||||
if (prev != end && prev->data == pos->data)
|
||||
{
|
||||
can_combine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We we can combine at least one entry, then we make a new collection
|
||||
// and populate it accordingly, and then swap it into place.
|
||||
if (can_combine)
|
||||
{
|
||||
std::vector<Entry> minimal_ranges;
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
|
||||
{
|
||||
if (prev != end && prev->data == pos->data)
|
||||
minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
|
||||
else
|
||||
minimal_ranges.push_back (*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap (minimal_ranges);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<Entry> m_entries;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
IsEmpty () const
|
||||
{
|
||||
return m_entries.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
GetNumEntries () const
|
||||
{
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
GetEntryAtIndex (uint32_t i) const
|
||||
{
|
||||
if (i<m_entries.size())
|
||||
return &m_entries[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
BaseLessThan (const Entry& lhs, const Entry& rhs)
|
||||
{
|
||||
return lhs.GetRangeBase() < rhs.GetRangeBase();
|
||||
}
|
||||
|
||||
const Entry *
|
||||
FindEntryThatContains (B addr) const
|
||||
{
|
||||
if ( !m_entries.empty() )
|
||||
{
|
||||
Entry entry;
|
||||
entry.SetRangeBase(addr);
|
||||
entry.SetByteSize(1);
|
||||
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
|
||||
typename std::vector<Entry>::const_iterator end = m_entries.end();
|
||||
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
|
||||
|
||||
if (pos != end && pos->Contains(addr))
|
||||
{
|
||||
return &(*pos);
|
||||
}
|
||||
else if (pos != begin)
|
||||
{
|
||||
--pos;
|
||||
if (pos->Contains(addr))
|
||||
{
|
||||
return &(*pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<Entry> m_entries;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ public:
|
|||
StringToBoolean (const char *s, bool fail_value, bool *success_ptr);
|
||||
|
||||
static int32_t
|
||||
StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, bool *success_ptr);
|
||||
StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error);
|
||||
|
||||
static lldb::ScriptLanguage
|
||||
StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr);
|
||||
|
|
|
@ -91,45 +91,42 @@ CommandObjectBreakpointCommandAdd::CommandOptions::SetOptionValue
|
|||
char short_option = (char) m_getopt_table[option_idx].val;
|
||||
|
||||
switch (short_option)
|
||||
{
|
||||
case 'o':
|
||||
m_use_one_liner = true;
|
||||
m_one_liner = option_arg;
|
||||
break;
|
||||
break;
|
||||
case 's':
|
||||
{
|
||||
bool found_one = false;
|
||||
m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
|
||||
g_option_table[option_idx].enum_values,
|
||||
eScriptLanguageNone,
|
||||
&found_one);
|
||||
if (!found_one)
|
||||
error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
|
||||
option_arg,
|
||||
short_option);
|
||||
{
|
||||
case 'o':
|
||||
m_use_one_liner = true;
|
||||
m_one_liner = option_arg;
|
||||
break;
|
||||
|
||||
if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
|
||||
{
|
||||
m_use_commands = false;
|
||||
m_use_script_language = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_use_commands = true;
|
||||
m_use_script_language = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
bool success_ptr;
|
||||
m_stop_on_error = Args::StringToBoolean(option_arg, false, &success_ptr);
|
||||
if (!success_ptr)
|
||||
error.SetErrorStringWithFormat("Invalid value for stop-on-error: \"%s\".\n", option_arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
|
||||
g_option_table[option_idx].enum_values,
|
||||
eScriptLanguageNone,
|
||||
error);
|
||||
|
||||
if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
|
||||
{
|
||||
m_use_commands = false;
|
||||
m_use_script_language = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_use_commands = true;
|
||||
m_use_script_language = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
{
|
||||
bool success = false;
|
||||
m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("Invalid value for stop-on-error: \"%s\".\n", option_arg);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1876,17 +1876,10 @@ public:
|
|||
switch (short_option)
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
bool found_one = false;
|
||||
m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
|
||||
g_option_table[option_idx].enum_values,
|
||||
eSortOrderNone,
|
||||
&found_one);
|
||||
if (!found_one)
|
||||
error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
|
||||
option_arg,
|
||||
short_option);
|
||||
}
|
||||
error);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -307,11 +307,8 @@ public:
|
|||
|
||||
case 'm':
|
||||
{
|
||||
bool found_one = false;
|
||||
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
|
||||
m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
|
||||
if (!found_one)
|
||||
error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
|
||||
m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -807,17 +804,16 @@ public:
|
|||
break;
|
||||
case 'm':
|
||||
{
|
||||
bool found_one = false;
|
||||
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
|
||||
lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, &found_one);
|
||||
lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
|
||||
|
||||
if (!found_one)
|
||||
error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
|
||||
else if (run_mode == eAllThreads)
|
||||
m_stop_others = false;
|
||||
else
|
||||
m_stop_others = true;
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
if (run_mode == eAllThreads)
|
||||
m_stop_others = false;
|
||||
else
|
||||
m_stop_others = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -2381,14 +2381,9 @@ void
|
|||
UserSettingsController::UpdateEnumVariable (OptionEnumValueElement *enum_values,
|
||||
int *enum_var,
|
||||
const char *new_value,
|
||||
Error &err)
|
||||
Error &error)
|
||||
{
|
||||
bool found_one;
|
||||
|
||||
*enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, &found_one);
|
||||
|
||||
if (!found_one)
|
||||
err.SetErrorString ("Invalid enumeration value; cannot update variable.\n");
|
||||
*enum_var = Args::StringToOptionEnum (new_value, enum_values, enum_values[0].value, error);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -834,21 +834,36 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t
|
|||
|
||||
|
||||
int32_t
|
||||
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, bool *success_ptr)
|
||||
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
|
||||
{
|
||||
if (enum_values && s && s[0])
|
||||
if (enum_values)
|
||||
{
|
||||
for (int i = 0; enum_values[i].string_value != NULL ; i++)
|
||||
if (s && s[0])
|
||||
{
|
||||
if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value)
|
||||
for (int i = 0; enum_values[i].string_value != NULL ; i++)
|
||||
{
|
||||
if (success_ptr) *success_ptr = true;
|
||||
return enum_values[i].value;
|
||||
if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value)
|
||||
{
|
||||
error.Clear();
|
||||
return enum_values[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StreamString strm;
|
||||
strm.PutCString ("invalid enumeration value, valid values are: ");
|
||||
for (int i = 0; enum_values[i].string_value != NULL; i++)
|
||||
{
|
||||
strm.Printf ("%s\"%s\"",
|
||||
i > 0 ? ", " : "",
|
||||
enum_values[i].string_value);
|
||||
}
|
||||
error.SetErrorString(strm.GetData());
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString ("invalid enumeration argument");
|
||||
}
|
||||
if (success_ptr) *success_ptr = false;
|
||||
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,12 +72,9 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter,
|
|||
{
|
||||
case 'd':
|
||||
{
|
||||
bool success;
|
||||
int32_t result;
|
||||
result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, &success);
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("Invalid dynamic value setting: \"%s\".\n", option_arg);
|
||||
else
|
||||
result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, error);
|
||||
if (error.Success())
|
||||
use_dynamic = (lldb::DynamicValueType) result;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -64,21 +64,16 @@ OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter,
|
|||
char short_option = (char) g_option_table[option_idx].short_option;
|
||||
switch (short_option)
|
||||
{
|
||||
case 'w': {
|
||||
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
|
||||
watch_type = (WatchType) Args::StringToOptionEnum(option_arg, enum_values, 0, &watch_variable);
|
||||
if (!watch_variable)
|
||||
error.SetErrorStringWithFormat("Invalid option arg for '-w': '%s'.\n", option_arg);
|
||||
case 'w':
|
||||
watch_type = (WatchType) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
|
||||
if (error.Success())
|
||||
watch_variable = true;
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
bool success = false;
|
||||
OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
|
||||
watch_size = (WatchType) Args::StringToOptionEnum(option_arg, enum_values, 0, &success);
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("Invalid option arg for '-x': '%s'.\n", option_arg);
|
||||
|
||||
case 'x':
|
||||
watch_size = (WatchType) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
|
||||
break;
|
||||
|
@ -91,8 +86,8 @@ void
|
|||
OptionGroupWatchpoint::OptionParsingStarting (CommandInterpreter &interpreter)
|
||||
{
|
||||
watch_variable = false;
|
||||
watch_type = eWatchInvalid;
|
||||
watch_size = 0;
|
||||
watch_type = eWatchInvalid;
|
||||
watch_size = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,8 +119,8 @@ DWARFDebugAranges::Dump (Log *log) const
|
|||
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
|
||||
log->Printf ("0x%8.8x: [0x%llx - 0x%llx)",
|
||||
entry->data,
|
||||
entry->range.GetBase(),
|
||||
entry->range.GetEnd());
|
||||
entry->GetRangeBase(),
|
||||
entry->GetRangeEnd());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class SymbolFileDWARF;
|
|||
class DWARFDebugAranges
|
||||
{
|
||||
protected:
|
||||
typedef lldb_private::RangeMap<dw_addr_t, uint32_t, dw_offset_t> RangeToDIE;
|
||||
typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t> RangeToDIE;
|
||||
|
||||
public:
|
||||
typedef RangeToDIE::Entry Range;
|
||||
|
|
Loading…
Reference in New Issue