dmangle.d (dmd-2.095.0) | : | dmangle.d (dmd-2.095.1) | ||
---|---|---|---|---|
skipping to change at line 182 | skipping to change at line 182 | |||
} | } | |||
private extern (C++) final class Mangler : Visitor | private extern (C++) final class Mangler : Visitor | |||
{ | { | |||
alias visit = Visitor.visit; | alias visit = Visitor.visit; | |||
public: | public: | |||
static assert(Key.sizeof == size_t.sizeof); | static assert(Key.sizeof == size_t.sizeof); | |||
AssocArray!(Type, size_t) types; // Type => (offset+1) in buf | AssocArray!(Type, size_t) types; // Type => (offset+1) in buf | |||
AssocArray!(Identifier, size_t) idents; // Identifier => (offset+1) in buf | AssocArray!(Identifier, size_t) idents; // Identifier => (offset+1) in buf | |||
OutBuffer* buf; | OutBuffer* buf; | |||
Type rootType; | ||||
extern (D) this(OutBuffer* buf) | extern (D) this(OutBuffer* buf, Type rootType = null) | |||
{ | { | |||
this.buf = buf; | this.buf = buf; | |||
this.rootType = rootType; | ||||
} | } | |||
/** | /** | |||
* writes a back reference with the relative position encoded with base 26 | * writes a back reference with the relative position encoded with base 26 | |||
* using upper case letters for all digits but the last digit which uses | * using upper case letters for all digits but the last digit which uses | |||
* a lower case letter. | * a lower case letter. | |||
* The decoder has to look up the referenced position to determine | * The decoder has to look up the referenced position to determine | |||
* whether the back reference is an identifer (starts with a digit) | * whether the back reference is an identifer (starts with a digit) | |||
* or a type (starts with a letter). | * or a type (starts with a letter). | |||
* | * | |||
skipping to change at line 231 | skipping to change at line 233 | |||
* | * | |||
* Params: | * Params: | |||
* t = the type to encode via back referencing | * t = the type to encode via back referencing | |||
* | * | |||
* Returns: | * Returns: | |||
* true if the type was found. A back reference has been encoded. | * true if the type was found. A back reference has been encoded. | |||
* false if the type was not found. The current position is saved for later back references. | * false if the type was not found. The current position is saved for later back references. | |||
*/ | */ | |||
bool backrefType(Type t) | bool backrefType(Type t) | |||
{ | { | |||
if (!t.isTypeBasic()) | if (t.isTypeBasic()) | |||
return backrefImpl(types, t); | return false; | |||
return false; | ||||
/** | ||||
* https://issues.dlang.org/show_bug.cgi?id=21591 | ||||
* | ||||
* Special case for unmerged TypeFunctions: use the generic merged | ||||
* function type as backref cache key to avoid missed backrefs. | ||||
* | ||||
* Merging is based on mangling, so we need to avoid an infinite | ||||
* recursion by excluding the case where `t` is the root type passed to | ||||
* `mangleToBuffer()`. | ||||
*/ | ||||
if (t != rootType) | ||||
{ | ||||
if (t.ty == Tfunction || t.ty == Tdelegate || | ||||
(t.ty == Tpointer && t.nextOf().ty == Tfunction)) | ||||
{ | ||||
t = t.merge2(); | ||||
} | ||||
} | ||||
return backrefImpl(types, t); | ||||
} | } | |||
/** | /** | |||
* Back references a single identifier | * Back references a single identifier | |||
* | * | |||
* The encoded mangling is | * The encoded mangling is | |||
* 'Q' <relative position of first occurrence of type> | * 'Q' <relative position of first occurrence of type> | |||
* | * | |||
* Params: | * Params: | |||
* id = the identifier to encode via back referencing | * id = the identifier to encode via back referencing | |||
skipping to change at line 1181 | skipping to change at line 1203 | |||
} | } | |||
return fd.mangleString; | return fd.mangleString; | |||
} | } | |||
extern (C++) void mangleToBuffer(Type t, OutBuffer* buf) | extern (C++) void mangleToBuffer(Type t, OutBuffer* buf) | |||
{ | { | |||
if (t.deco) | if (t.deco) | |||
buf.writestring(t.deco); | buf.writestring(t.deco); | |||
else | else | |||
{ | { | |||
scope Mangler v = new Mangler(buf); | scope Mangler v = new Mangler(buf, t); | |||
v.visitWithMask(t, 0); | v.visitWithMask(t, 0); | |||
} | } | |||
} | } | |||
extern (C++) void mangleToBuffer(Expression e, OutBuffer* buf) | extern (C++) void mangleToBuffer(Expression e, OutBuffer* buf) | |||
{ | { | |||
scope Mangler v = new Mangler(buf); | scope Mangler v = new Mangler(buf); | |||
e.accept(v); | e.accept(v); | |||
} | } | |||
skipping to change at line 1203 | skipping to change at line 1225 | |||
{ | { | |||
scope Mangler v = new Mangler(buf); | scope Mangler v = new Mangler(buf); | |||
s.accept(v); | s.accept(v); | |||
} | } | |||
extern (C++) void mangleToBuffer(TemplateInstance ti, OutBuffer* buf) | extern (C++) void mangleToBuffer(TemplateInstance ti, OutBuffer* buf) | |||
{ | { | |||
scope Mangler v = new Mangler(buf); | scope Mangler v = new Mangler(buf); | |||
v.mangleTemplateInstance(ti); | v.mangleTemplateInstance(ti); | |||
} | } | |||
/****************************************************************************** | ||||
* Mangle function signatures ('this' qualifier, and parameter types) | ||||
* to check conflicts in function overloads. | ||||
* It's different from fd.type.deco. For example, fd.type.deco would be null | ||||
* if fd is an auto function. | ||||
* | ||||
* Params: | ||||
* buf = `OutBuffer` to write the mangled function signature to | ||||
* fd = `FuncDeclaration` to mangle | ||||
*/ | ||||
void mangleToFuncSignature(ref OutBuffer buf, FuncDeclaration fd) | ||||
{ | ||||
auto tf = fd.type.isTypeFunction(); | ||||
scope Mangler v = new Mangler(&buf); | ||||
MODtoDecoBuffer(&buf, tf.mod); | ||||
foreach (idx, param; tf.parameterList) | ||||
param.accept(v); | ||||
buf.writeByte('Z' - tf.parameterList.varargs); | ||||
} | ||||
End of changes. 6 change blocks. | ||||
5 lines changed or deleted | 27 lines changed or added |