Skip to content

Commit

Permalink
[Core] Remove use of ClangASTContext in DumpDataExtractor
Browse files Browse the repository at this point in the history
Summary:
DumpDataExtractor uses ClangASTContext in order to get the proper llvm
fltSemantics for the type it needs so that it can dump floats in a more
precise way. However, there's no reason that this behavior needs to be
specific ClangASTContext. Instead, I think it makes sense to ask
TypeSystems for the float semantics for a type of a given size.

Differential Revision: https://reviews.llvm.org/D67239

llvm-svn: 371258
  • Loading branch information
bulbazord committed Sep 6, 2019
1 parent 6cee434 commit b482db6
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 52 deletions.
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/ClangASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ class ClangASTContext : public TypeSystem {

// Exploring the type

const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override;

llvm::Optional<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) {
if (llvm::Optional<uint64_t> bit_size = GetBitSize(type, exe_scope))
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <mutex>
#include <string>

#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/Casting.h"
Expand Down Expand Up @@ -276,6 +277,8 @@ class TypeSystem : public PluginInterface {

// Exploring the type

virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0;

virtual llvm::Optional<uint64_t>
GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) = 0;
Expand Down
80 changes: 28 additions & 52 deletions lldb/source/Core/DumpDataExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/SectionLoadList.h"
Expand Down Expand Up @@ -69,6 +68,9 @@ static float half2float(uint16_t half) {
static llvm::Optional<llvm::APInt> GetAPInt(const DataExtractor &data,
lldb::offset_t *offset_ptr,
lldb::offset_t byte_size) {
if (byte_size == 0)
return llvm::None;

llvm::SmallVector<uint64_t, 2> uint64_array;
lldb::offset_t bytes_left = byte_size;
uint64_t u64;
Expand Down Expand Up @@ -556,57 +558,31 @@ lldb::offset_t lldb_private::DumpDataExtractor(
if (exe_scope)
target_sp = exe_scope->CalculateTarget();
if (target_sp) {
ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
if (clang_ast) {
clang::ASTContext *ast = clang_ast->getASTContext();
if (ast) {
llvm::SmallVector<char, 256> sv;
// Show full precision when printing float values
const unsigned format_precision = 0;
const unsigned format_max_padding =
target_sp->GetMaxZeroPaddingInFloatFormat();
size_t item_bit_size = item_byte_size * 8;

if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
llvm::Optional<llvm::APInt> apint =
GetAPInt(DE, &offset, item_byte_size);
if (apint.hasValue()) {
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
apint.getValue());
apfloat.toString(sv, format_precision, format_max_padding);
}
} else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
llvm::Optional<llvm::APInt> apint =
GetAPInt(DE, &offset, item_byte_size);
if (apint.hasValue()) {
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
apint.getValue());
apfloat.toString(sv, format_precision, format_max_padding);
}
} else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
const auto &semantics =
ast->getFloatTypeSemantics(ast->LongDoubleTy);

offset_t byte_size = item_byte_size;
if (&semantics == &llvm::APFloatBase::x87DoubleExtended())
byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;

llvm::Optional<llvm::APInt> apint =
GetAPInt(DE, &offset, byte_size);
if (apint.hasValue()) {
llvm::APFloat apfloat(semantics, apint.getValue());
apfloat.toString(sv, format_precision, format_max_padding);
}
} else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
llvm::Optional<llvm::APInt> apint =
GetAPInt(DE, &offset, item_byte_size);
if (apint.hasValue()) {
llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
apint.getValue());
apfloat.toString(sv, format_precision, format_max_padding);
}
}

auto type_system_or_err =
target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
if (!type_system_or_err) {
llvm::consumeError(type_system_or_err.takeError());
} else {
auto &type_system = *type_system_or_err;
llvm::SmallVector<char, 256> sv;
// Show full precision when printing float values
const unsigned format_precision = 0;
const unsigned format_max_padding =
target_sp->GetMaxZeroPaddingInFloatFormat();

const auto &semantics =
type_system.GetFloatTypeSemantics(item_byte_size);

// Recalculate the byte size in case of a difference. This is possible
// when item_byte_size is 16 (128-bit), because you could get back the
// x87DoubleExtended semantics which has a byte size of 10 (80-bit).
const size_t semantics_byte_size =
(llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
llvm::Optional<llvm::APInt> apint =
GetAPInt(DE, &offset, semantics_byte_size);
if (apint.hasValue()) {
llvm::APFloat apfloat(semantics, apint.getValue());
apfloat.toString(sv, format_precision, format_max_padding);
if (!sv.empty()) {
s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
used_upfloat = true;
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Symbol/ClangASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4991,6 +4991,22 @@ CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
}
// Exploring the type

const llvm::fltSemantics &
ClangASTContext::GetFloatTypeSemantics(size_t byte_size) {
if (auto *ast = getASTContext()) {
const size_t bit_size = byte_size * 8;
if (bit_size == ast->getTypeSize(ast->FloatTy))
return ast->getFloatTypeSemantics(ast->FloatTy);
else if (bit_size == ast->getTypeSize(ast->DoubleTy))
return ast->getFloatTypeSemantics(ast->DoubleTy);
else if (bit_size == ast->getTypeSize(ast->LongDoubleTy))
return ast->getFloatTypeSemantics(ast->LongDoubleTy);
else if (bit_size == ast->getTypeSize(ast->HalfTy))
return ast->getFloatTypeSemantics(ast->HalfTy);
}
return llvm::APFloatBase::Bogus();
}

Optional<uint64_t>
ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) {
Expand Down

0 comments on commit b482db6

Please sign in to comment.