Skip to content

Conversation

kuilpd
Copy link
Contributor

@kuilpd kuilpd commented Aug 27, 2025

This patch introduces ScalarLiteralNode without any uses by other nodes yet. It also includes lexing and parsing for integer and floating point numbers.
Reapplies #152308 with a fix.

@kuilpd kuilpd requested a review from JDevlieghere as a code owner August 27, 2025 12:25
@kuilpd kuilpd added the lldb label Aug 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

@llvm/pr-subscribers-lldb

Author: Ilia Kuklin (kuilpd)

Changes

This patch introduces ScalarLiteralNode without any uses by other nodes yet. It also includes lexing and parsing for integer and floating point numbers.


Patch is 28.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155610.diff

15 Files Affected:

  • (modified) lldb/docs/dil-expr-lang.ebnf (+5-1)
  • (modified) lldb/include/lldb/ValueObject/DILAST.h (+52)
  • (modified) lldb/include/lldb/ValueObject/DILEval.h (+9)
  • (modified) lldb/include/lldb/ValueObject/DILLexer.h (+3-1)
  • (modified) lldb/include/lldb/ValueObject/DILParser.h (+3)
  • (modified) lldb/source/ValueObject/DILAST.cpp (+9)
  • (modified) lldb/source/ValueObject/DILEval.cpp (+105)
  • (modified) lldb/source/ValueObject/DILLexer.cpp (+42-15)
  • (modified) lldb/source/ValueObject/DILParser.cpp (+67)
  • (modified) lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py (+3-7)
  • (modified) lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py (+1-1)
  • (added) lldb/test/API/commands/frame/var-dil/expr/Literals/Makefile (+3)
  • (added) lldb/test/API/commands/frame/var-dil/expr/Literals/TestFrameVarDILLiterals.py (+88)
  • (added) lldb/test/API/commands/frame/var-dil/expr/Literals/main.cpp (+3)
  • (modified) lldb/unittests/ValueObject/DILLexerTests.cpp (+36-6)
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index 783432dabd6db..67328939ba420 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -15,7 +15,8 @@ postfix_expression = primary_expression
                    | postfix_expression "." id_expression
                    | postfix_expression "->" id_expression ;
 
-primary_expression = id_expression
+primary_expression = numeric_literal
+                   | id_expression
                    | "(" expression ")" ;
 
 id_expression = unqualified_id
@@ -31,6 +32,9 @@ identifier = ? C99 Identifier ? ;
 
 integer_literal = ? Integer constant: hexademical, decimal, octal, binary ? ;
 
+numeric_literal = ? Integer constant: hexademical, decimal, octal, binary ?
+                | ? Floating constant ? ;
+
 register = "$" ? Register name ? ;
 
 nested_name_specifier = type_name "::"
diff --git a/lldb/include/lldb/ValueObject/DILAST.h b/lldb/include/lldb/ValueObject/DILAST.h
index 709f0639135f1..1d10755c46e39 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -21,7 +21,9 @@ enum class NodeKind {
   eArraySubscriptNode,
   eBitExtractionNode,
   eErrorNode,
+  eFloatLiteralNode,
   eIdentifierNode,
+  eIntegerLiteralNode,
   eMemberOfNode,
   eUnaryOpNode,
 };
@@ -178,6 +180,52 @@ class BitFieldExtractionNode : public ASTNode {
   int64_t m_last_index;
 };
 
+enum class IntegerTypeSuffix { None, Long, LongLong };
+
+class IntegerLiteralNode : public ASTNode {
+public:
+  IntegerLiteralNode(uint32_t location, llvm::APInt value, uint32_t radix,
+                     bool is_unsigned, IntegerTypeSuffix type)
+      : ASTNode(location, NodeKind::eIntegerLiteralNode),
+        m_value(std::move(value)), m_radix(radix), m_is_unsigned(is_unsigned),
+        m_type(type) {}
+
+  llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
+
+  const llvm::APInt &GetValue() const { return m_value; }
+  uint32_t GetRadix() const { return m_radix; }
+  bool IsUnsigned() const { return m_is_unsigned; }
+  IntegerTypeSuffix GetTypeSuffix() const { return m_type; }
+
+  static bool classof(const ASTNode *node) {
+    return node->GetKind() == NodeKind::eIntegerLiteralNode;
+  }
+
+private:
+  llvm::APInt m_value;
+  uint32_t m_radix;
+  bool m_is_unsigned;
+  IntegerTypeSuffix m_type;
+};
+
+class FloatLiteralNode : public ASTNode {
+public:
+  FloatLiteralNode(uint32_t location, llvm::APFloat value)
+      : ASTNode(location, NodeKind::eFloatLiteralNode),
+        m_value(std::move(value)) {}
+
+  llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override;
+
+  const llvm::APFloat &GetValue() const { return m_value; }
+
+  static bool classof(const ASTNode *node) {
+    return node->GetKind() == NodeKind::eFloatLiteralNode;
+  }
+
+private:
+  llvm::APFloat m_value;
+};
+
 /// This class contains one Visit method for each specialized type of
 /// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
 /// the correct function in the DIL expression evaluator for evaluating that
@@ -195,6 +243,10 @@ class Visitor {
   Visit(const ArraySubscriptNode *node) = 0;
   virtual llvm::Expected<lldb::ValueObjectSP>
   Visit(const BitFieldExtractionNode *node) = 0;
+  virtual llvm::Expected<lldb::ValueObjectSP>
+  Visit(const IntegerLiteralNode *node) = 0;
+  virtual llvm::Expected<lldb::ValueObjectSP>
+  Visit(const FloatLiteralNode *node) = 0;
 };
 
 } // namespace lldb_private::dil
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 45e29b3ddcd7b..5a48c2c989f4d 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -54,6 +54,15 @@ class Interpreter : Visitor {
   Visit(const ArraySubscriptNode *node) override;
   llvm::Expected<lldb::ValueObjectSP>
   Visit(const BitFieldExtractionNode *node) override;
+  llvm::Expected<lldb::ValueObjectSP>
+  Visit(const IntegerLiteralNode *node) override;
+  llvm::Expected<lldb::ValueObjectSP>
+  Visit(const FloatLiteralNode *node) override;
+
+  llvm::Expected<CompilerType>
+  PickIntegerType(lldb::TypeSystemSP type_system,
+                  std::shared_ptr<ExecutionContextScope> ctx,
+                  const IntegerLiteralNode *literal);
 
   // Used by the interpreter to create objects, perform casts, etc.
   lldb::TargetSP m_target;
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 9c1ba97680253..4345e6ce7f26b 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -28,12 +28,14 @@ class Token {
     arrow,
     coloncolon,
     eof,
+    float_constant,
     identifier,
+    integer_constant,
     l_paren,
     l_square,
     minus,
-    numeric_constant,
     period,
+    plus,
     r_paren,
     r_square,
     star,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 9eda7bac4a364..90df109337dcf 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -96,6 +96,9 @@ class DILParser {
   std::string ParseIdExpression();
   std::string ParseUnqualifiedId();
   std::optional<int64_t> ParseIntegerConstant();
+  ASTNodeUP ParseNumericLiteral();
+  ASTNodeUP ParseIntegerLiteral();
+  ASTNodeUP ParseFloatingPointLiteral();
 
   void BailOut(const std::string &error, uint32_t loc, uint16_t err_len);
 
diff --git a/lldb/source/ValueObject/DILAST.cpp b/lldb/source/ValueObject/DILAST.cpp
index b1cd824c2299e..70564663a62cd 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -37,4 +37,13 @@ BitFieldExtractionNode::Accept(Visitor *v) const {
   return v->Visit(this);
 }
 
+llvm::Expected<lldb::ValueObjectSP>
+IntegerLiteralNode::Accept(Visitor *v) const {
+  return v->Visit(this);
+}
+
+llvm::Expected<lldb::ValueObjectSP> FloatLiteralNode::Accept(Visitor *v) const {
+  return v->Visit(this);
+}
+
 } // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 3ac200228acfd..c6cf41ee9e9ee 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/ValueObject/DILEval.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/ValueObject/DILAST.h"
@@ -497,4 +499,107 @@ Interpreter::Visit(const BitFieldExtractionNode *node) {
   return child_valobj_sp;
 }
 
+static llvm::Expected<lldb::TypeSystemSP>
+GetTypeSystemFromCU(std::shared_ptr<StackFrame> ctx) {
+  SymbolContext symbol_context =
+      ctx->GetSymbolContext(lldb::eSymbolContextCompUnit);
+  lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
+
+  symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule);
+  return symbol_context.module_sp->GetTypeSystemForLanguage(language);
+}
+
+static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
+                                 lldb::BasicType basic_type) {
+  if (type_system)
+    return type_system.get()->GetBasicTypeFromAST(basic_type);
+
+  return CompilerType();
+}
+
+llvm::Expected<CompilerType>
+Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
+                             std::shared_ptr<ExecutionContextScope> ctx,
+                             const IntegerLiteralNode *literal) {
+  // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
+  // an unsigned integer.
+  bool unsigned_is_allowed = literal->IsUnsigned() || literal->GetRadix() != 10;
+  llvm::APInt apint = literal->GetValue();
+
+  llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
+  if (literal->GetTypeSuffix() <= IntegerTypeSuffix::None)
+    candidates.emplace_back(lldb::eBasicTypeInt,
+                            unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
+                                                : lldb::eBasicTypeInvalid);
+  if (literal->GetTypeSuffix() <= IntegerTypeSuffix::Long)
+    candidates.emplace_back(lldb::eBasicTypeLong,
+                            unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
+                                                : lldb::eBasicTypeInvalid);
+  candidates.emplace_back(lldb::eBasicTypeLongLong,
+                          lldb::eBasicTypeUnsignedLongLong);
+  for (auto [signed_, unsigned_] : candidates) {
+    CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
+    if (!signed_type)
+      continue;
+    llvm::Expected<uint64_t> size = signed_type.GetBitSize(ctx.get());
+    if (!size)
+      return size.takeError();
+    if (!literal->IsUnsigned() && apint.isIntN(*size - 1))
+      return signed_type;
+    if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
+      return type_system->GetBasicTypeFromAST(unsigned_);
+  }
+
+  return llvm::make_error<DILDiagnosticError>(
+      m_expr,
+      "integer literal is too large to be represented in any integer type",
+      literal->GetLocation());
+}
+
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const IntegerLiteralNode *node) {
+  llvm::Expected<lldb::TypeSystemSP> type_system =
+      GetTypeSystemFromCU(m_exe_ctx_scope);
+  if (!type_system)
+    return type_system.takeError();
+
+  llvm::Expected<CompilerType> type =
+      PickIntegerType(*type_system, m_exe_ctx_scope, node);
+  if (!type)
+    return type.takeError();
+
+  Scalar scalar = node->GetValue();
+  // APInt from StringRef::getAsInteger comes with just enough bitwidth to
+  // hold the value. This adjusts APInt bitwidth to match the compiler type.
+  llvm::Expected<uint64_t> type_bitsize =
+      type->GetBitSize(m_exe_ctx_scope.get());
+  if (!type_bitsize)
+    return type_bitsize.takeError();
+  scalar.TruncOrExtendTo(*type_bitsize, false);
+  return ValueObject::CreateValueObjectFromScalar(m_target, scalar, *type,
+                                                  "result");
+}
+
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::Visit(const FloatLiteralNode *node) {
+  llvm::Expected<lldb::TypeSystemSP> type_system =
+      GetTypeSystemFromCU(m_exe_ctx_scope);
+  if (!type_system)
+    return type_system.takeError();
+
+  bool isFloat =
+      &node->GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
+  lldb::BasicType basic_type =
+      isFloat ? lldb::eBasicTypeFloat : lldb::eBasicTypeDouble;
+  CompilerType type = GetBasicType(*type_system, basic_type);
+
+  if (!type)
+    return llvm::make_error<DILDiagnosticError>(
+        m_expr, "unable to create a const literal", node->GetLocation());
+
+  Scalar scalar = node->GetValue();
+  return ValueObject::CreateValueObjectFromScalar(m_target, scalar, type,
+                                                  "result");
+}
+
 } // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index eaefaf484bc18..0b2288a9d9230 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -28,18 +28,23 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
     return "coloncolon";
   case Kind::eof:
     return "eof";
+  case Kind::float_constant:
+    return "float_constant";
   case Kind::identifier:
     return "identifier";
+  case Kind::integer_constant:
+    return "integer_constant";
   case Kind::l_paren:
     return "l_paren";
   case Kind::l_square:
     return "l_square";
   case Kind::minus:
     return "minus";
-  case Kind::numeric_constant:
-    return "numeric_constant";
   case Kind::period:
     return "period";
+    return "l_square";
+  case Kind::plus:
+    return "plus";
   case Kind::r_paren:
     return "r_paren";
   case Kind::r_square:
@@ -70,13 +75,32 @@ static std::optional<llvm::StringRef> IsWord(llvm::StringRef expr,
   return candidate;
 }
 
-static bool IsNumberBodyChar(char ch) { return IsDigit(ch) || IsLetter(ch); }
+static bool IsNumberBodyChar(char ch) {
+  return IsDigit(ch) || IsLetter(ch) || ch == '.';
+}
 
-static std::optional<llvm::StringRef> IsNumber(llvm::StringRef expr,
-                                               llvm::StringRef &remainder) {
-  if (IsDigit(remainder[0])) {
-    llvm::StringRef number = remainder.take_while(IsNumberBodyChar);
-    remainder = remainder.drop_front(number.size());
+static std::optional<llvm::StringRef> IsNumber(llvm::StringRef &remainder,
+                                               bool &isFloat) {
+  llvm::StringRef tail = remainder;
+  llvm::StringRef body = tail.take_while(IsNumberBodyChar);
+  size_t dots = body.count('.');
+  if (dots > 1 || dots == body.size())
+    return std::nullopt;
+  if (IsDigit(body.front()) || (body[0] == '.' && IsDigit(body[1]))) {
+    isFloat = dots == 1;
+    tail = tail.drop_front(body.size());
+    bool isHex = body.contains_insensitive('x');
+    bool hasExp = !isHex && body.contains_insensitive('e');
+    bool hasHexExp = isHex && body.contains_insensitive('p');
+    if (hasExp || hasHexExp) {
+      isFloat = true; // This marks numbers like 0x1p1 and 1e1 as float
+      if (body.ends_with_insensitive("e") || body.ends_with_insensitive("p"))
+        if (tail.consume_front("+") || tail.consume_front("-"))
+          tail = tail.drop_while(IsNumberBodyChar);
+    }
+    size_t number_length = remainder.size() - tail.size();
+    llvm::StringRef number = remainder.take_front(number_length);
+    remainder = remainder.drop_front(number_length);
     return number;
   }
   return std::nullopt;
@@ -106,18 +130,21 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
     return Token(Token::eof, "", (uint32_t)expr.size());
 
   uint32_t position = cur_pos - expr.begin();
-  std::optional<llvm::StringRef> maybe_number = IsNumber(expr, remainder);
-  if (maybe_number)
-    return Token(Token::numeric_constant, maybe_number->str(), position);
+  bool isFloat = false;
+  std::optional<llvm::StringRef> maybe_number = IsNumber(remainder, isFloat);
+  if (maybe_number) {
+    auto kind = isFloat ? Token::float_constant : Token::integer_constant;
+    return Token(kind, maybe_number->str(), position);
+  }
   std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
   if (maybe_word)
     return Token(Token::identifier, maybe_word->str(), position);
 
   constexpr std::pair<Token::Kind, const char *> operators[] = {
-      {Token::amp, "&"},     {Token::arrow, "->"},   {Token::coloncolon, "::"},
-      {Token::l_paren, "("}, {Token::l_square, "["}, {Token::minus, "-"},
-      {Token::period, "."},  {Token::r_paren, ")"},  {Token::r_square, "]"},
-      {Token::star, "*"},
+      {Token::amp, "&"},      {Token::arrow, "->"},   {Token::coloncolon, "::"},
+      {Token::l_paren, "("},  {Token::l_square, "["}, {Token::minus, "-"},
+      {Token::period, "."},   {Token::plus, "+"},     {Token::r_paren, ")"},
+      {Token::r_square, "]"}, {Token::star, "*"},
   };
   for (auto [kind, str] : operators) {
     if (remainder.consume_front(str))
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index eac41fab90763..8c4f7fdb25bea 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -179,10 +179,13 @@ ASTNodeUP DILParser::ParsePostfixExpression() {
 // Parse a primary_expression.
 //
 //  primary_expression:
+//    numeric_literal
 //    id_expression
 //    "(" expression ")"
 //
 ASTNodeUP DILParser::ParsePrimaryExpression() {
+  if (CurToken().IsOneOf({Token::integer_constant, Token::float_constant}))
+    return ParseNumericLiteral();
   if (CurToken().IsOneOf(
           {Token::coloncolon, Token::identifier, Token::l_paren})) {
     // Save the source location for the diagnostics message.
@@ -346,6 +349,7 @@ void DILParser::BailOut(const std::string &error, uint32_t loc,
   m_dil_lexer.ResetTokenIdx(m_dil_lexer.NumLexedTokens() - 1);
 }
 
+// FIXME: Remove this once subscript operator uses ScalarLiteralNode.
 // Parse a integer_literal.
 //
 //  integer_literal:
@@ -370,6 +374,69 @@ std::optional<int64_t> DILParser::ParseIntegerConstant() {
   return std::nullopt;
 }
 
+// Parse a numeric_literal.
+//
+//  numeric_literal:
+//    ? Token::integer_constant ?
+//    ? Token::floating_constant ?
+//
+ASTNodeUP DILParser::ParseNumericLiteral() {
+  ASTNodeUP numeric_constant;
+  if (CurToken().Is(Token::integer_constant))
+    numeric_constant = ParseIntegerLiteral();
+  else
+    numeric_constant = ParseFloatingPointLiteral();
+  if (!numeric_constant) {
+    BailOut(llvm::formatv("Failed to parse token as numeric-constant: {0}",
+                          CurToken()),
+            CurToken().GetLocation(), CurToken().GetSpelling().length());
+    return std::make_unique<ErrorNode>();
+  }
+  m_dil_lexer.Advance();
+  return numeric_constant;
+}
+
+ASTNodeUP DILParser::ParseIntegerLiteral() {
+  Token token = CurToken();
+  auto spelling = token.GetSpelling();
+  llvm::StringRef spelling_ref = spelling;
+
+  auto radix = llvm::getAutoSenseRadix(spelling_ref);
+  IntegerTypeSuffix type = IntegerTypeSuffix::None;
+  bool is_unsigned = false;
+  if (spelling_ref.consume_back_insensitive("u"))
+    is_unsigned = true;
+  if (spelling_ref.consume_back_insensitive("ll"))
+    type = IntegerTypeSuffix::LongLong;
+  else if (spelling_ref.consume_back_insensitive("l"))
+    type = IntegerTypeSuffix::Long;
+  // Suffix 'u' can be only specified only once, before or after 'l'
+  if (!is_unsigned && spelling_ref.consume_back_insensitive("u"))
+    is_unsigned = true;
+
+  llvm::APInt raw_value;
+  if (!spelling_ref.getAsInteger(radix, raw_value))
+    return std::make_unique<IntegerLiteralNode>(token.GetLocation(), raw_value,
+                                                radix, is_unsigned, type);
+  return nullptr;
+}
+
+ASTNodeUP DILParser::ParseFloatingPointLiteral() {
+  Token token = CurToken();
+  auto spelling = token.GetSpelling();
+  llvm::StringRef spelling_ref = spelling;
+
+  llvm::APFloat raw_float(llvm::APFloat::IEEEdouble());
+  if (spelling_ref.consume_back_insensitive("f"))
+    raw_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+
+  auto StatusOrErr = raw_float.convertFromString(
+      spelling_ref, llvm::APFloat::rmNearestTiesToEven);
+  if (!errorToBool(StatusOrErr.takeError()))
+    return std::make_unique<FloatLiteralNode>(token.GetLocation(), raw_float);
+  return nullptr;
+}
+
 void DILParser::Expect(Token::Kind kind) {
   if (CurToken().IsNot(kind)) {
     BailOut(llvm::formatv("expected {0}, got: {1}", kind, CurToken()),
diff --git a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py
index e3cfb878dd415..f47e86266f474 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/ArraySubscript/TestFrameVarDILArraySubscript.py
@@ -66,14 +66,15 @@ def test_subscript(self):
         self.expect(
             "frame var 'int_arr[1.0]'",
             error=True,
-            substrs=["expected 'r_square', got: <'.'"],
+            substrs=["failed to parse integer constant: <'1.0' (float_constant)>"],
         )
 
         # Test accessing bits in scalar types.
         self.expect_var_path("idx_1[0]", value="1")
         self.expect_var_path("idx_1[1]", value="0")
+        self.expect_var_path("1[0]", value="1")
 
-        # Bit adcess not valid for a reference.
+        # Bit access not valid for a reference.
         self.expect(
             "frame var 'idx_1_ref[0]'",
             error=True,
@@ -86,11 +87,6 @@ def test_subscript(self):
             error=True,
             substrs=["failed to parse integer constant"],
         )
-        self.expect(
-            "frame var '1[2]'",
-            error=True,
-            substrs=["Unexpected token"],
-        )
 
         # Base should not be a pointer to void
         self.expect(
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
index 38c72131d797c..28eba4f1a...
[truncated]

@kuilpd kuilpd merged commit bae1772 into llvm:main Aug 27, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants