1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
//===-- ObjCRuntimeSyntheticProvider.cpp ------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "ObjCRuntimeSyntheticProvider.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/lldb-public.h"
using namespace lldb;
using namespace lldb_private;
std::string ObjCRuntimeSyntheticProvider::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s Runtime-generated synthetic provider for %s {\n",
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
m_descriptor_sp->GetClassName().AsCString("<unknown>"));
return sstr.GetString().str();
}
size_t ObjCRuntimeSyntheticProvider::FrontEnd::GetNumBases() {
return m_provider->m_descriptor_sp->GetSuperclass().get() ? 1 : 0;
}
llvm::Expected<uint32_t>
ObjCRuntimeSyntheticProvider::FrontEnd::CalculateNumChildren() {
uint32_t ivars = m_provider->GetNumIVars();
uint32_t bases = GetNumBases();
return bases + ivars;
}
static lldb::ValueObjectSP GetSuitableRootObject(ValueObjectSP valobj_sp) {
if (valobj_sp) {
if (!valobj_sp->GetParent())
return valobj_sp;
if (valobj_sp->IsBaseClass()) {
if (valobj_sp->GetParent()->IsBaseClass())
return GetSuitableRootObject(valobj_sp->GetParent()->GetSP());
return valobj_sp;
}
}
return valobj_sp;
}
ObjCRuntimeSyntheticProvider::FrontEnd::FrontEnd(
ObjCRuntimeSyntheticProvider *prv, ValueObject &backend)
: SyntheticChildrenFrontEnd(backend), m_provider(prv),
m_root_sp(::GetSuitableRootObject(backend.GetSP())) {}
lldb::ValueObjectSP
ObjCRuntimeSyntheticProvider::FrontEnd::GetChildAtIndex(uint32_t idx) {
lldb::ValueObjectSP child_sp(nullptr);
if (idx < CalculateNumChildrenIgnoringErrors()) {
if (GetNumBases() == 1) {
if (idx == 0) {
do {
ProcessSP process_sp(m_backend.GetProcessSP());
if (!process_sp)
break;
ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
if (!runtime)
break;
DeclVendor *vendor = runtime->GetDeclVendor();
if (!vendor)
break;
std::vector<CompilerDecl> decls;
auto descriptor_sp(m_provider->m_descriptor_sp);
if (!descriptor_sp)
break;
descriptor_sp = descriptor_sp->GetSuperclass();
if (!descriptor_sp)
break;
const bool append = false;
const uint32_t max = 1;
if (0 ==
vendor->FindDecls(descriptor_sp->GetClassName(), append, max,
decls))
break;
const uint32_t offset = 0;
const bool can_create = true;
if (decls.empty())
break;
auto *ctx = llvm::dyn_cast<TypeSystemClang>(decls[0].GetTypeSystem());
if (!ctx)
break;
CompilerType type = ctx->GetTypeForDecl(decls[0].GetOpaqueDecl());
if (!type.IsValid())
break;
child_sp = m_backend.GetSyntheticBase(offset, type, can_create);
} while (false);
return child_sp;
} else
--idx;
}
if (m_root_sp) {
const auto &ivar_info(m_provider->GetIVarAtIndex(idx));
const bool can_create = true;
child_sp = m_root_sp->GetSyntheticChildAtOffset(
ivar_info.m_offset, ivar_info.m_type, can_create);
if (child_sp)
child_sp->SetName(ivar_info.m_name);
}
}
return child_sp;
}
size_t ObjCRuntimeSyntheticProvider::FrontEnd::GetIndexOfChildWithName(
ConstString name) {
for (size_t idx = 0; idx < CalculateNumChildrenIgnoringErrors(); idx++) {
const auto &ivar_info(m_provider->GetIVarAtIndex(idx));
if (name == ivar_info.m_name)
return idx + GetNumBases();
}
return UINT32_MAX;
}
|