[LLDB] Update DIL to pass current 'frame var' tests. (#145055)
As a preliminary to making DIL the default implementation for 'frame var', ran check-lldb forcing 'frame var' to always use DIL, and discovered a few failing tests. This fixes most of them. The only remaining failing test is TestDAP_evaluate.py, which now passes a test case that the test says should fail (still investigating this). Changes in this PR: - Sets correct VariableSP, as well as returning ValueObjectSP (needed for several watchpoint tests). - Updates error messages, when looking up members, to match what the rest of LLDB expects. Also update appropriate DIL tests to expect the updated error messages. - Updates DIL parser to look for and accept "(anonymous namespace)::" at the front of a variable name.
This commit is contained in:
@@ -562,6 +562,7 @@ ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath(
|
||||
return ValueObjectConstResult::Create(nullptr, std::move(error));
|
||||
}
|
||||
|
||||
var_sp = (*valobj_or_error)->GetVariable();
|
||||
return *valobj_or_error;
|
||||
}
|
||||
|
||||
|
||||
@@ -363,8 +363,8 @@ Interpreter::Visit(const MemberOfNode *node) {
|
||||
|
||||
if (!m_use_synthetic || !field_obj) {
|
||||
std::string errMsg = llvm::formatv(
|
||||
"no member named '{0}' in {1}", node->GetFieldName(),
|
||||
base->GetCompilerType().GetFullyUnqualifiedType().TypeDescription());
|
||||
"\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(),
|
||||
base->GetTypeName().AsCString("<invalid type>"), base->GetName());
|
||||
return llvm::make_error<DILDiagnosticError>(
|
||||
m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
|
||||
}
|
||||
@@ -383,9 +383,9 @@ Interpreter::Visit(const MemberOfNode *node) {
|
||||
CompilerType base_type = base->GetCompilerType();
|
||||
if (node->GetIsArrow() && base->IsPointerType())
|
||||
base_type = base_type.GetPointeeType();
|
||||
std::string errMsg =
|
||||
llvm::formatv("no member named '{0}' in {1}", node->GetFieldName(),
|
||||
base_type.GetFullyUnqualifiedType().TypeDescription());
|
||||
std::string errMsg = llvm::formatv(
|
||||
"\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(),
|
||||
base->GetTypeName().AsCString("<invalid type>"), base->GetName());
|
||||
return llvm::make_error<DILDiagnosticError>(
|
||||
m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
|
||||
}
|
||||
|
||||
@@ -183,12 +183,14 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
|
||||
// "(" expression ")"
|
||||
//
|
||||
ASTNodeUP DILParser::ParsePrimaryExpression() {
|
||||
if (CurToken().IsOneOf({Token::coloncolon, Token::identifier})) {
|
||||
if (CurToken().IsOneOf(
|
||||
{Token::coloncolon, Token::identifier, Token::l_paren})) {
|
||||
// Save the source location for the diagnostics message.
|
||||
uint32_t loc = CurToken().GetLocation();
|
||||
auto identifier = ParseIdExpression();
|
||||
std::string identifier = ParseIdExpression();
|
||||
|
||||
return std::make_unique<IdentifierNode>(loc, identifier);
|
||||
if (!identifier.empty())
|
||||
return std::make_unique<IdentifierNode>(loc, identifier);
|
||||
}
|
||||
|
||||
if (CurToken().Is(Token::l_paren)) {
|
||||
@@ -232,16 +234,15 @@ std::string DILParser::ParseNestedNameSpecifier() {
|
||||
m_dil_lexer.LookAhead(4).Is(Token::coloncolon)) {
|
||||
m_dil_lexer.Advance(4);
|
||||
|
||||
assert(
|
||||
(CurToken().Is(Token::identifier) || CurToken().Is(Token::l_paren)) &&
|
||||
"Expected an identifier or anonymous namespace, but not found.");
|
||||
Expect(Token::coloncolon);
|
||||
m_dil_lexer.Advance();
|
||||
if (!CurToken().Is(Token::identifier) && !CurToken().Is(Token::l_paren)) {
|
||||
BailOut("Expected an identifier or anonymous namespace, but not found.",
|
||||
CurToken().GetLocation(), CurToken().GetSpelling().length());
|
||||
}
|
||||
// Continue parsing the nested_namespace_specifier.
|
||||
std::string identifier2 = ParseNestedNameSpecifier();
|
||||
if (identifier2.empty()) {
|
||||
Expect(Token::identifier);
|
||||
identifier2 = CurToken().GetSpelling();
|
||||
m_dil_lexer.Advance();
|
||||
}
|
||||
|
||||
return "(anonymous namespace)::" + identifier2;
|
||||
}
|
||||
|
||||
@@ -301,6 +302,9 @@ std::string DILParser::ParseIdExpression() {
|
||||
nested_name_specifier, unqualified_id);
|
||||
}
|
||||
|
||||
if (!CurToken().Is(Token::identifier))
|
||||
return "";
|
||||
|
||||
// No nested_name_specifier, but with global scope -- this is also a
|
||||
// qualified_id production. Follow the second production rule.
|
||||
if (global_scope) {
|
||||
|
||||
Reference in New Issue
Block a user