Skip to content

Commit 47655fc

Browse files
Merge pull request #6292 from adrian-prantl/104842059
Support variadic generics in LLDB.
2 parents 0b90beb + 8b29717 commit 47655fc

File tree

12 files changed

+811
-15
lines changed

12 files changed

+811
-15
lines changed

lldb/include/lldb/lldb-enumerations.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,8 @@ FLAGS_ENUM(TypeFlags){
11031103
eTypeIsTuple = (1u << 26),
11041104
eTypeIsMetatype = (1u << 27),
11051105
eTypeHasUnboundGeneric = (1u << 28),
1106-
eTypeHasDynamicSelf = (1u << 29)};
1106+
eTypeHasDynamicSelf = (1u << 29),
1107+
eTypeIsPack = (1u << 30)};
11071108

11081109
FLAGS_ENUM(CommandFlags){
11091110
/// eCommandRequiresTarget

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,51 @@ class SwiftLanguageRuntime : public LanguageRuntime {
267267
const SymbolContext &sc,
268268
llvm::DenseMap<ArchetypePath, llvm::StringRef> &dict);
269269

270+
/// Invoke callback for each DependentGenericParamType.
271+
static void
272+
ForEachGenericParameter(swift::Demangle::NodePointer node,
273+
std::function<void(unsigned, unsigned)> callback);
274+
275+
/// One element for each value pack / pack expansion in the signature.
276+
struct GenericSignature {
277+
/// Represents a single generic parameter.
278+
struct GenericParam {
279+
unsigned depth;
280+
unsigned index;
281+
/// A vector of |generic_params| bits, indicating which other
282+
/// generic_params share the same shape.
283+
llvm::BitVector same_shape;
284+
GenericParam(unsigned d, unsigned i, unsigned nparams)
285+
: depth(d), index(i), same_shape(nparams) {}
286+
};
287+
288+
struct PackExpansion {
289+
llvm::BitVector generic_params;
290+
ConstString mangled_type;
291+
unsigned shape;
292+
PackExpansion(unsigned nparams, unsigned shape)
293+
: generic_params(nparams), shape(shape) {}
294+
};
295+
296+
llvm::SmallVector<GenericParam, 4> generic_params;
297+
/// Indices of the shape of the pack expansions.
298+
llvm::SmallVector<PackExpansion> pack_expansions;
299+
300+
llvm::SmallVector<unsigned, 4> count_for_value_pack;
301+
llvm::SmallVector<unsigned, 4> count_for_type_pack;
302+
303+
unsigned GetNumValuePacks() { return count_for_value_pack.size(); }
304+
unsigned GetNumTypePacks() { return count_for_type_pack.size(); }
305+
unsigned GetCountForValuePack(unsigned i) {
306+
return count_for_value_pack[i];
307+
}
308+
unsigned GetCountForTypePack(unsigned i) { return count_for_type_pack[i]; }
309+
};
310+
/// Extract the generic signature out of a mangled Swift function name.
311+
static llvm::Optional<GenericSignature>
312+
GetGenericSignature(llvm::StringRef function_name,
313+
TypeSystemSwiftTypeRef &ts);
314+
270315
/// Using the generic type parameters of \p stack_frame return a
271316
/// version of \p base_type that replaces all generic type
272317
/// parameters with bound generic types. If a generic type parameter

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 272 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,11 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
995995
if (!ts)
996996
return {};
997997

998+
// Deal with the LLDB-only SILPackType variant.
999+
if (auto pack_type = ts->IsSILPackType(type))
1000+
if (pack_type->expanded)
1001+
return pack_type->count;
1002+
9981003
// Try the static type metadata.
9991004
const swift::reflection::TypeRef *tr = nullptr;
10001005
auto *ti = GetSwiftRuntimeTypeInfo(type, exe_scope, &tr);
@@ -1319,6 +1324,26 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13191324
if (!ts)
13201325
return {};
13211326

1327+
ExecutionContext exe_ctx;
1328+
if (valobj)
1329+
exe_ctx = valobj->GetExecutionContextRef();
1330+
1331+
// Deal with the LLDB-only SILPackType variant.
1332+
if (auto pack_element_type = ts->GetSILPackElementAtIndex(type, idx)) {
1333+
llvm::raw_string_ostream os(child_name);
1334+
os << '.' << idx;
1335+
child_byte_size =
1336+
GetBitSize(pack_element_type, exe_ctx.GetBestExecutionContextScope())
1337+
.getValueOr(0);
1338+
int stack_dir = -1;
1339+
child_byte_offset = ts->GetPointerByteSize() * idx * stack_dir;
1340+
child_bitfield_bit_size = 0;
1341+
child_bitfield_bit_offset = 0;
1342+
child_is_base_class = false;
1343+
child_is_deref_of_parent = true;
1344+
return pack_element_type;
1345+
}
1346+
13221347
// The actual conversion from the FieldInfo record.
13231348
auto get_from_field_info =
13241349
[&](const swift::reflection::FieldInfo &field,
@@ -1345,10 +1370,6 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13451370
};
13461371

13471372
// Try the static type metadata.
1348-
ExecutionContext exe_ctx;
1349-
if (valobj)
1350-
exe_ctx = valobj->GetExecutionContextRef();
1351-
13521373
auto *ti =
13531374
GetSwiftRuntimeTypeInfo(type, exe_ctx.GetBestExecutionContextScope());
13541375
if (!ti)
@@ -1599,6 +1620,247 @@ bool SwiftLanguageRuntime::IsSelf(Variable &variable) {
15991620
node_ptr->getKind() == swift::Demangle::Node::Kind::Allocator;
16001621
}
16011622

1623+
/// Strip off SILPack(In)Direct from a mangled type name.
1624+
static ConstString unwrapSILPackType(ConstString mangledName,
1625+
swift::Demangle::Demangler &demangler,
1626+
TypeSystemSwiftTypeRef &ts,
1627+
bool &indirect) {
1628+
swift::Demangle::Context dem;
1629+
auto node = dem.demangleSymbolAsNode(mangledName.GetStringRef());
1630+
if (!node || node->getKind() != swift::Demangle::Node::Kind::Global)
1631+
return mangledName;
1632+
if (node->getNumChildren() != 1)
1633+
return mangledName;
1634+
node = node->getChild(0);
1635+
if (!node || node->getKind() != swift::Demangle::Node::Kind::TypeMangling)
1636+
return mangledName;
1637+
if (node->getNumChildren() != 1)
1638+
return mangledName;
1639+
node = node->getChild(0);
1640+
if (!node || node->getKind() != swift::Demangle::Node::Kind::Type)
1641+
return mangledName;
1642+
if (node->getNumChildren() != 1)
1643+
return mangledName;
1644+
node = node->getChild(0);
1645+
if (!node)
1646+
return mangledName;
1647+
1648+
indirect = false;
1649+
if (node->getKind() == swift::Demangle::Node::Kind::SILPackIndirect)
1650+
indirect = true;
1651+
if (node->getKind() != swift::Demangle::Node::Kind::SILPackIndirect &&
1652+
node->getKind() != swift::Demangle::Node::Kind::SILPackDirect)
1653+
return mangledName;
1654+
1655+
if (node->getNumChildren() != 1)
1656+
return mangledName;
1657+
node = node->getChild(0);
1658+
1659+
return ts.RemangleAsType(demangler, node).GetMangledTypeName();
1660+
}
1661+
1662+
bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Pack(
1663+
ValueObject &in_value, CompilerType pack_type,
1664+
lldb::DynamicValueType use_dynamic, TypeAndOrName &pack_type_or_name,
1665+
Address &address) {
1666+
Log *log(GetLog(LLDBLog::Types));
1667+
auto *reflection_ctx = GetReflectionContext();
1668+
if (!reflection_ctx)
1669+
return false;
1670+
1671+
// Return a tuple type, with one element per pack element and its
1672+
// type has all DependentGenericParamType that appear in type packs
1673+
// substituted.
1674+
1675+
StackFrameSP frame = in_value.GetExecutionContextRef().GetFrameSP();
1676+
if (!frame)
1677+
return false;
1678+
ConstString func_name = frame->GetSymbolContext(eSymbolContextFunction)
1679+
.GetFunctionName(Mangled::ePreferMangled);
1680+
1681+
// Extract the generic signature from the function symbol.
1682+
auto ts =
1683+
pack_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwiftTypeRef>();
1684+
if (!ts)
1685+
return false;
1686+
auto signature =
1687+
SwiftLanguageRuntime::GetGenericSignature(func_name.GetStringRef(), *ts);
1688+
if (!signature) {
1689+
LLDB_LOG(log, "cannot decode pack_expansion type: failed to decode generic "
1690+
"signature from function name");
1691+
return false;
1692+
}
1693+
// This type has already been resolved?
1694+
if (auto info = ts->IsSILPackType(pack_type))
1695+
if (info->expanded)
1696+
return false;
1697+
1698+
bool indirect = false;
1699+
swift::Demangle::Demangler dem;
1700+
ConstString mangled_pack_type = pack_type.GetMangledTypeName();
1701+
mangled_pack_type = unwrapSILPackType(mangled_pack_type, dem, *ts, indirect);
1702+
1703+
// Find pack_type in the pack_expansions.
1704+
unsigned i = 0;
1705+
Target &target = m_process.GetTarget();
1706+
size_t ptr_size = m_process.GetAddressByteSize();
1707+
SwiftLanguageRuntime::GenericSignature::PackExpansion *pack_expansion =
1708+
nullptr;
1709+
for (auto &pe : signature->pack_expansions) {
1710+
if (pe.mangled_type == mangled_pack_type) {
1711+
pack_expansion = &pe;
1712+
break;
1713+
}
1714+
++i;
1715+
}
1716+
if (!pack_expansion) {
1717+
LLDB_LOGF(log, "cannot decode pack_expansion type: failed to find a "
1718+
"matching type in the function signature");
1719+
return false;
1720+
}
1721+
1722+
// Extract the count.
1723+
llvm::SmallString<16> buf;
1724+
llvm::raw_svector_ostream os(buf);
1725+
os << "$pack_count_" << signature->GetCountForValuePack(i);
1726+
StringRef count_var = os.str();
1727+
llvm::Optional<lldb::addr_t> count =
1728+
GetTypeMetadataForTypeNameAndFrame(count_var, *frame);
1729+
if (!count) {
1730+
LLDB_LOGF(log,
1731+
"cannot decode pack_expansion type: failed to find count "
1732+
"argument \"%s\" in frame",
1733+
count_var.str().c_str());
1734+
return false;
1735+
}
1736+
1737+
// Extract the metadata for the type packs in this value pack.
1738+
llvm::SmallDenseMap<std::pair<unsigned, unsigned>, lldb::addr_t> type_packs;
1739+
swift::Demangle::NodePointer dem_pack_type =
1740+
dem.demangleSymbol(mangled_pack_type.GetStringRef());
1741+
auto shape = signature->generic_params[pack_expansion->shape];
1742+
// Filter out all type packs in this value pack.
1743+
bool error = false;
1744+
ForEachGenericParameter(dem_pack_type, [&](unsigned depth, unsigned index) {
1745+
if (type_packs.count({depth, index}))
1746+
return;
1747+
for (auto p : shape.same_shape.set_bits()) {
1748+
// If a generic parameter that shows up in the
1749+
// pack_expansion has the same shape as the pack expansion
1750+
// it's a type pack.
1751+
auto &generic_param = signature->generic_params[p];
1752+
if (generic_param.depth == depth && generic_param.index == index) {
1753+
llvm::SmallString<16> buf;
1754+
llvm::raw_svector_ostream os(buf);
1755+
os << u8"$\u03C4_" << shape.depth << '_' << shape.index;
1756+
StringRef mds_var = os.str();
1757+
llvm::Optional<lldb::addr_t> mds_ptr =
1758+
GetTypeMetadataForTypeNameAndFrame(mds_var, *frame);
1759+
if (!mds_ptr) {
1760+
LLDB_LOGF(log,
1761+
"cannot decode pack_expansion type: failed to find "
1762+
"metadata "
1763+
"for \"%s\" in frame",
1764+
mds_var.str().c_str());
1765+
error = true;
1766+
return;
1767+
}
1768+
type_packs.insert({{depth, index}, *mds_ptr});
1769+
}
1770+
}
1771+
});
1772+
if (error)
1773+
return false;
1774+
1775+
// Walk the type packs.
1776+
std::vector<TypeSystemSwift::TupleElement> elements;
1777+
for (unsigned j = 0; j < *count; ++j) {
1778+
1779+
// Build the list of type substitutions.
1780+
swift::reflection::GenericArgumentMap substitutions;
1781+
for (auto it : type_packs) {
1782+
unsigned depth = it.first.first;
1783+
unsigned index = it.first.second;
1784+
lldb::addr_t md_ptr = it.second + j * ptr_size;
1785+
1786+
// Read the type metadata pointer.
1787+
Status status;
1788+
lldb::addr_t md = LLDB_INVALID_ADDRESS;
1789+
target.ReadMemory(md_ptr, &md, ptr_size, status, true);
1790+
if (!status.Success()) {
1791+
LLDB_LOGF(log,
1792+
"cannot decode pack_expansion type: failed to read type "
1793+
"pack for type %d/%d of type pack with shape %d %d",
1794+
j, (unsigned)*count, depth, index);
1795+
return false;
1796+
}
1797+
1798+
auto *type_ref = reflection_ctx->readTypeFromMetadata(md);
1799+
if (!type_ref) {
1800+
LLDB_LOGF(log,
1801+
"cannot decode pack_expansion type: failed to decode type "
1802+
"metadata for type %d/%d of type pack with shape %d %d",
1803+
j, (unsigned)*count, depth, index);
1804+
return false;
1805+
}
1806+
substitutions.insert({{depth, index}, type_ref});
1807+
}
1808+
if (substitutions.empty())
1809+
return false;
1810+
1811+
// Replace all pack expansions with a singular type. Otherwise the
1812+
// reflection context won't accept them.
1813+
NodePointer pack_element = TypeSystemSwiftTypeRef::Transform(
1814+
dem, dem_pack_type, [](NodePointer node) {
1815+
if (node->getKind() != Node::Kind::PackExpansion)
1816+
return node;
1817+
assert(node->getNumChildren() == 2);
1818+
if (node->getNumChildren() != 2)
1819+
return node;
1820+
return node->getChild(0);
1821+
});
1822+
1823+
// Build a TypeRef from the demangle tree.
1824+
auto typeref_or_err =
1825+
decodeMangledType(reflection_ctx->getBuilder(), pack_element);
1826+
if (typeref_or_err.isError()) {
1827+
LLDB_LOG(log, "Couldn't get TypeRef for %s",
1828+
pack_type.GetMangledTypeName().GetCString());
1829+
return false;
1830+
}
1831+
auto typeref = typeref_or_err.getType();
1832+
1833+
// Apply the substitutions.
1834+
auto bound_typeref =
1835+
typeref->subst(reflection_ctx->getBuilder(), substitutions);
1836+
swift::Demangle::NodePointer node = bound_typeref->getDemangling(dem);
1837+
CompilerType type = ts->RemangleAsType(dem, node);
1838+
1839+
// Add the substituted type to the tuple.
1840+
elements.push_back({{}, type});
1841+
}
1842+
// Create a tuple type with all the concrete types in the pack.
1843+
CompilerType tuple = ts->CreateTupleType(elements);
1844+
// Wrap the type inside a SILPackType to mark it for GetChildAtIndex.
1845+
CompilerType sil_pack_type = ts->CreateSILPackType(tuple, indirect);
1846+
pack_type_or_name.SetCompilerType(sil_pack_type);
1847+
LLDB_LOGF(log, "decoded pack_expansion type: %s",
1848+
tuple.GetMangledTypeName().GetCString());
1849+
1850+
lldb::addr_t addr = in_value.GetAddressOf();
1851+
if (indirect) {
1852+
Status status;
1853+
addr = m_process.ReadPointerFromMemory(addr, status);
1854+
if (status.Fail()) {
1855+
LLDB_LOGF(log, "failed to dereference indirect pack: %s",
1856+
tuple.GetMangledTypeName().GetCString());
1857+
return false;
1858+
}
1859+
}
1860+
address.SetRawAddress(addr);
1861+
return true;
1862+
}
1863+
16021864
/// Determine whether the scratch SwiftASTContext has been locked.
16031865
static bool IsScratchContextLocked(Target &target) {
16041866
if (target.GetSwiftScratchContextLock().try_lock()) {
@@ -1986,9 +2248,9 @@ SwiftLanguageRuntimeImpl::GetPromiseForTypeNameAndFrame(const char *type_name,
19862248
return GetMetadataPromise(metadata_location, *metadata_ptr_var_sp);
19872249
}
19882250

1989-
static void
1990-
ForEachGenericParameter(swift::Demangle::NodePointer node,
1991-
std::function<void(unsigned, unsigned)> callback) {
2251+
void SwiftLanguageRuntime::ForEachGenericParameter(
2252+
swift::Demangle::NodePointer node,
2253+
std::function<void(unsigned, unsigned)> callback) {
19922254
if (!node)
19932255
return;
19942256

@@ -2124,7 +2386,6 @@ SwiftLanguageRuntimeImpl::BindGenericTypeParameters(StackFrame &stack_frame,
21242386
GetTypeMetadataForTypeNameAndFrame(mdvar_name.GetString(), stack_frame);
21252387
if (!metadata_location)
21262388
return;
2127-
21282389
const swift::reflection::TypeRef *type_ref =
21292390
reflection_ctx->readTypeFromMetadata(*metadata_location);
21302391
if (!type_ref)
@@ -2738,6 +2999,9 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress(
27382999
if (is_indirect_enum_case)
27393000
success = GetDynamicTypeAndAddress_IndirectEnumCase(
27403001
in_value, use_dynamic, class_type_or_name, address);
3002+
else if (type_info.AnySet(eTypeIsPack))
3003+
success = GetDynamicTypeAndAddress_Pack(in_value, val_type, use_dynamic,
3004+
class_type_or_name, address);
27413005
else if (type_info.AnySet(eTypeIsClass) ||
27423006
type_info.AllSet(eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue))
27433007
success = GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,

0 commit comments

Comments
 (0)