Revert "[LLDB] Add ScalarLiteralNode and literal parsing in DIL" (#155605)

Reverts llvm/llvm-project#152308
This commit is contained in:
Ilia Kuklin
2025-08-27 17:14:44 +05:00
committed by GitHub
parent 00926a6db6
commit 241d1601b4
15 changed files with 31 additions and 433 deletions

View File

@@ -37,13 +37,4 @@ 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

View File

@@ -7,9 +7,7 @@
//===----------------------------------------------------------------------===//
#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"
@@ -499,107 +497,4 @@ 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

View File

@@ -28,23 +28,18 @@ 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:
@@ -75,32 +70,13 @@ static std::optional<llvm::StringRef> IsWord(llvm::StringRef expr,
return candidate;
}
static bool IsNumberBodyChar(char ch) {
return IsDigit(ch) || IsLetter(ch) || ch == '.';
}
static bool IsNumberBodyChar(char ch) { return IsDigit(ch) || IsLetter(ch); }
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);
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());
return number;
}
return std::nullopt;
@@ -130,21 +106,18 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
return Token(Token::eof, "", (uint32_t)expr.size());
uint32_t position = cur_pos - expr.begin();
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_number = IsNumber(expr, remainder);
if (maybe_number)
return Token(Token::numeric_constant, 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::plus, "+"}, {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::r_paren, ")"}, {Token::r_square, "]"},
{Token::star, "*"},
};
for (auto [kind, str] : operators) {
if (remainder.consume_front(str))

View File

@@ -179,13 +179,10 @@ 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.
@@ -349,7 +346,6 @@ 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:
@@ -374,69 +370,6 @@ 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()),