mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
Merge current development state of 2.067
First merge of current development stream. Asm blocks are known to be broken. DMD: 0c9f437bc24015707130ba42dc434d9cd58282fb druntime: 86d49cfb3670904603df0cfdfe44c6fff565c0fc Phobos: a8ca4f7964becac680af0eadbde05aa7d10fc338
This commit is contained in:
parent
2bcf8880d1
commit
a2748cd2fd
95 changed files with 8240 additions and 7214 deletions
325
dmd2/cppmangle.c
325
dmd2/cppmangle.c
|
@ -49,6 +49,7 @@ class CppMangleVisitor : public Visitor
|
|||
Objects components;
|
||||
OutBuffer buf;
|
||||
bool is_top_level;
|
||||
bool components_on;
|
||||
|
||||
void writeBase36(size_t i)
|
||||
{
|
||||
|
@ -67,50 +68,55 @@ class CppMangleVisitor : public Visitor
|
|||
|
||||
int substitute(RootObject *p)
|
||||
{
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
if (p == components[i])
|
||||
//printf("substitute %s\n", p ? p->toChars() : NULL);
|
||||
if (components_on)
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
|
||||
*/
|
||||
buf.writeByte('S');
|
||||
if (i)
|
||||
writeBase36(i - 1);
|
||||
buf.writeByte('_');
|
||||
return 1;
|
||||
if (p == components[i])
|
||||
{
|
||||
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
|
||||
*/
|
||||
buf.writeByte('S');
|
||||
if (i)
|
||||
writeBase36(i - 1);
|
||||
buf.writeByte('_');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exist(RootObject *p)
|
||||
{
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
if (p == components[i])
|
||||
//printf("exist %s\n", p ? p->toChars() : NULL);
|
||||
if (components_on)
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
return 1;
|
||||
if (p == components[i])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void store(RootObject *p)
|
||||
{
|
||||
//printf("push %s\n", p ? p->toChars() : NULL);
|
||||
components.push(p);
|
||||
//printf("store %s\n", p ? p->toChars() : NULL);
|
||||
if (components_on)
|
||||
components.push(p);
|
||||
}
|
||||
|
||||
void source_name(Dsymbol *s)
|
||||
void source_name(Dsymbol *s, bool skipname = false)
|
||||
{
|
||||
char *name = s->ident->toChars();
|
||||
//printf("source_name(%s)\n", s->toChars());
|
||||
TemplateInstance *ti = s->isTemplateInstance();
|
||||
if (ti)
|
||||
{
|
||||
if (!substitute(ti->tempdecl))
|
||||
if (!skipname && !substitute(ti->tempdecl))
|
||||
{
|
||||
store(ti->tempdecl);
|
||||
name = ti->name->toChars();
|
||||
const char *name = ti->toAlias()->ident->toChars();
|
||||
buf.printf("%d%s", strlen(name), name);
|
||||
}
|
||||
buf.writeByte('I');
|
||||
|
@ -208,8 +214,7 @@ class CppMangleVisitor : public Visitor
|
|||
{
|
||||
if (!substitute(d))
|
||||
{
|
||||
cpp_mangle_name(d);
|
||||
store(d);
|
||||
cpp_mangle_name(d, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -234,12 +239,14 @@ class CppMangleVisitor : public Visitor
|
|||
}
|
||||
else
|
||||
{
|
||||
const char *name = s->ident->toChars();
|
||||
buf.printf("%d%s", strlen(name), name);
|
||||
}
|
||||
}
|
||||
|
||||
void prefix_name(Dsymbol *s)
|
||||
{
|
||||
//printf("prefix_name(%s)\n", s->toChars());
|
||||
if (!substitute(s))
|
||||
{
|
||||
store(s);
|
||||
|
@ -265,13 +272,32 @@ class CppMangleVisitor : public Visitor
|
|||
}
|
||||
}
|
||||
|
||||
void cpp_mangle_name(Dsymbol *s)
|
||||
/* Is s the initial qualifier?
|
||||
*/
|
||||
bool is_initial_qualifier(Dsymbol *s)
|
||||
{
|
||||
Dsymbol *p = s->toParent();
|
||||
if (p && p->isTemplateInstance())
|
||||
{
|
||||
if (exist(p->isTemplateInstance()->tempdecl))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
p = p->toParent();
|
||||
}
|
||||
|
||||
return !p || p->isModule();
|
||||
}
|
||||
|
||||
void cpp_mangle_name(Dsymbol *s, bool qualified)
|
||||
{
|
||||
//printf("cpp_mangle_name(%s, %d)\n", s->toChars(), qualified);
|
||||
Dsymbol *p = s->toParent();
|
||||
Dsymbol *se = s;
|
||||
bool dont_write_prefix = false;
|
||||
if (p && p->isTemplateInstance())
|
||||
{
|
||||
s = p;
|
||||
se = p;
|
||||
if (exist(p->isTemplateInstance()->tempdecl))
|
||||
dont_write_prefix = true;
|
||||
p = p->toParent();
|
||||
|
@ -279,14 +305,93 @@ class CppMangleVisitor : public Visitor
|
|||
|
||||
if (p && !p->isModule())
|
||||
{
|
||||
buf.writeByte('N');
|
||||
if (!dont_write_prefix)
|
||||
prefix_name(p);
|
||||
source_name(s);
|
||||
buf.writeByte('E');
|
||||
/* The N..E is not required if:
|
||||
* 1. the parent is 'std'
|
||||
* 2. 'std' is the initial qualifier
|
||||
* 3. there is no CV-qualifier or a ref-qualifier for a member function
|
||||
* ABI 5.1.8
|
||||
*/
|
||||
if (p->ident == Id::std &&
|
||||
is_initial_qualifier(p) &&
|
||||
!qualified)
|
||||
{
|
||||
if (s->ident == Id::allocator)
|
||||
{
|
||||
buf.writestring("Sa"); // "Sa" is short for ::std::allocator
|
||||
source_name(se, true);
|
||||
}
|
||||
else if (s->ident == Id::basic_string)
|
||||
{
|
||||
components_on = false; // turn off substitutions
|
||||
buf.writestring("Sb"); // "Sb" is short for ::std::basic_string
|
||||
size_t off = buf.offset;
|
||||
source_name(se, true);
|
||||
components_on = true;
|
||||
|
||||
// Replace ::std::basic_string < char, ::std::char_traits<char>, ::std::allocator<char> >
|
||||
// with Ss
|
||||
//printf("xx: '%.*s'\n", (int)(buf.offset - off), buf.data + off);
|
||||
if (buf.offset - off >= 26 &&
|
||||
memcmp(buf.data + off, "IcSt11char_traitsIcESaIcEE", 26) == 0)
|
||||
{
|
||||
buf.remove(off - 2, 28);
|
||||
buf.insert(off - 2, "Ss", 2);
|
||||
return;
|
||||
}
|
||||
buf.setsize(off);
|
||||
source_name(se, true);
|
||||
}
|
||||
else if (s->ident == Id::basic_istream ||
|
||||
s->ident == Id::basic_ostream ||
|
||||
s->ident == Id::basic_iostream)
|
||||
{
|
||||
/* Replace
|
||||
* ::std::basic_istream<char, std::char_traits<char> > with Si
|
||||
* ::std::basic_ostream<char, std::char_traits<char> > with So
|
||||
* ::std::basic_iostream<char, std::char_traits<char> > with Sd
|
||||
*/
|
||||
size_t off = buf.offset;
|
||||
components_on = false; // turn off substitutions
|
||||
source_name(se, true);
|
||||
components_on = true;
|
||||
|
||||
//printf("xx: '%.*s'\n", (int)(buf.offset - off), buf.data + off);
|
||||
if (buf.offset - off >= 21 &&
|
||||
memcmp(buf.data + off, "IcSt11char_traitsIcEE", 21) == 0)
|
||||
{
|
||||
buf.remove(off, 21);
|
||||
char mbuf[2];
|
||||
mbuf[0] = 'S';
|
||||
mbuf[1] = 'i';
|
||||
if (s->ident == Id::basic_ostream)
|
||||
mbuf[1] = 'o';
|
||||
else if(s->ident == Id::basic_iostream)
|
||||
mbuf[1] = 'd';
|
||||
buf.insert(off, mbuf, 2);
|
||||
return;
|
||||
}
|
||||
buf.setsize(off);
|
||||
buf.writestring("St");
|
||||
source_name(se);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.writestring("St");
|
||||
source_name(se);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.writeByte('N');
|
||||
if (!dont_write_prefix)
|
||||
prefix_name(p);
|
||||
source_name(se);
|
||||
buf.writeByte('E');
|
||||
}
|
||||
}
|
||||
else
|
||||
source_name(s);
|
||||
source_name(se);
|
||||
store(s);
|
||||
}
|
||||
|
||||
void mangle_variable(VarDeclaration *d, bool is_temp_arg_ref)
|
||||
|
@ -324,6 +429,7 @@ class CppMangleVisitor : public Visitor
|
|||
|
||||
void mangle_function(FuncDeclaration *d)
|
||||
{
|
||||
//printf("mangle_function(%s)\n", d->toChars());
|
||||
/*
|
||||
* <mangled-name> ::= _Z <encoding>
|
||||
* <encoding> ::= <function name> <bare-function-type>
|
||||
|
@ -340,6 +446,30 @@ class CppMangleVisitor : public Visitor
|
|||
if (d->type->isConst())
|
||||
buf.writeByte('K');
|
||||
prefix_name(p);
|
||||
|
||||
// See ABI 5.1.8 Compression
|
||||
|
||||
// Replace ::std::allocator with Sa
|
||||
if (buf.offset >= 17 && memcmp(buf.data, "_ZN3std9allocator", 17) == 0)
|
||||
{
|
||||
buf.remove(3, 14);
|
||||
buf.insert(3, "Sa", 2);
|
||||
}
|
||||
|
||||
// Replace ::std::basic_string with Sb
|
||||
if (buf.offset >= 21 && memcmp(buf.data, "_ZN3std12basic_string", 21) == 0)
|
||||
{
|
||||
buf.remove(3, 18);
|
||||
buf.insert(3, "Sb", 2);
|
||||
}
|
||||
|
||||
// Replace ::std with St
|
||||
if (buf.offset >= 7 && memcmp(buf.data, "_ZN3std", 7) == 0)
|
||||
{
|
||||
buf.remove(3, 4);
|
||||
buf.insert(3, "St", 2);
|
||||
}
|
||||
|
||||
if (d->isDtorDeclaration())
|
||||
{
|
||||
buf.writestring("D1");
|
||||
|
@ -408,7 +538,7 @@ class CppMangleVisitor : public Visitor
|
|||
|
||||
public:
|
||||
CppMangleVisitor()
|
||||
: buf(), components(), is_top_level(false)
|
||||
: buf(), components(), is_top_level(false), components_on(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -483,14 +613,14 @@ public:
|
|||
case Tint32: c = 'i'; break;
|
||||
case Tuns32: c = 'j'; break;
|
||||
case Tfloat32: c = 'f'; break;
|
||||
case Tint64: c = (Target::longsize == 8 ? 'l' : 'x'); break;
|
||||
case Tuns64: c = (Target::longsize == 8 ? 'm' : 'y'); break;
|
||||
case Tint64: c = (Target::c_longsize == 8 ? 'l' : 'x'); break;
|
||||
case Tuns64: c = (Target::c_longsize == 8 ? 'm' : 'y'); break;
|
||||
case Tfloat64: c = 'd'; break;
|
||||
case Tfloat80: c = (Target::realsize - Target::realpad == 16) ? 'g' : 'e'; break;
|
||||
case Tbool: c = 'b'; break;
|
||||
case Tchar: c = 'c'; break;
|
||||
case Twchar: c = 't'; break;
|
||||
case Tdchar: c = 'w'; break;
|
||||
case Twchar: c = 't'; break; // unsigned short
|
||||
case Tdchar: c = 'w'; break; // wchar_t (UTF-32)
|
||||
|
||||
case Timaginary32: p = 'G'; c = 'f'; break;
|
||||
case Timaginary64: p = 'G'; c = 'd'; break;
|
||||
|
@ -639,7 +769,42 @@ public:
|
|||
|
||||
void visit(TypeStruct *t)
|
||||
{
|
||||
Identifier *id = t->sym->ident;
|
||||
//printf("struct id = '%s'\n", id->toChars());
|
||||
char c;
|
||||
if (id == Id::__c_long)
|
||||
c = 'l';
|
||||
else if (id == Id::__c_ulong)
|
||||
c = 'm';
|
||||
else
|
||||
c = 0;
|
||||
if (c)
|
||||
{
|
||||
if (t->isImmutable() || t->isShared())
|
||||
{
|
||||
visit((Type *)t);
|
||||
}
|
||||
if (t->isConst())
|
||||
{
|
||||
if (substitute(t))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
store(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (t->isConst())
|
||||
buf.writeByte('K');
|
||||
|
||||
buf.writeByte(c);
|
||||
return;
|
||||
}
|
||||
|
||||
is_top_level = false;
|
||||
|
||||
if (substitute(t)) return;
|
||||
if (t->isImmutable() || t->isShared())
|
||||
{
|
||||
|
@ -650,8 +815,7 @@ public:
|
|||
|
||||
if (!substitute(t->sym))
|
||||
{
|
||||
cpp_mangle_name(t->sym);
|
||||
store(t->sym);
|
||||
cpp_mangle_name(t->sym, t->isConst());
|
||||
}
|
||||
|
||||
if (t->isImmutable() || t->isShared())
|
||||
|
@ -667,13 +831,13 @@ public:
|
|||
{
|
||||
is_top_level = false;
|
||||
if (substitute(t)) return;
|
||||
|
||||
if (t->isConst())
|
||||
buf.writeByte('K');
|
||||
|
||||
if (!substitute(t->sym))
|
||||
{
|
||||
cpp_mangle_name(t->sym);
|
||||
store(t->sym);
|
||||
cpp_mangle_name(t->sym, t->isConst());
|
||||
}
|
||||
|
||||
if (t->isImmutable() || t->isShared())
|
||||
|
@ -685,11 +849,6 @@ public:
|
|||
store(t);
|
||||
}
|
||||
|
||||
void visit(TypeTypedef *t)
|
||||
{
|
||||
visit((Type *)t);
|
||||
}
|
||||
|
||||
void visit(TypeClass *t)
|
||||
{
|
||||
if (substitute(t)) return;
|
||||
|
@ -701,12 +860,13 @@ public:
|
|||
buf.writeByte('K');
|
||||
is_top_level = false;
|
||||
buf.writeByte('P');
|
||||
|
||||
if (t->isConst())
|
||||
buf.writeByte('K');
|
||||
|
||||
if (!substitute(t->sym))
|
||||
{
|
||||
cpp_mangle_name(t->sym);
|
||||
store(t->sym);
|
||||
cpp_mangle_name(t->sym, t->isConst());
|
||||
}
|
||||
if (t->isConst())
|
||||
store(NULL);
|
||||
|
@ -716,6 +876,7 @@ public:
|
|||
|
||||
char *toCppMangle(Dsymbol *s)
|
||||
{
|
||||
//printf("toCppMangle(%s)\n", s->toChars());
|
||||
CppMangleVisitor v;
|
||||
return v.mangleOf(s);
|
||||
}
|
||||
|
@ -818,7 +979,7 @@ public:
|
|||
case Tfloat64: buf.writeByte('N'); break;
|
||||
case Tbool: buf.writestring("_N"); break;
|
||||
case Tchar: buf.writeByte('D'); break;
|
||||
case Twchar: buf.writeByte('G'); break; // unsigned short
|
||||
case Tdchar: buf.writeByte('I'); break; // unsigned int
|
||||
|
||||
case Tfloat80:
|
||||
if (flags & IS_DMC)
|
||||
|
@ -827,7 +988,7 @@ public:
|
|||
buf.writestring("_T"); // Intel long double
|
||||
break;
|
||||
|
||||
case Tdchar:
|
||||
case Twchar:
|
||||
if (flags & IS_DMC)
|
||||
buf.writestring("_Y"); // DigitalMars wchar_t
|
||||
else
|
||||
|
@ -981,14 +1142,44 @@ public:
|
|||
|
||||
void visit(TypeStruct *type)
|
||||
{
|
||||
if (checkTypeSaved(type)) return;
|
||||
//printf("visit(TypeStruct); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
|
||||
mangleModifier(type);
|
||||
if (type->sym->isUnionDeclaration())
|
||||
buf.writeByte('T');
|
||||
Identifier *id = type->sym->ident;
|
||||
char c;
|
||||
if (id == Id::__c_long_double)
|
||||
c = 'O'; // VC++ long double
|
||||
else if (id == Id::__c_long)
|
||||
c = 'J'; // VC++ long
|
||||
else if (id == Id::__c_ulong)
|
||||
c = 'K'; // VC++ unsigned long
|
||||
else
|
||||
buf.writeByte('U');
|
||||
mangleIdent(type->sym);
|
||||
c = 0;
|
||||
|
||||
if (c)
|
||||
{
|
||||
if (type->isImmutable() || type->isShared())
|
||||
{
|
||||
visit((Type*)type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type->isConst() && ((flags & IS_NOT_TOP_TYPE) || (flags & IS_DMC)))
|
||||
{
|
||||
if (checkTypeSaved(type)) return;
|
||||
}
|
||||
|
||||
mangleModifier(type);
|
||||
buf.writeByte(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (checkTypeSaved(type)) return;
|
||||
//printf("visit(TypeStruct); is_not_top_type = %d\n", (int)(flags & IS_NOT_TOP_TYPE));
|
||||
mangleModifier(type);
|
||||
if (type->sym->isUnionDeclaration())
|
||||
buf.writeByte('T');
|
||||
else
|
||||
buf.writeByte('U');
|
||||
mangleIdent(type->sym);
|
||||
}
|
||||
flags &= ~IS_NOT_TOP_TYPE;
|
||||
flags &= ~IGNORE_CONST;
|
||||
}
|
||||
|
@ -1096,7 +1287,7 @@ private:
|
|||
// Pivate methods always non-virtual in D and it should be mangled as non-virtual in C++
|
||||
if (d->isVirtual() && d->vtblIndex != -1)
|
||||
{
|
||||
switch (d->protection)
|
||||
switch (d->protection.kind)
|
||||
{
|
||||
case PROTprivate:
|
||||
buf.writeByte('E');
|
||||
|
@ -1111,7 +1302,7 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (d->protection)
|
||||
switch (d->protection.kind)
|
||||
{
|
||||
case PROTprivate:
|
||||
buf.writeByte('A');
|
||||
|
@ -1137,7 +1328,7 @@ private:
|
|||
}
|
||||
else if (d->isMember2()) // static function
|
||||
{ // <flags> ::= <virtual/protection flag> <calling convention flag>
|
||||
switch (d->protection)
|
||||
switch (d->protection.kind)
|
||||
{
|
||||
case PROTprivate:
|
||||
buf.writeByte('C');
|
||||
|
@ -1179,7 +1370,7 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (d->protection)
|
||||
switch (d->protection.kind)
|
||||
{
|
||||
case PROTprivate:
|
||||
buf.writeByte('0');
|
||||
|
@ -1608,8 +1799,14 @@ private:
|
|||
flags &= ~IGNORE_CONST;
|
||||
if (rettype->ty == Tstruct || rettype->ty == Tenum)
|
||||
{
|
||||
tmp.buf.writeByte('?');
|
||||
tmp.buf.writeByte('A');
|
||||
Identifier *id = rettype->toDsymbol(NULL)->ident;
|
||||
if (id != Id::__c_long_double &&
|
||||
id != Id::__c_long &&
|
||||
id != Id::__c_ulong)
|
||||
{
|
||||
tmp.buf.writeByte('?');
|
||||
tmp.buf.writeByte('A');
|
||||
}
|
||||
}
|
||||
tmp.flags |= MANGLE_RETURN_TYPE;
|
||||
rettype->accept(&tmp);
|
||||
|
@ -1673,7 +1870,7 @@ private:
|
|||
|
||||
char *toCppMangle(Dsymbol *s)
|
||||
{
|
||||
VisualCPPMangler v(!global.params.is64bit);
|
||||
VisualCPPMangler v(!global.params.mscoff);
|
||||
return v.mangleOf(s);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue