Skip to content

Fix Builtin.FixedArray type reconstruction and change integer type mangling #77273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ Types
type ::= 'Xe' // error or unresolved type

#if SWIFT_RUNTIME_VERSION >= 6.TBD
type ::= '$' 'n'? NATURAL_ZERO // integer type
type ::= '$' 'n'? INDEX // integer type
#endif

bound-generic-type ::= type 'y' (type* '_')* type* retroactive-conformance* 'G' // one type-list per nesting level of type
Expand Down
17 changes: 17 additions & 0 deletions include/swift/AST/ASTDemangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ class ASTBuilder {
/// For saving and restoring generic parameters.
llvm::SmallVector<decltype(ParameterPacks), 2> ParameterPackStack;

/// The depth and index of each value parameter in the current generic
/// signature. We need this becasue the mangling for a type parameter
/// doesn't record whether it is a value or not; we find the correct
/// depth and index in this array, and use its value-ness.
llvm::SmallVector<std::tuple<std::pair<unsigned, unsigned>, Type>, 1> ValueParameters;

/// For saving and restoring generic parameters.
llvm::SmallVector<decltype(ValueParameters), 1> ValueParametersStack;

/// This builder doesn't perform "on the fly" substitutions, so we preserve
/// all pack expansions. We still need an active expansion stack though,
/// for the dummy implementation of these methods:
Expand All @@ -93,6 +102,12 @@ class ASTBuilder {
for (auto *paramTy : genericSig.getGenericParams()) {
if (paramTy->isParameterPack())
ParameterPacks.emplace_back(paramTy->getDepth(), paramTy->getIndex());

if (paramTy->isValue()) {
auto pair = std::make_pair(paramTy->getDepth(), paramTy->getIndex());
auto tuple = std::make_tuple(pair, paramTy->getValueType());
ValueParameters.emplace_back(tuple);
}
}
}

Expand Down Expand Up @@ -235,6 +250,8 @@ class ASTBuilder {

Type createNegativeIntegerType(intptr_t value);

Type createBuiltinFixedArrayType(Type size, Type element);

BuiltGenericSignature
createGenericSignature(ArrayRef<BuiltType> params,
ArrayRef<BuiltRequirement> requirements);
Expand Down
20 changes: 19 additions & 1 deletion include/swift/Demangling/TypeDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,8 @@ void decodeRequirement(
BuilderType &Builder) {
for (auto &child : *node) {
if (child->getKind() == Demangle::Node::Kind::DependentGenericParamCount ||
child->getKind() == Demangle::Node::Kind::DependentGenericParamPackMarker)
child->getKind() == Demangle::Node::Kind::DependentGenericParamPackMarker ||
child->getKind() == Demangle::Node::Kind::DependentGenericParamValueMarker)
continue;

if (child->getNumChildren() != 2)
Expand Down Expand Up @@ -1529,6 +1530,23 @@ class TypeDecoder {
return Builder.createNegativeIntegerType((intptr_t)Node->getIndex());
}

case NodeKind::BuiltinFixedArray: {
if (Node->getNumChildren() < 2)
return MAKE_NODE_TYPE_ERROR(Node,
"fewer children (%zu) than required (2)",
Node->getNumChildren());

auto size = decodeMangledType(Node->getChild(0), depth + 1);
if (size.isError())
return size;

auto element = decodeMangledType(Node->getChild(1), depth + 1);
if (element.isError())
return element;

return Builder.createBuiltinFixedArrayType(size.getType(), element.getType());
}

// TODO: Handle OpaqueReturnType, when we're in the middle of reconstructing
// the defining decl
default:
Expand Down
6 changes: 6 additions & 0 deletions include/swift/RemoteInspection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,12 @@ class TypeRefBuilder {
return nullptr;
}

const TypeRef *createBuiltinFixedArrayType(const TypeRef *size,
const TypeRef *element) {
// FIXME: implement
return nullptr;
}

// Construct a bound generic type ref along with the parent type info
// The parent list contains every parent type with at least 1 generic
// type parameter.
Expand Down
30 changes: 30 additions & 0 deletions lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,11 @@ void ASTBuilder::pushGenericParams(ArrayRef<std::pair<unsigned, unsigned>> param
void ASTBuilder::popGenericParams() {
ParameterPacks = ParameterPackStack.back();
ParameterPackStack.pop_back();

if (!ValueParametersStack.empty()) {
ValueParameters = ValueParametersStack.back();
ValueParametersStack.pop_back();
}
}

Type ASTBuilder::createGenericTypeParameterType(unsigned depth,
Expand All @@ -857,6 +862,17 @@ Type ASTBuilder::createGenericTypeParameterType(unsigned depth,
}
}

if (!ValueParameters.empty()) {
for (auto tuple : ValueParameters) {
auto pair = std::get<std::pair<unsigned, unsigned>>(tuple);
auto type = std::get<Type>(tuple);

if (pair.first == depth && pair.second == index) {
return GenericTypeParamType::getValue(depth, index, type, Ctx);
}
}
}

return GenericTypeParamType::getType(depth, index, Ctx);
}

Expand Down Expand Up @@ -1049,6 +1065,11 @@ Type ASTBuilder::createNegativeIntegerType(intptr_t value) {
return IntegerType::get(std::to_string(value), /*isNegative*/ true, Ctx);
}

Type ASTBuilder::createBuiltinFixedArrayType(Type size, Type element) {
return BuiltinFixedArrayType::get(size->getCanonicalType(),
element->getCanonicalType());
}

GenericSignature
ASTBuilder::createGenericSignature(ArrayRef<BuiltType> builtParams,
ArrayRef<BuiltRequirement> requirements) {
Expand Down Expand Up @@ -1197,9 +1218,18 @@ CanGenericSignature ASTBuilder::demangleGenericSignature(
// we introduce the parameter packs from the nominal's generic signature.
ParameterPackStack.push_back(ParameterPacks);
ParameterPacks.clear();

ValueParametersStack.push_back(ValueParameters);
ValueParameters.clear();
for (auto *paramTy : baseGenericSig.getGenericParams()) {
if (paramTy->isParameterPack())
ParameterPacks.emplace_back(paramTy->getDepth(), paramTy->getIndex());

if (paramTy->isValue()) {
auto pair = std::make_pair(paramTy->getDepth(), paramTy->getIndex());
auto tuple = std::make_tuple(pair, paramTy->getValueType());
ValueParameters.emplace_back(tuple);
}
}
SWIFT_DEFER { popGenericParams(); };

Expand Down
16 changes: 13 additions & 3 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,11 +1685,14 @@ void ASTMangler::appendType(Type type, GenericSignature sig,

appendOperator("$");

auto value = integer->getValue().getSExtValue();

if (integer->isNegative()) {
appendOperator("n");
appendOperator("n", Index(-value));
} else {
appendOperator("", Index(value));
}

appendOperator(integer->getDigitsText());
return;
}

Expand Down Expand Up @@ -3629,10 +3632,17 @@ void ASTMangler::appendGenericSignatureParts(
ArrayRef<Requirement> requirements = parts.requirements;
ArrayRef<InverseRequirement> inverseRequirements = parts.inverses;

// Mangle which generic parameters are pack parameters.
// Mangle the kind for each generic parameter.
for (auto param : params) {
// Regular type parameters have no marker.

if (param->isParameterPack())
appendOpWithGenericParamIndex("Rv", param);

if (param->isValue()) {
appendType(param->getValueType(), sig);
appendOpWithGenericParamIndex("RV", param);
}
}

// Mangle the requirements.
Expand Down
4 changes: 2 additions & 2 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4450,11 +4450,11 @@ NodePointer Demangler::demangleIntegerType() {
switch (peekChar()) {
case 'n':
nextChar();
integer = createNode(Node::Kind::NegativeInteger, -demangleNatural());
integer = createNode(Node::Kind::NegativeInteger, -demangleIndex());
break;

default:
integer = createNode(Node::Kind::Integer, demangleNatural());
integer = createNode(Node::Kind::Integer, demangleIndex());
break;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,8 @@ class NodePrinter {
auto child = Node->getChild(firstRequirement);
if (child->getKind() == Node::Kind::Type)
child = child->getChild(0);
if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) {
if (child->getKind() != Node::Kind::DependentGenericParamPackMarker &&
child->getKind() != Node::Kind::DependentGenericParamValueMarker) {
break;
}
}
Expand Down
13 changes: 8 additions & 5 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3996,22 +3996,25 @@ mangleNonUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node,
}

ManglingError Remangler::mangleInteger(Node *node, unsigned int depth) {
Buffer << "$" << node->getIndex();
Buffer << "$";
mangleIndex(node->getIndex());

return ManglingError::Success;
}

ManglingError Remangler::mangleNegativeInteger(Node *node, unsigned int depth) {
Buffer << "$n" << -node->getIndex();
Buffer << "$n";
mangleIndex(-node->getIndex());

return ManglingError::Success;
}

ManglingError Remangler::mangleDependentGenericParamValueMarker(Node *node,
unsigned depth) {
DEMANGLER_ASSERT(node->getNumChildren() == 1, node);
DEMANGLER_ASSERT(node->getChild(0)->getKind() == Node::Kind::Type, node);
RETURN_IF_ERROR(mangleType(node->getChild(0)->getChild(1), depth + 1));
DEMANGLER_ASSERT(node->getNumChildren() == 2, node);
DEMANGLER_ASSERT(node->getChild(0)->getChild(0)->getKind() == Node::Kind::DependentGenericParamType, node);
DEMANGLER_ASSERT(node->getChild(1)->getKind() == Node::Kind::Type, node);
RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1));
Buffer << "RV";
mangleDependentGenericParamIndex(node->getChild(0)->getChild(0));
return ManglingError::Success;
Expand Down
7 changes: 7 additions & 0 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2454,6 +2454,13 @@ class DecodedMetadataBuilder {
TypeLookupErrorOr<BuiltType> createNegativeIntegerType(intptr_t value) {
return BuiltType(value);
}

TypeLookupErrorOr<BuiltType> createBuiltinFixedArrayType(BuiltType size,
BuiltType element) {
return BuiltType(swift_getFixedArrayTypeMetadata(MetadataState::Abstract,
size.getValue(),
element.getMetadata()));
}
};

}
Expand Down
21 changes: 21 additions & 0 deletions test/DebugInfo/value-generics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %target-swift-frontend %s -emit-ir -g -enable-builtin-module -enable-experimental-feature ValueGenerics -disable-experimental-parser-round-trip -disable-availability-checking -o - | %FileCheck %s

import Builtin

struct Vector<let N: Int, Element: ~Copyable>: ~Copyable {
let storage: Builtin.FixedArray<N, Element>
}

extension Vector: Copyable where Element: Copyable {}

// CHECK-DAG: !DICompositeType({{.*}}name: "Builtin.FixedArray", {{.*}}identifier: "$sxq_BVD"
func genericBA<let N: Int, Element>(_: Builtin.FixedArray<N, Element>) {}

// CHECK-DAG: !DICompositeType({{.*}}name: "$s4main6VectorVyxq_GD"
func genericV<let N: Int, Element>(_: Vector<N, Element>) {}

// CHECK-DAG: !DICompositeType({{.*}}name: "Builtin.FixedArray", {{.*}}identifier: "$s$3_SiBVD"
func concreteBA(_: Builtin.FixedArray<4, Int>) {}

// CHECK-DAG: !DICompositeType({{.*}}name: "$s4main6VectorVy$1_SiGD"
func concreteV(_: Vector<2, Int>) {}
3 changes: 3 additions & 0 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -480,3 +480,6 @@ $s2hi1SV1iSivy ---> hi.S.i.read2 : Swift.Int
$s2hi1SVIetMIy_TC ---> coroutine continuation prototype for @escaping @convention(thin) @convention(method) @yield_once_2 (@unowned hi.S) -> ()
$s4mainAAyyycAA1CCFTTI ---> identity thunk of main.main(main.C) -> () -> ()
$s4mainAAyyycAA1CCFTTH ---> hop to main actor thunk of main.main(main.C) -> () -> ()

$s4main6VectorVy$1_SiG ---> main.Vector<2, Swift.Int>
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>