Skip to content

Commit

Permalink
Mangling: Change new mangling for bound generic types.
Browse files Browse the repository at this point in the history
Putting the nominal type in the first place increases the changes for common prefixes (for the trie).
  • Loading branch information
eeckstein committed Dec 15, 2016
1 parent ea7f27e commit 4a492fc
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 35 deletions.
2 changes: 1 addition & 1 deletion docs/ABI.rst
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ Types
type ::= context decl-name 'a' // Type alias (DWARF only)
type ::= function-signature 'c' // function type
type ::= function-signature 'X' FUNCTION-KIND // special function type
type ::= type-list+ type 'G' // bound generic type (one type-list per nesting level of type)
type ::= type 'y' (type* '_')* type* 'G' // bound generic type (one type-list per nesting level of type)
type ::= type 'Xo' // @unowned type
type ::= type 'Xu' // @unowned(unsafe) type
type ::= type 'Xw' // @weak type
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class ASTMangler : public Mangler {
appendType(BlandTy);
}

void appendBoundGenericArgs(Type type);
void appendBoundGenericArgs(Type type, bool &isFirstArgList);

void appendImplFunctionType(SILFunctionType *fn);

Expand Down
4 changes: 3 additions & 1 deletion include/swift/Basic/Demangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ class Demangler {
NodePointer popTypeList();
NodePointer popProtocol();
NodePointer demangleBoundGenericType();
NodePointer demangleBoundGenericArgs(NodePointer nominalType);
NodePointer demangleBoundGenericArgs(NodePointer nominalType,
const std::vector<NodePointer> &TypeLists,
size_t TypeListIdx);
NodePointer demangleInitializer();
NodePointer demangleImplParamConvention();
NodePointer demangleImplResultConvention(Node::Kind ConvKind);
Expand Down
39 changes: 22 additions & 17 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,9 @@ void ASTMangler::appendType(Type type) {
case TypeKind::BoundGenericEnum:
case TypeKind::BoundGenericStruct:
if (type->isSpecialized()) {
appendBoundGenericArgs(type);
appendNominalType(type->getAnyNominal());
bool isFirstArgList = true;
appendBoundGenericArgs(type, isFirstArgList);
return appendOperator("G");
}
appendNominalType(tybase->getAnyNominal());
Expand Down Expand Up @@ -765,25 +766,29 @@ void ASTMangler::bindGenericParameters(const DeclContext *DC) {
bindGenericParameters(sig->getCanonicalSignature());
}

void ASTMangler::appendBoundGenericArgs(Type type) {
void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
BoundGenericType *boundType = nullptr;
if (auto *unboundType = type->getAs<UnboundGenericType>()) {
if (auto parent = unboundType->getParent())
appendBoundGenericArgs(parent);
return appendOperator("y");
if (Type parent = unboundType->getParent())
appendBoundGenericArgs(parent, isFirstArgList);
} else if (auto *nominalType = type->getAs<NominalType>()) {
if (Type parent = nominalType->getParent())
appendBoundGenericArgs(parent, isFirstArgList);
} else {
boundType = type->castTo<BoundGenericType>();
if (Type parent = boundType->getParent())
appendBoundGenericArgs(parent, isFirstArgList);
}
if (auto *nominalType = type->getAs<NominalType>()) {
if (auto parent = nominalType->getParent())
appendBoundGenericArgs(parent);
return appendOperator("y");
if (isFirstArgList) {
appendOperator("y");
isFirstArgList = false;
} else {
appendOperator("_");
}
auto *boundType = type->castTo<BoundGenericType>();
if (auto parent = boundType->getParent())
appendBoundGenericArgs(parent);

bool firstArg = true;
for (Type arg : boundType->getGenericArgs()) {
appendType(arg);
appendListSeparator(firstArg);
if (boundType) {
for (Type arg : boundType->getGenericArgs()) {
appendType(arg);
}
}
}

Expand Down
29 changes: 24 additions & 5 deletions lib/Basic/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,25 +661,44 @@ NodePointer Demangler::popProtocol() {
}

NodePointer Demangler::demangleBoundGenericType() {
std::vector<NodePointer> TypeListList;
std::vector<NodePointer> Types;
for (;;) {
NodePointer TList = NodeFactory::create(Node::Kind::TypeList);
TypeListList.push_back(TList);
while (NodePointer Ty = popNode(Node::Kind::Type)) {
Types.push_back(Ty);
}
while (NodePointer Ty = pop_back_val(Types)) {
TList->addChild(Ty);
}
if (popNode(Node::Kind::EmptyList))
break;
if (!popNode(Node::Kind::FirstElementMarker))
return nullptr;
}
NodePointer Nominal = popTypeAndGetNominal();
return createType(demangleBoundGenericArgs(Nominal));
return createType(demangleBoundGenericArgs(Nominal, TypeListList, 0));
}

NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal) {
NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal,
const std::vector<NodePointer> &TypeLists,
size_t TypeListIdx) {
if (!Nominal || Nominal->getNumChildren() < 2)
return nullptr;

NodePointer args = popTypeList();
if (!args)
if (TypeListIdx >= TypeLists.size())
return nullptr;
NodePointer args = TypeLists[TypeListIdx];

// Generic arguments for the outermost type come first.
NodePointer Context = Nominal->getFirstChild();

if (Context->getKind() != Node::Kind::Module &&
Context->getKind() != Node::Kind::Function &&
Context->getKind() != Node::Kind::Extension) {
NodePointer BoundParent = demangleBoundGenericArgs(Context);
NodePointer BoundParent = demangleBoundGenericArgs(Context, TypeLists,
TypeListIdx + 1);

// Rebuild this type with the new parent type, which may have
// had its generic arguments applied.
Expand Down
21 changes: 11 additions & 10 deletions lib/Basic/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class Remangler {

void mangleAnyNominalType(Node *node);
void mangleNominalType(Node *node, char TypeOp);
void mangleGenericArgs(Node *node);
void mangleGenericArgs(Node *node, char &Separator);

#define NODE(ID) \
void mangle##ID(Node *node);
Expand Down Expand Up @@ -419,8 +419,9 @@ void Remangler::mangleAnyNominalType(Node *node) {
if (isSpecialized(node)) {
NodePointer unboundType = getUnspecialized(node);
TemporaryNodes.push_back(unboundType);
mangleGenericArgs(node);
mangleAnyNominalType(unboundType.get());
char Separator = 'y';
mangleGenericArgs(node, Separator);
Buffer << 'G';
return;
}
Expand All @@ -433,16 +434,15 @@ void Remangler::mangleAnyNominalType(Node *node) {
}
}

void Remangler::mangleGenericArgs(Node *node) {
void Remangler::mangleGenericArgs(Node *node, char &Separator) {
switch (node->getKind()) {
case Node::Kind::Structure:
case Node::Kind::Enum:
case Node::Kind::Class: {
NodePointer parentOrModule = node->getChild(0);
mangleGenericArgs(parentOrModule.get());

// No generic arguments at this level
Buffer << 'y';
mangleGenericArgs(parentOrModule.get(), Separator);
Buffer << Separator;
Separator = '_';
break;
}

Expand All @@ -453,9 +453,10 @@ void Remangler::mangleGenericArgs(Node *node) {
assert(unboundType->getKind() == Node::Kind::Type);
NodePointer nominalType = unboundType->getChild(0);
NodePointer parentOrModule = nominalType->getChild(0);
mangleGenericArgs(parentOrModule.get());

mangleTypeList(node->getChild(1).get());
mangleGenericArgs(parentOrModule.get(), Separator);
Buffer << Separator;
Separator = '_';
mangleChildNodes(node->getChild(1).get());
break;
}

Expand Down

0 comments on commit 4a492fc

Please sign in to comment.