Skip to content

Commit

Permalink
Mangling: add a substitution for optional types (bound generic enum S…
Browse files Browse the repository at this point in the history
…wift.Optional)
  • Loading branch information
eeckstein committed Dec 15, 2016
1 parent 4a492fc commit eb9cadb
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/ABI.rst
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,7 @@ Types
type ::= function-signature 'c' // function type
type ::= function-signature 'X' FUNCTION-KIND // special function type
type ::= type 'y' (type* '_')* type* 'G' // bound generic type (one type-list per nesting level of type)
type ::= type 'Sg' // optional type, shortcut for: type 'ySqG'
type ::= type 'Xo' // @unowned type
type ::= type 'Xu' // @unowned(unsafe) type
type ::= type 'Xw' // @weak type
Expand Down
5 changes: 2 additions & 3 deletions include/swift/Basic/ManglingMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#define NO_ARGS_MANGLING yy
#define FUNC_TYPE_MANGLING c
#define OBJC_PARTIAL_APPLY_THUNK_MANGLING Ta
#define OPTIONAL_MANGLING(Ty) MANGLING_CONCAT2_IMPL(Ty, Sg)

#else

Expand All @@ -60,6 +61,7 @@
#define NO_ARGS_MANGLING T_T_
#define FUNC_TYPE_MANGLING F
#define OBJC_PARTIAL_APPLY_THUNK_MANGLING PAo
#define OPTIONAL_MANGLING(Ty) MANGLING_CONCAT3_IMPL(GSq, Ty, _)

#endif

Expand All @@ -69,9 +71,6 @@
#define THIN_FUNCTION_MANGLING \
MANGLING_CONCAT2(NO_ARGS_MANGLING, Xf)

#define OPTIONAL_MANGLING(Ty) \
MANGLING_CONCAT3(MANGLING_CONCAT2_IMPL(Ty, _), Sq, G)

#define METADATA_SYM(Ty) \
MANGLE_SYM(MANGLING_CONCAT2(Ty, METADATA_MANGLING))

Expand Down
18 changes: 15 additions & 3 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ static const char *getMetatypeRepresentationOp(MetatypeRepresentation Rep) {
}
}

static bool isStdlibType(const NominalTypeDecl *decl) {
DeclContext *dc = decl->getDeclContext();
return dc->isModuleScopeContext() && dc->getParentModule()->isStdlibModule();
}

/// Mangle a type into the buffer.
///
void ASTMangler::appendType(Type type) {
Expand Down Expand Up @@ -538,7 +543,15 @@ void ASTMangler::appendType(Type type) {
case TypeKind::BoundGenericEnum:
case TypeKind::BoundGenericStruct:
if (type->isSpecialized()) {
appendNominalType(type->getAnyNominal());
NominalTypeDecl *NDecl = type->getAnyNominal();
if (isStdlibType(NDecl) && NDecl->getName().str() == "Optional") {
auto GenArgs = type->castTo<BoundGenericType>()->getGenericArgs();
assert(GenArgs.size() == 1);
appendType(GenArgs[0]);
return appendOperator("Sg");
}

appendNominalType(NDecl);
bool isFirstArgList = true;
appendBoundGenericArgs(type, isFirstArgList);
return appendOperator("G");
Expand Down Expand Up @@ -1509,8 +1522,7 @@ void ASTMangler::appendDeclType(const ValueDecl *decl) {

bool ASTMangler::tryAppendStandardSubstitution(const NominalTypeDecl *decl) {
// Bail out if our parent isn't the swift standard library.
DeclContext *dc = decl->getDeclContext();
if (!dc->isModuleScopeContext() || !dc->getParentModule()->isStdlibModule())
if (!isStdlibType(decl))
return false;

StringRef name = decl->getName().str();
Expand Down
4 changes: 4 additions & 0 deletions lib/Basic/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ NodePointer Demangler::demangleKnownType() {
return createSwiftType(Node::Kind::Structure, "String");
case 'u':
return createSwiftType(Node::Kind::Structure, "UInt");
case 'g':
return createType(createWithChildren(Node::Kind::BoundGenericEnum,
createSwiftType(Node::Kind::Enum, "Optional"),
createWithChild(Node::Kind::TypeList, popNode(Node::Kind::Type))));
default:
return nullptr;
}
Expand Down
10 changes: 10 additions & 0 deletions lib/Basic/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,16 @@ void Remangler::mangleBoundGenericClass(Node *node) {
}

void Remangler::mangleBoundGenericEnum(Node *node) {
Node *Enum = node->getChild(0).get()->getChild(0).get();
assert(Enum->getKind() == Node::Kind::Enum);
Node *Mod = Enum->getChild(0).get();
Node *Id = Enum->getChild(1).get();
if (Mod->getKind() == Node::Kind::Module && Mod->getText() == STDLIB_NAME &&
Id->getKind() == Node::Kind::Identifier && Id->getText() == "Optional") {
mangleSingleChildNode(node->getChild(1).get());
Buffer << "Sg";
return;
}
mangleAnyNominalType(node);
}

Expand Down

0 comments on commit eb9cadb

Please sign in to comment.