|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 | 9 | #include "lldb/ValueObject/DILEval.h"
|
| 10 | +#include "lldb/Core/Module.h" |
10 | 11 | #include "lldb/Symbol/CompileUnit.h"
|
| 12 | +#include "lldb/Symbol/TypeSystem.h" |
11 | 13 | #include "lldb/Symbol/VariableList.h"
|
12 | 14 | #include "lldb/Target/RegisterContext.h"
|
13 | 15 | #include "lldb/ValueObject/DILAST.h"
|
@@ -497,4 +499,107 @@ Interpreter::Visit(const BitFieldExtractionNode *node) {
|
497 | 499 | return child_valobj_sp;
|
498 | 500 | }
|
499 | 501 |
|
| 502 | +static llvm::Expected<lldb::TypeSystemSP> |
| 503 | +GetTypeSystemFromCU(std::shared_ptr<StackFrame> ctx) { |
| 504 | + SymbolContext symbol_context = |
| 505 | + ctx->GetSymbolContext(lldb::eSymbolContextCompUnit); |
| 506 | + lldb::LanguageType language = symbol_context.comp_unit->GetLanguage(); |
| 507 | + |
| 508 | + symbol_context = ctx->GetSymbolContext(lldb::eSymbolContextModule); |
| 509 | + return symbol_context.module_sp->GetTypeSystemForLanguage(language); |
| 510 | +} |
| 511 | + |
| 512 | +static CompilerType GetBasicType(lldb::TypeSystemSP type_system, |
| 513 | + lldb::BasicType basic_type) { |
| 514 | + if (type_system) |
| 515 | + return type_system.get()->GetBasicTypeFromAST(basic_type); |
| 516 | + |
| 517 | + return CompilerType(); |
| 518 | +} |
| 519 | + |
| 520 | +llvm::Expected<CompilerType> |
| 521 | +Interpreter::PickIntegerType(lldb::TypeSystemSP type_system, |
| 522 | + std::shared_ptr<ExecutionContextScope> ctx, |
| 523 | + const IntegerLiteralNode *literal) { |
| 524 | + // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be |
| 525 | + // an unsigned integer. |
| 526 | + bool unsigned_is_allowed = literal->IsUnsigned() || literal->GetRadix() != 10; |
| 527 | + llvm::APInt apint = literal->GetValue(); |
| 528 | + |
| 529 | + llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates; |
| 530 | + if (literal->GetTypeSuffix() <= IntegerTypeSuffix::None) |
| 531 | + candidates.emplace_back(lldb::eBasicTypeInt, |
| 532 | + unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt |
| 533 | + : lldb::eBasicTypeInvalid); |
| 534 | + if (literal->GetTypeSuffix() <= IntegerTypeSuffix::Long) |
| 535 | + candidates.emplace_back(lldb::eBasicTypeLong, |
| 536 | + unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong |
| 537 | + : lldb::eBasicTypeInvalid); |
| 538 | + candidates.emplace_back(lldb::eBasicTypeLongLong, |
| 539 | + lldb::eBasicTypeUnsignedLongLong); |
| 540 | + for (auto [signed_, unsigned_] : candidates) { |
| 541 | + CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_); |
| 542 | + if (!signed_type) |
| 543 | + continue; |
| 544 | + llvm::Expected<uint64_t> size = signed_type.GetBitSize(ctx.get()); |
| 545 | + if (!size) |
| 546 | + return size.takeError(); |
| 547 | + if (!literal->IsUnsigned() && apint.isIntN(*size - 1)) |
| 548 | + return signed_type; |
| 549 | + if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size)) |
| 550 | + return type_system->GetBasicTypeFromAST(unsigned_); |
| 551 | + } |
| 552 | + |
| 553 | + return llvm::make_error<DILDiagnosticError>( |
| 554 | + m_expr, |
| 555 | + "integer literal is too large to be represented in any integer type", |
| 556 | + literal->GetLocation()); |
| 557 | +} |
| 558 | + |
| 559 | +llvm::Expected<lldb::ValueObjectSP> |
| 560 | +Interpreter::Visit(const IntegerLiteralNode *node) { |
| 561 | + llvm::Expected<lldb::TypeSystemSP> type_system = |
| 562 | + GetTypeSystemFromCU(m_exe_ctx_scope); |
| 563 | + if (!type_system) |
| 564 | + return type_system.takeError(); |
| 565 | + |
| 566 | + llvm::Expected<CompilerType> type = |
| 567 | + PickIntegerType(*type_system, m_exe_ctx_scope, node); |
| 568 | + if (!type) |
| 569 | + return type.takeError(); |
| 570 | + |
| 571 | + Scalar scalar = node->GetValue(); |
| 572 | + // APInt from StringRef::getAsInteger comes with just enough bitwidth to |
| 573 | + // hold the value. This adjusts APInt bitwidth to match the compiler type. |
| 574 | + llvm::Expected<uint64_t> type_bitsize = |
| 575 | + type->GetBitSize(m_exe_ctx_scope.get()); |
| 576 | + if (!type_bitsize) |
| 577 | + return type_bitsize.takeError(); |
| 578 | + scalar.TruncOrExtendTo(*type_bitsize, false); |
| 579 | + return ValueObject::CreateValueObjectFromScalar(m_target, scalar, *type, |
| 580 | + "result"); |
| 581 | +} |
| 582 | + |
| 583 | +llvm::Expected<lldb::ValueObjectSP> |
| 584 | +Interpreter::Visit(const FloatLiteralNode *node) { |
| 585 | + llvm::Expected<lldb::TypeSystemSP> type_system = |
| 586 | + GetTypeSystemFromCU(m_exe_ctx_scope); |
| 587 | + if (!type_system) |
| 588 | + return type_system.takeError(); |
| 589 | + |
| 590 | + bool isFloat = |
| 591 | + &node->GetValue().getSemantics() == &llvm::APFloat::IEEEsingle(); |
| 592 | + lldb::BasicType basic_type = |
| 593 | + isFloat ? lldb::eBasicTypeFloat : lldb::eBasicTypeDouble; |
| 594 | + CompilerType type = GetBasicType(*type_system, basic_type); |
| 595 | + |
| 596 | + if (!type) |
| 597 | + return llvm::make_error<DILDiagnosticError>( |
| 598 | + m_expr, "unable to create a const literal", node->GetLocation()); |
| 599 | + |
| 600 | + Scalar scalar = node->GetValue(); |
| 601 | + return ValueObject::CreateValueObjectFromScalar(m_target, scalar, type, |
| 602 | + "result"); |
| 603 | +} |
| 604 | + |
500 | 605 | } // namespace lldb_private::dil
|
0 commit comments