Skip to content

Commit 1ff2154

Browse files
authored
Merge pull request swiftlang#6040 from eeckstein/newmangling
Implementation of new mangling (but not enabled yet)
2 parents 5c83637 + 5e6c5a7 commit 1ff2154

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+7775
-699
lines changed

docs/ABI.rst

Lines changed: 499 additions & 374 deletions
Large diffs are not rendered by default.

include/swift/AST/ASTMangler.h

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
//===--- ASTMangler.h - Swift AST symbol mangling ---------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef __SWIFT_AST_ASTMANGLER_H__
14+
#define __SWIFT_AST_ASTMANGLER_H__
15+
16+
#include "swift/Basic/Mangler.h"
17+
#include "swift/AST/Types.h"
18+
#include "swift/AST/Decl.h"
19+
#include "swift/AST/GenericSignature.h"
20+
21+
namespace swift {
22+
23+
class AbstractClosureExpr;
24+
25+
namespace NewMangling {
26+
27+
/// Utility function which selects either the old or new mangling for a type.
28+
std::string mangleTypeForDebugger(Type Ty, const DeclContext *DC);
29+
30+
/// Utility function which selects either the old or new mangling for a type and
31+
/// mangles the type as USR.
32+
std::string mangleTypeAsUSR(Type Ty);
33+
34+
/// The mangler for AST declarations.
35+
class ASTMangler : public Mangler {
36+
protected:
37+
CanGenericSignature CurGenericSignature;
38+
ModuleDecl *Mod = nullptr;
39+
const DeclContext *DeclCtx = nullptr;
40+
41+
/// Optimize out protocol names if a type only conforms to one protocol.
42+
bool OptimizeProtocolNames;
43+
44+
/// If enabled, Arche- and Alias types are mangled with context.
45+
bool DWARFMangling;
46+
47+
public:
48+
enum class SymbolKind {
49+
Default,
50+
VTableMethod,
51+
DynamicThunk,
52+
SwiftAsObjCThunk,
53+
ObjCAsSwiftThunk,
54+
DirectMethodReferenceThunk,
55+
};
56+
57+
ASTMangler(bool DWARFMangling = false,
58+
bool usePunycode = true,
59+
bool OptimizeProtocolNames = true)
60+
: Mangler(usePunycode),
61+
OptimizeProtocolNames(OptimizeProtocolNames),
62+
DWARFMangling(DWARFMangling) {}
63+
64+
std::string mangleClosureEntity(const AbstractClosureExpr *closure,
65+
SymbolKind SKind);
66+
67+
std::string mangleEntity(const ValueDecl *decl, bool isCurried,
68+
SymbolKind SKind = SymbolKind::Default);
69+
70+
std::string mangleDestructorEntity(const DestructorDecl *decl,
71+
bool isDeallocating, SymbolKind SKind);
72+
73+
std::string mangleConstructorEntity(const ConstructorDecl *ctor,
74+
bool isAllocating, bool isCurried,
75+
SymbolKind SKind = SymbolKind::Default);
76+
77+
std::string mangleIVarInitDestroyEntity(const ClassDecl *decl,
78+
bool isDestroyer, SymbolKind SKind);
79+
80+
std::string mangleAccessorEntity(AccessorKind kind,
81+
AddressorKind addressorKind,
82+
const ValueDecl *decl,
83+
bool isStatic,
84+
SymbolKind SKind);
85+
86+
std::string mangleGlobalGetterEntity(ValueDecl *decl,
87+
SymbolKind SKind = SymbolKind::Default);
88+
89+
std::string mangleDefaultArgumentEntity(const DeclContext *func,
90+
unsigned index,
91+
SymbolKind SKind);
92+
93+
std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);
94+
95+
std::string mangleNominalType(const NominalTypeDecl *decl);
96+
97+
std::string mangleWitnessTable(NormalProtocolConformance *C);
98+
99+
std::string mangleWitnessThunk(ProtocolConformance *Conformance,
100+
ValueDecl *Requirement);
101+
102+
std::string mangleClosureWitnessThunk(ProtocolConformance *Conformance,
103+
AbstractClosureExpr *Closure);
104+
105+
std::string mangleBehaviorInitThunk(const VarDecl *decl);
106+
107+
std::string mangleGlobalVariableFull(const VarDecl *decl);
108+
109+
std::string mangleGlobalInit(const VarDecl *decl, int counter,
110+
bool isInitFunc);
111+
112+
std::string mangleReabstructionThunkHelper(CanSILFunctionType ThunkType,
113+
Type FromType, Type ToType,
114+
ModuleDecl *Module);
115+
116+
std::string mangleType(Type decl, const DeclContext *DC);
117+
118+
std::string mangleTypeAsUSR(Type type);
119+
120+
std::string mangleTypeAsContextUSR(const NominalTypeDecl *type);
121+
122+
std::string mangleDeclAsUSR(ValueDecl *Decl, StringRef USRPrefix);
123+
124+
protected:
125+
126+
void appendSymbolKind(SymbolKind SKind);
127+
128+
void appendType(Type type);
129+
130+
void appendDeclName(const ValueDecl *decl);
131+
132+
void appendProtocolList(ArrayRef<Type> Protocols, bool &First);
133+
134+
GenericTypeParamType *appendAssocType(DependentMemberType *DepTy,
135+
bool &isAssocTypeAtDepth);
136+
137+
void appendOpWithGenericParamIndex(StringRef,
138+
GenericTypeParamType *paramTy);
139+
140+
void bindGenericParameters(const DeclContext *DC);
141+
142+
void bindGenericParameters(CanGenericSignature sig);
143+
144+
/// \brief Mangles a sugared type iff we are mangling for the debugger.
145+
template <class T> void appendSugaredType(Type type) {
146+
assert(DWARFMangling &&
147+
"sugared types are only legal when mangling for the debugger");
148+
auto *BlandTy = cast<T>(type.getPointer())->getSinglyDesugaredType();
149+
appendType(BlandTy);
150+
}
151+
152+
void appendBoundGenericArgs(Type type);
153+
154+
void appendImplFunctionType(SILFunctionType *fn);
155+
156+
void appendContextOf(const ValueDecl *decl);
157+
158+
void appendContext(const DeclContext *ctx);
159+
160+
void appendModule(const ModuleDecl *module);
161+
162+
void appendProtocolName(const ProtocolDecl *protocol);
163+
164+
void appendNominalType(const NominalTypeDecl *decl);
165+
166+
void appendFunctionType(AnyFunctionType *fn);
167+
168+
void appendFunctionSignature(AnyFunctionType *fn);
169+
170+
void appendParams(Type ParamsTy);
171+
172+
void appendTypeList(Type listTy);
173+
174+
void appendGenericSignature(const GenericSignature *sig);
175+
176+
void appendRequirement(const Requirement &reqt);
177+
178+
void appendGenericSignatureParts(ArrayRef<GenericTypeParamType*> params,
179+
unsigned initialParamDepth,
180+
ArrayRef<Requirement> requirements);
181+
182+
void appendAssociatedTypeName(DependentMemberType *dmt);
183+
184+
void appendClosureEntity(const SerializedAbstractClosureExpr *closure);
185+
186+
void appendClosureEntity(const AbstractClosureExpr *closure);
187+
188+
void appendClosureComponents(Type Ty, unsigned discriminator, bool isImplicit,
189+
const DeclContext *parentContext,
190+
const DeclContext *localContext);
191+
192+
void appendDefaultArgumentEntity(const DeclContext *ctx, unsigned index);
193+
194+
void appendInitializerEntity(const VarDecl *var);
195+
196+
Type getDeclTypeForMangling(const ValueDecl *decl,
197+
ArrayRef<GenericTypeParamType *> &genericParams,
198+
unsigned &initialParamIndex,
199+
ArrayRef<Requirement> &requirements,
200+
SmallVectorImpl<Requirement> &requirementsBuf);
201+
202+
void appendDeclType(const ValueDecl *decl);
203+
204+
bool tryAppendStandardSubstitution(const NominalTypeDecl *type);
205+
206+
void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating);
207+
208+
void appendDestructorEntity(const DestructorDecl *decl, bool isDeallocating);
209+
210+
void appendAccessorEntity(AccessorKind kind,
211+
AddressorKind addressorKind,
212+
const ValueDecl *decl,
213+
bool isStatic);
214+
215+
void appendEntity(const ValueDecl *decl, StringRef EntityOp, bool isStatic);
216+
217+
void appendEntity(const ValueDecl *decl);
218+
219+
void appendProtocolConformance(const ProtocolConformance *conformance);
220+
};
221+
222+
} // end namespace NewMangling
223+
} // end namespace swift
224+
225+
#endif // __SWIFT_AST_ASTMANGLER_H__

include/swift/Basic/Demangle.h

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,9 @@ static inline char encodeSpecializationPass(SpecializationPass Pass) {
108108
}
109109

110110
enum class ValueWitnessKind {
111-
AllocateBuffer,
112-
AssignWithCopy,
113-
AssignWithTake,
114-
DeallocateBuffer,
115-
Destroy,
116-
DestroyBuffer,
117-
InitializeBufferWithCopyOfBuffer,
118-
InitializeBufferWithCopy,
119-
InitializeWithCopy,
120-
InitializeBufferWithTake,
121-
InitializeWithTake,
122-
ProjectBuffer,
123-
InitializeBufferWithTakeOfBuffer,
124-
DestroyArray,
125-
InitializeArrayWithCopy,
126-
InitializeArrayWithTakeFrontToBack,
127-
InitializeArrayWithTakeBackToFront,
128-
StoreExtraInhabitant,
129-
GetExtraInhabitantIndex,
130-
GetEnumTag,
131-
DestructiveProjectEnumData,
111+
#define VALUE_WITNESS(MANGLING, NAME) \
112+
NAME,
113+
#include "swift/Basic/ValueWitnessMangling.def"
132114
};
133115

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

319+
std::string mangleNodeNew(const NodePointer &root);
320+
337321
/// \brief Transform the node structure to a string.
338322
///
339323
/// Typical usage:
@@ -404,11 +388,20 @@ class DemanglerPrinter {
404388
}
405389

406390
std::string &&str() && { return std::move(Stream); }
407-
391+
392+
llvm::StringRef getStringRef() const { return Stream; }
393+
394+
/// Returns a mutable reference to the last character added to the printer.
395+
char &lastChar() { return Stream.back(); }
396+
408397
private:
409398
std::string Stream;
410399
};
411400

401+
bool mangleStandardSubstitution(Node *node, DemanglerPrinter &Out);
402+
bool isSpecialized(Node *node);
403+
NodePointer getUnspecialized(Node *node);
404+
412405
/// Is a character considered a digit by the demangling grammar?
413406
///
414407
/// Yes, this is equivalent to the standard C isdigit(3), but some platforms

include/swift/Basic/DemangleNodes.def

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,14 @@ NODE(VTableAttribute)
161161
NODE(Weak)
162162
CONTEXT_NODE(WillSet)
163163
NODE(WitnessTableOffset)
164+
NODE(ReflectionMetadataBuiltinDescriptor)
165+
NODE(ReflectionMetadataFieldDescriptor)
166+
NODE(ReflectionMetadataAssocTypeDescriptor)
167+
NODE(ReflectionMetadataSuperclassDescriptor)
168+
CONTEXT_NODE(CurryThunk)
164169
NODE(ThrowsAnnotation)
165-
170+
NODE(EmptyList)
171+
NODE(FirstElementMarker)
172+
NODE(VariadicMarker)
166173
#undef CONTEXT_NODE
167174
#undef NODE

include/swift/Basic/DemangleWrappers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class NodeDumper {
3939
void print(llvm::raw_ostream &Out) const;
4040
};
4141

42+
/// Utility function, useful to be called from the debugger.
43+
void dumpNode(const NodePointer &Root);
44+
4245
NodePointer
4346
demangleSymbolAsNode(StringRef MangledName,
4447
const DemangleOptions &Options = DemangleOptions());

0 commit comments

Comments
 (0)