@@ -1655,6 +1655,48 @@ class MetadataReader {
1655
1655
return nameChild;
1656
1656
}
1657
1657
1658
+ // / Resolve a relative target protocol descriptor pointer, which uses
1659
+ // / the lowest bit to indicate an indirect vs. direct relative reference and
1660
+ // / the second lowest bit to indicate whether it is an Objective-C protocol.
1661
+ StoredPointer resolveRelativeIndirectProtocol (
1662
+ ContextDescriptorRef descriptor,
1663
+ const RelativeTargetProtocolDescriptorPointer<Runtime> &protocol) {
1664
+ // Map the offset from within our local buffer to the remote address.
1665
+ auto distance = (intptr_t )&protocol - (intptr_t )descriptor.getLocalBuffer ();
1666
+ StoredPointer targetAddress (descriptor.getAddress () + distance);
1667
+
1668
+ // Read the relative offset.
1669
+ int32_t relative;
1670
+ if (!Reader->readInteger (RemoteAddress (targetAddress), &relative))
1671
+ return StoredPointer ();
1672
+
1673
+ // Collect and mask off the 'indirect' and 'isObjC' bits.
1674
+ bool indirect = relative & 1 ;
1675
+ relative &= ~1u ;
1676
+ bool isObjC = relative & 2 ;
1677
+ relative &= ~2u ;
1678
+
1679
+ using SignedPointer = typename std::make_signed<StoredPointer>::type;
1680
+ auto signext = (SignedPointer)(int32_t )relative;
1681
+
1682
+ StoredPointer resultAddress = targetAddress + signext;
1683
+
1684
+ // Low bit set in the offset indicates that the offset leads to the absolute
1685
+ // address in memory.
1686
+ if (indirect) {
1687
+ if (!Reader->readBytes (RemoteAddress (resultAddress),
1688
+ (uint8_t *)&resultAddress,
1689
+ sizeof (StoredPointer)))
1690
+ return StoredPointer ();
1691
+ }
1692
+
1693
+ // Add back the Objective-C bit.
1694
+ if (isObjC)
1695
+ resultAddress |= 0x1 ;
1696
+
1697
+ return resultAddress;
1698
+ }
1699
+
1658
1700
Demangle::NodePointer
1659
1701
buildContextDescriptorMangling (ContextDescriptorRef descriptor,
1660
1702
Demangler &dem) {
@@ -1748,14 +1790,141 @@ class MetadataReader {
1748
1790
MangledNameKind::Type,
1749
1791
dem);
1750
1792
1751
- // FIXME: If there are generic requirements, turn them into a demangle
1752
- // tree.
1753
1793
auto demangling = dem.createNode (Node::Kind::Extension);
1754
1794
demangling->addChild (parentDemangling, dem);
1755
1795
demangling->addChild (demangledExtendedContext, dem);
1756
- return demangling;
1757
1796
1758
- return nullptr ;
1797
+ // / Resolver to turn a protocol reference into a demangling.
1798
+ struct ProtocolResolver {
1799
+ using Result = Demangle::Node *;
1800
+
1801
+ Demangler &dem;
1802
+
1803
+ Result failure () const {
1804
+ return nullptr ;
1805
+ }
1806
+
1807
+ Result swiftProtocol (Demangle::Node *node) {
1808
+ return node;
1809
+ }
1810
+
1811
+ #if SWIFT_OBJC_INTEROP
1812
+ Result objcProtocol (StringRef name) {
1813
+ // FIXME: Unify this with the runtime's Demangle.cpp
1814
+ auto module = dem.createNode (Node::Kind::Module,
1815
+ MANGLING_MODULE_OBJC);
1816
+ auto node = dem.createNode (Node::Kind::Protocol);
1817
+ node->addChild (module , dem);
1818
+ node->addChild (dem.createNode (Node::Kind::Identifier, name),
1819
+ dem);
1820
+ return node;
1821
+ }
1822
+ #endif
1823
+ } protocolResolver{dem};
1824
+
1825
+ // If there are generic requirements, form the generic signature.
1826
+ auto requirements = extensionBuffer->getGenericRequirements ();
1827
+ if (!requirements.empty ()) {
1828
+ auto signatureNode =
1829
+ dem.createNode (Node::Kind::DependentGenericSignature);
1830
+ bool failed = false ;
1831
+ for (const auto &req : requirements) {
1832
+ if (failed)
1833
+ break ;
1834
+
1835
+ // Demangle the subject.
1836
+ auto subjectAddress = resolveRelativeField (descriptor, req.Param );
1837
+ NodePointer subject = readMangledName (RemoteAddress (subjectAddress),
1838
+ MangledNameKind::Type,
1839
+ dem);
1840
+ if (!subject) {
1841
+ failed = true ;
1842
+ break ;
1843
+ }
1844
+
1845
+ switch (req.Flags .getKind ()) {
1846
+ case GenericRequirementKind::Protocol: {
1847
+ auto protocolAddress =
1848
+ resolveRelativeIndirectProtocol (descriptor, req.Protocol );
1849
+ auto protocol = readProtocol (protocolAddress, dem,
1850
+ protocolResolver);
1851
+ if (!protocol) {
1852
+ failed = true ;
1853
+ break ;
1854
+ }
1855
+
1856
+ auto reqNode =
1857
+ dem.createNode (
1858
+ Node::Kind::DependentGenericConformanceRequirement);
1859
+ reqNode->addChild (subject, dem);
1860
+ reqNode->addChild (protocol, dem);
1861
+ signatureNode->addChild (reqNode, dem);
1862
+ break ;
1863
+ }
1864
+
1865
+ case GenericRequirementKind::SameType:
1866
+ case GenericRequirementKind::BaseClass: {
1867
+ // Demangle the right-hand type.
1868
+ auto typeAddress = resolveRelativeField (descriptor, req.Type );
1869
+ NodePointer type = readMangledName (RemoteAddress (typeAddress),
1870
+ MangledNameKind::Type,
1871
+ dem);
1872
+ if (!type) {
1873
+ failed = true ;
1874
+ break ;
1875
+ }
1876
+
1877
+ Node::Kind nodeKind;
1878
+ if (req.Flags .getKind () == GenericRequirementKind::SameType)
1879
+ nodeKind = Node::Kind::DependentGenericSameTypeRequirement;
1880
+ else
1881
+ nodeKind = Node::Kind::DependentGenericConformanceRequirement;
1882
+
1883
+ auto reqNode = dem.createNode (nodeKind);
1884
+ reqNode->addChild (subject, dem);
1885
+ reqNode->addChild (type, dem);
1886
+ signatureNode->addChild (reqNode, dem);
1887
+ break ;
1888
+ }
1889
+
1890
+ case GenericRequirementKind::SameConformance:
1891
+ // Do nothing
1892
+ break ;
1893
+
1894
+ case GenericRequirementKind::Layout: {
1895
+ // Map the offset from within our local buffer to the remote
1896
+ // address.
1897
+ auto distance =
1898
+ (intptr_t )&req.Layout - (intptr_t )descriptor.getLocalBuffer ();
1899
+ StoredPointer targetAddress (descriptor.getAddress () + distance);
1900
+
1901
+ GenericRequirementLayoutKind kind;
1902
+ if (!Reader->readBytes (RemoteAddress (targetAddress),
1903
+ (uint8_t *)&kind, sizeof (kind))) {
1904
+ failed = true ;
1905
+ break ;
1906
+ }
1907
+
1908
+ if (kind == GenericRequirementLayoutKind::Class) {
1909
+ auto reqNode =
1910
+ dem.createNode (Node::Kind::DependentGenericLayoutRequirement);
1911
+ reqNode->addChild (subject, dem);
1912
+ auto idNode = dem.createNode (Node::Kind::Identifier, " C" );
1913
+ reqNode->addChild (idNode, dem);
1914
+ signatureNode->addChild (reqNode, dem);
1915
+ } else {
1916
+ failed = true ;
1917
+ }
1918
+ break ;
1919
+ }
1920
+ }
1921
+ }
1922
+
1923
+ if (!failed) {
1924
+ demangling->addChild (signatureNode, dem);
1925
+ }
1926
+ }
1927
+ return demangling;
1759
1928
}
1760
1929
1761
1930
case ContextDescriptorKind::Anonymous: {
0 commit comments