Debugger: More work on expression variables.

- If the current frame belongs to a class function, and the requested name
  doesn't match that of any of the parameters/local variables, attempt to
  find it in the member list as well.
This commit is contained in:
Rene Gollent
2014-10-29 22:48:19 -04:00
parent 00460996cf
commit d0c118a6dc
2 changed files with 71 additions and 18 deletions
@@ -21,6 +21,7 @@
#include "Number.h" #include "Number.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "Thread.h" #include "Thread.h"
#include "Type.h"
#include "Value.h" #include "Value.h"
#include "ValueNode.h" #include "ValueNode.h"
#include "ValueNodeManager.h" #include "ValueNodeManager.h"
@@ -779,11 +780,39 @@ CLanguageExpressionEvaluator::_ParseIdentifier()
AutoLocker<ValueNodeContainer> containerLocker(container); AutoLocker<ValueNodeContainer> containerLocker(container);
ValueNodeChild* child = NULL; ValueNodeChild* child = NULL;
ValueNodeChild* thisChild = NULL;
for (int32 i = 0; i < container->CountChildren(); i++) { for (int32 i = 0; i < container->CountChildren(); i++) {
ValueNodeChild* current = container->ChildAt(i); ValueNodeChild* current = container->ChildAt(i);
if (current->Name() == identifierName) { const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current; child = current;
break; break;
} else if (nodeName == "this")
thisChild = current;
}
if (child == NULL && thisChild != NULL) {
// the name was not found in the variables or parameters,
// but we have a class pointer. Try to find the name in the
// list of members.
_RequestValueIfNeeded(token, thisChild);
ValueNode* thisNode = thisChild->Node();
// skip the intermediate pointer
if (thisNode->GetType()->Kind() == TYPE_ADDRESS
&& thisNode->CountChildren() == 1) {
thisChild = thisNode->ChildAt(0);
_RequestValueIfNeeded(token, thisChild);
thisNode = thisChild->Node();
}
for (int32 i = 0; i < thisNode->CountChildren(); i++) {
ValueNodeChild* current = thisNode->ChildAt(i);
const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current;
break;
}
} }
} }
@@ -794,25 +823,9 @@ CLanguageExpressionEvaluator::_ParseIdentifier()
throw ParseException(errorMessage, token.position); throw ParseException(errorMessage, token.position);
} }
status_t state = child->LocationResolutionState(); _RequestValueIfNeeded(token, child);
if (state != B_OK) {
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
"%s", identifierName.String(),
strerror(state));
throw ParseException(errorMessage, token.position);
}
ValueNode* node = child->Node(); ValueNode* node = child->Node();
state = node->LocationAndValueResolutionState();
if (state == VALUE_NODE_UNRESOLVED) {
throw ValueNeededException(node);
} else if (state != B_OK) {
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
"%s", identifierName.String(),
strerror(state));
throw ParseException(errorMessage, token.position);
}
BVariant variant; BVariant variant;
Value* nodeValue = node->GetValue(); Value* nodeValue = node->GetValue();
nodeValue->ToVariant(variant); nodeValue->ToVariant(variant);
@@ -894,3 +907,39 @@ CLanguageExpressionEvaluator::_EatToken(int32 type)
throw ParseException(temp.String(), token.position); throw ParseException(temp.String(), token.position);
} }
} }
void
CLanguageExpressionEvaluator::_RequestValueIfNeeded(const Token& token,
ValueNodeChild* child)
{
status_t state;
BString errorMessage;
if (child->Node() == NULL) {
state = fNodeManager->AddChildNodes(child);
if (state != B_OK) {
errorMessage.SetToFormat("Unable to add children for node '%s': "
"%s", child->Name().String(), strerror(state));
throw ParseException(errorMessage, token.position);
}
}
state = child->LocationResolutionState();
if (state == VALUE_NODE_UNRESOLVED)
throw ValueNeededException(child->Node());
else if (state != B_OK) {
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
"%s", child->Name().String(), strerror(state));
throw ParseException(errorMessage, token.position);
}
ValueNode* node = child->Node();
state = node->LocationAndValueResolutionState();
if (state == VALUE_NODE_UNRESOLVED)
throw ValueNeededException(child->Node());
else if (state != B_OK) {
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
"%s", child->Name().String(), strerror(state));
throw ParseException(errorMessage, token.position);
}
}
@@ -16,6 +16,7 @@
class ValueNode; class ValueNode;
class ValueNodeChild;
class ValueNodeManager; class ValueNodeManager;
@@ -76,6 +77,9 @@ class CLanguageExpressionEvaluator {
void _EatToken(int32 type); void _EatToken(int32 type);
void _RequestValueIfNeeded(const Token& token,
ValueNodeChild* child);
Tokenizer* fTokenizer; Tokenizer* fTokenizer;
type_code fCurrentType; type_code fCurrentType;
ValueNodeManager* fNodeManager; ValueNodeManager* fNodeManager;