Debugger: Rework expression parsing API.

ExpressionInfo:
- No longer stores an explicit result type (this is inferred from
  evaluation of the expression itself now).
- Introduce class ExpressionResult for returning the result of an
  expression computation. This can currently take the form of either
  a primitive value, or a value node object.
- Adjust UserInterfaceListener and ExpressionInfo::Listener to take
  the above changes into account, and correspondingly adjust all
  callers/listeners.

CLanguageExpressionEvaluator:
- Introduce child class Operand. This subsumes the functionality that
  was previously in the separate Number class, and can represent a
  primitive value, a value node or  a type. Also has functionality to
  implicity handle type promotion/inferring when performing calculations
  between operands.
- Adjust expression parser to operate in terms of Operands rather than
  Numbers. This allows a number of improvements, most notably that an
  expression can now return a value node as a result rather than only
  a primitive number. This capability isn't yet fully used, but paves
  the way for future uses such as an expression that evaluates to a data
  member, a global variable, or an arbitrary pointer of a particular type.
- Various cleanups/simplifications that were possible as a result of the above
  changes.

ExpressionEvaluationWindow/ExpressionPromptWindow:
- Remove type menu field, since the expression API no longer uses it.

Adding/removing expressions in the VariablesView is temporarily disabled,
pending some further rework there to properly handle the new result object.
This commit is contained in:
Rene Gollent
2014-11-22 17:06:48 -05:00
parent 8d48eb9311
commit 81c848a14a
29 changed files with 1682 additions and 1630 deletions
+29 -25
View File
@@ -35,6 +35,7 @@
#include "Team.h"
#include "Tracing.h"
#include "Value.h"
#include "ValueLocation.h"
#include "Worker.h"
@@ -63,7 +64,7 @@ public:
}
virtual void ExpressionEvaluated(ExpressionInfo* info, status_t result,
Value* value)
ExpressionResult* value)
{
fHandler->_HandleBreakpointConditionEvaluated(value);
}
@@ -888,14 +889,8 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
if (listener == NULL)
return false;
Type* type = new(std::nothrow) SyntheticPrimitiveType(B_UINT64_TYPE);
if (type == NULL)
return false;
BReference<Type> typeReference(type, true);
ExpressionInfo* expressionInfo = new(std::nothrow) ExpressionInfo(
userBreakpoint->Condition(), type);
userBreakpoint->Condition());
if (expressionInfo == NULL)
return false;
@@ -921,23 +916,13 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
teamLocker.Lock();
bool stop = false;
if (fConditionResult == NULL)
stop = true;
else {
BVariant value;
if (!fConditionResult->ToVariant(value))
stop = true;
if (!value.TypeIsInteger(value.Type()))
stop = true;
stop = value.ToBool();
fConditionResult->ReleaseReference();
fConditionResult = NULL;
}
if (stop)
if (_CheckStopCondition()) {
if (fConditionResult != NULL) {
fConditionResult->ReleaseReference();
fConditionResult = NULL;
}
return false;
else {
} else {
_SetThreadState(THREAD_STATE_RUNNING, NULL,
THREAD_STOPPED_UNKNOWN, BString());
fDebuggerInterface->ContinueThread(fThread->ID());
@@ -951,7 +936,7 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
void
ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value)
ThreadHandler::_HandleBreakpointConditionEvaluated(ExpressionResult* value)
{
fConditionResult = value;
if (fConditionResult != NULL)
@@ -960,6 +945,25 @@ ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value)
}
bool
ThreadHandler::_CheckStopCondition()
{
// if we we're unable to properly assess the expression result
// in any way, fall back to behaving like an unconditional breakpoint.
if (fConditionResult == NULL)
return true;
if (fConditionResult->Kind() != EXPRESSION_RESULT_KIND_PRIMITIVE)
return true;
BVariant value;
if (!fConditionResult->PrimitiveValue()->ToVariant(value))
return true;
return value.ToBool();
}
bool
ThreadHandler::_HasExitedFrame(target_addr_t framePointer) const
{