Skip to content

Implementation of new mangling (but not enabled yet) #6040

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 7 commits into from
Dec 3, 2016
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
873 changes: 499 additions & 374 deletions docs/ABI.rst

Large diffs are not rendered by default.

225 changes: 225 additions & 0 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
//===--- ASTMangler.h - Swift AST symbol mangling ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef __SWIFT_AST_ASTMANGLER_H__
#define __SWIFT_AST_ASTMANGLER_H__

#include "swift/Basic/Mangler.h"
#include "swift/AST/Types.h"
#include "swift/AST/Decl.h"
#include "swift/AST/GenericSignature.h"

namespace swift {

class AbstractClosureExpr;

namespace NewMangling {

/// Utility function which selects either the old or new mangling for a type.
std::string mangleTypeForDebugger(Type Ty, const DeclContext *DC);

/// Utility function which selects either the old or new mangling for a type and
/// mangles the type as USR.
std::string mangleTypeAsUSR(Type Ty);

/// The mangler for AST declarations.
class ASTMangler : public Mangler {
protected:
CanGenericSignature CurGenericSignature;
ModuleDecl *Mod = nullptr;
const DeclContext *DeclCtx = nullptr;

/// Optimize out protocol names if a type only conforms to one protocol.
bool OptimizeProtocolNames;

/// If enabled, Arche- and Alias types are mangled with context.
bool DWARFMangling;

public:
enum class SymbolKind {
Default,
VTableMethod,
DynamicThunk,
SwiftAsObjCThunk,
ObjCAsSwiftThunk,
DirectMethodReferenceThunk,
};

ASTMangler(bool DWARFMangling = false,
bool usePunycode = true,
bool OptimizeProtocolNames = true)
: Mangler(usePunycode),
OptimizeProtocolNames(OptimizeProtocolNames),
DWARFMangling(DWARFMangling) {}

std::string mangleClosureEntity(const AbstractClosureExpr *closure,
SymbolKind SKind);

std::string mangleEntity(const ValueDecl *decl, bool isCurried,
SymbolKind SKind = SymbolKind::Default);

std::string mangleDestructorEntity(const DestructorDecl *decl,
bool isDeallocating, SymbolKind SKind);

std::string mangleConstructorEntity(const ConstructorDecl *ctor,
bool isAllocating, bool isCurried,
SymbolKind SKind = SymbolKind::Default);

std::string mangleIVarInitDestroyEntity(const ClassDecl *decl,
bool isDestroyer, SymbolKind SKind);

std::string mangleAccessorEntity(AccessorKind kind,
AddressorKind addressorKind,
const ValueDecl *decl,
bool isStatic,
SymbolKind SKind);

std::string mangleGlobalGetterEntity(ValueDecl *decl,
SymbolKind SKind = SymbolKind::Default);

std::string mangleDefaultArgumentEntity(const DeclContext *func,
unsigned index,
SymbolKind SKind);

std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);

std::string mangleNominalType(const NominalTypeDecl *decl);

std::string mangleWitnessTable(NormalProtocolConformance *C);

std::string mangleWitnessThunk(ProtocolConformance *Conformance,
ValueDecl *Requirement);

std::string mangleClosureWitnessThunk(ProtocolConformance *Conformance,
AbstractClosureExpr *Closure);

std::string mangleBehaviorInitThunk(const VarDecl *decl);

std::string mangleGlobalVariableFull(const VarDecl *decl);

std::string mangleGlobalInit(const VarDecl *decl, int counter,
bool isInitFunc);

std::string mangleReabstructionThunkHelper(CanSILFunctionType ThunkType,
Type FromType, Type ToType,
ModuleDecl *Module);

std::string mangleType(Type decl, const DeclContext *DC);

std::string mangleTypeAsUSR(Type type);

std::string mangleTypeAsContextUSR(const NominalTypeDecl *type);

std::string mangleDeclAsUSR(ValueDecl *Decl, StringRef USRPrefix);

protected:

void appendSymbolKind(SymbolKind SKind);

void appendType(Type type);

void appendDeclName(const ValueDecl *decl);

void appendProtocolList(ArrayRef<Type> Protocols, bool &First);

GenericTypeParamType *appendAssocType(DependentMemberType *DepTy,
bool &isAssocTypeAtDepth);

void appendOpWithGenericParamIndex(StringRef,
GenericTypeParamType *paramTy);

void bindGenericParameters(const DeclContext *DC);

void bindGenericParameters(CanGenericSignature sig);

/// \brief Mangles a sugared type iff we are mangling for the debugger.
template <class T> void appendSugaredType(Type type) {
assert(DWARFMangling &&
"sugared types are only legal when mangling for the debugger");
auto *BlandTy = cast<T>(type.getPointer())->getSinglyDesugaredType();
appendType(BlandTy);
}

void appendBoundGenericArgs(Type type);

void appendImplFunctionType(SILFunctionType *fn);

void appendContextOf(const ValueDecl *decl);

void appendContext(const DeclContext *ctx);

void appendModule(const ModuleDecl *module);

void appendProtocolName(const ProtocolDecl *protocol);

void appendNominalType(const NominalTypeDecl *decl);

void appendFunctionType(AnyFunctionType *fn);

void appendFunctionSignature(AnyFunctionType *fn);

void appendParams(Type ParamsTy);

void appendTypeList(Type listTy);

void appendGenericSignature(const GenericSignature *sig);

void appendRequirement(const Requirement &reqt);

void appendGenericSignatureParts(ArrayRef<GenericTypeParamType*> params,
unsigned initialParamDepth,
ArrayRef<Requirement> requirements);

void appendAssociatedTypeName(DependentMemberType *dmt);

void appendClosureEntity(const SerializedAbstractClosureExpr *closure);

void appendClosureEntity(const AbstractClosureExpr *closure);

void appendClosureComponents(Type Ty, unsigned discriminator, bool isImplicit,
const DeclContext *parentContext,
const DeclContext *localContext);

void appendDefaultArgumentEntity(const DeclContext *ctx, unsigned index);

void appendInitializerEntity(const VarDecl *var);

Type getDeclTypeForMangling(const ValueDecl *decl,
ArrayRef<GenericTypeParamType *> &genericParams,
unsigned &initialParamIndex,
ArrayRef<Requirement> &requirements,
SmallVectorImpl<Requirement> &requirementsBuf);

void appendDeclType(const ValueDecl *decl);

bool tryAppendStandardSubstitution(const NominalTypeDecl *type);

void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating);

void appendDestructorEntity(const DestructorDecl *decl, bool isDeallocating);

void appendAccessorEntity(AccessorKind kind,
AddressorKind addressorKind,
const ValueDecl *decl,
bool isStatic);

void appendEntity(const ValueDecl *decl, StringRef EntityOp, bool isStatic);

void appendEntity(const ValueDecl *decl);

void appendProtocolConformance(const ProtocolConformance *conformance);
};

} // end namespace NewMangling
} // end namespace swift

#endif // __SWIFT_AST_ASTMANGLER_H__
37 changes: 15 additions & 22 deletions include/swift/Basic/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,27 +108,9 @@ static inline char encodeSpecializationPass(SpecializationPass Pass) {
}

enum class ValueWitnessKind {
AllocateBuffer,
AssignWithCopy,
AssignWithTake,
DeallocateBuffer,
Destroy,
DestroyBuffer,
InitializeBufferWithCopyOfBuffer,
InitializeBufferWithCopy,
InitializeWithCopy,
InitializeBufferWithTake,
InitializeWithTake,
ProjectBuffer,
InitializeBufferWithTakeOfBuffer,
DestroyArray,
InitializeArrayWithCopy,
InitializeArrayWithTakeFrontToBack,
InitializeArrayWithTakeBackToFront,
StoreExtraInhabitant,
GetExtraInhabitantIndex,
GetEnumTag,
DestructiveProjectEnumData,
#define VALUE_WITNESS(MANGLING, NAME) \
NAME,
#include "swift/Basic/ValueWitnessMangling.def"
};

enum class Directness {
Expand Down Expand Up @@ -334,6 +316,8 @@ void mangleIdentifier(const char *data, size_t length,
/// This should always round-trip perfectly with demangleSymbolAsNode.
std::string mangleNode(const NodePointer &root);

std::string mangleNodeNew(const NodePointer &root);

/// \brief Transform the node structure to a string.
///
/// Typical usage:
Expand Down Expand Up @@ -404,11 +388,20 @@ class DemanglerPrinter {
}

std::string &&str() && { return std::move(Stream); }


llvm::StringRef getStringRef() const { return Stream; }

/// Returns a mutable reference to the last character added to the printer.
char &lastChar() { return Stream.back(); }

private:
std::string Stream;
};

bool mangleStandardSubstitution(Node *node, DemanglerPrinter &Out);
bool isSpecialized(Node *node);
NodePointer getUnspecialized(Node *node);

/// Is a character considered a digit by the demangling grammar?
///
/// Yes, this is equivalent to the standard C isdigit(3), but some platforms
Expand Down
9 changes: 8 additions & 1 deletion include/swift/Basic/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,14 @@ NODE(VTableAttribute)
NODE(Weak)
CONTEXT_NODE(WillSet)
NODE(WitnessTableOffset)
NODE(ReflectionMetadataBuiltinDescriptor)
NODE(ReflectionMetadataFieldDescriptor)
NODE(ReflectionMetadataAssocTypeDescriptor)
NODE(ReflectionMetadataSuperclassDescriptor)
CONTEXT_NODE(CurryThunk)
NODE(ThrowsAnnotation)

NODE(EmptyList)
NODE(FirstElementMarker)
NODE(VariadicMarker)
#undef CONTEXT_NODE
#undef NODE
3 changes: 3 additions & 0 deletions include/swift/Basic/DemangleWrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class NodeDumper {
void print(llvm::raw_ostream &Out) const;
};

/// Utility function, useful to be called from the debugger.
void dumpNode(const NodePointer &Root);

NodePointer
demangleSymbolAsNode(StringRef MangledName,
const DemangleOptions &Options = DemangleOptions());
Expand Down
Loading