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:
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user