698 changes: 345 additions & 353 deletions src/cppmangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,442 +39,434 @@
* so nothing would be compatible anyway.
*/

struct CppMangleState
class CppMangleVisitor : public Visitor
{
static Objects components;

int substitute(OutBuffer *buf, RootObject *p);
int exist(RootObject *p);
void store(RootObject *p);
};

Objects CppMangleState::components;

Objects components;
OutBuffer buf;

void writeBase36(OutBuffer *buf, size_t i)
{
if (i >= 36)
void writeBase36(size_t i)
{
writeBase36(buf, i / 36);
i %= 36;
if (i >= 36)
{
writeBase36(i / 36);
i %= 36;
}
if (i < 10)
buf.writeByte((char)(i + '0'));
else if (i < 36)
buf.writeByte((char)(i - 10 + 'A'));
else
assert(0);
}
if (i < 10)
buf->writeByte((char)(i + '0'));
else if (i < 36)
buf->writeByte((char)(i - 10 + 'A'));
else
assert(0);
}

int CppMangleState::substitute(OutBuffer *buf, RootObject *p)
{
for (size_t i = 0; i < components.dim; i++)
int substitute(RootObject *p)
{
if (p == components[i])
for (size_t i = 0; i < components.dim; i++)
{
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
*/
buf->writeByte('S');
if (i)
writeBase36(buf, 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;
}
}
components.push(p);
return 0;
}
components.push(p);
return 0;
}

int CppMangleState::exist(RootObject *p)
{
for (size_t i = 0; i < components.dim; i++)
int exist(RootObject *p)
{
if (p == components[i])
for (size_t i = 0; i < components.dim; i++)
{
return 1;
if (p == components[i])
{
return 1;
}
}
return 0;
}
return 0;
}

void CppMangleState::store(RootObject *p)
{
components.push(p);
}
void store(RootObject *p)
{
components.push(p);
}

void source_name(OutBuffer *buf, Dsymbol *s)
{
char *name = s->ident->toChars();
buf->printf("%d%s", strlen(name), name);
}
void source_name(Dsymbol *s)
{
char *name = s->ident->toChars();
buf.printf("%d%s", strlen(name), name);
}

void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
if (!cms->substitute(buf, s))
void prefix_name(Dsymbol *s)
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
if (!substitute(s))
{
prefix_name(buf, cms, p);
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
prefix_name(p);
}
source_name(s);
}
source_name(buf, s);
}
}

void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
public:
CppMangleVisitor(const char *prefix)
: buf(), components()
{
buf->writeByte('N');
buf.writestring(prefix);
}

char *finish()
{
buf.writeByte(0);
return (char *)buf.extractData();
}

FuncDeclaration *fd = s->isFuncDeclaration();
VarDeclaration *vd = s->isVarDeclaration();
if (fd && fd->type->isConst())
void cpp_mangle_name(Dsymbol *s)
{
Dsymbol *p = s->toParent();
if (p && !p->isModule())
{
buf->writeByte('K');
buf.writeByte('N');

FuncDeclaration *fd = s->isFuncDeclaration();
VarDeclaration *vd = s->isVarDeclaration();
if (fd && fd->type->isConst())
{
buf.writeByte('K');
}
if (vd && !(vd->storage_class & (STCextern | STCgshared)))
{
s->error("C++ static non- __gshared non-extern variables not supported");
}
if (vd || fd)
{
prefix_name(p);
source_name(s);
}
else
{
assert(0);
}
buf.writeByte('E');
}
if (vd && !(vd->storage_class & (STCextern | STCgshared)))
{
s->error("C++ static non- __gshared non-extern variables not supported");
else
source_name(s);
}

void visit(Type *t)
{
/* Make this the 'vendor extended type' when there is no
* C++ analog.
* u <source-name>
*/
if (!substitute(t))
{ assert(t->deco);
buf.printf("u%d%s", strlen(t->deco), t->deco);
}
if (vd || fd)
}

void visit(TypeBasic *t)
{
/* ABI spec says:
* v void
* w wchar_t
* b bool
* c char
* a signed char
* h unsigned char
* s short
* t unsigned short
* i int
* j unsigned int
* l long
* m unsigned long
* x long long, __int64
* y unsigned long long, __int64
* n __int128
* o unsigned __int128
* f float
* d double
* e long double, __float80
* g __float128
* z ellipsis
* u <source-name> # vendor extended type
*/

char c;
char p = 0;
switch (t->ty)
{
prefix_name(buf, cms, p);
source_name(buf, s);
case Tvoid: c = 'v'; break;
case Tint8: c = 'a'; break;
case Tuns8: c = 'h'; break;
case Tint16: c = 's'; break;
case Tuns16: c = 't'; break;
case Tint32: c = 'i'; break;
case Tuns32: c = 'j'; break;
case Tfloat32: c = 'f'; break;
case Tint64: c = 'x'; break;
case Tuns64: c = 'y'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break;
case Tdchar: c = 'w'; break;

case Timaginary32: p = 'G'; c = 'f'; break;
case Timaginary64: p = 'G'; c = 'd'; break;
case Timaginary80: p = 'G'; c = 'e'; break;
case Tcomplex32: p = 'C'; c = 'f'; break;
case Tcomplex64: p = 'C'; c = 'd'; break;
case Tcomplex80: p = 'C'; c = 'e'; break;

default: assert(0);
}
else
if (p || t->isConst())
{
assert(0);
if (substitute(t))
return;
}
buf->writeByte('E');
}
else
source_name(buf, s);
}

if (t->isConst())
buf.writeByte('K');

char *cpp_mangle(Dsymbol *s)
{
/*
* <mangled-name> ::= _Z <encoding>
* <encoding> ::= <function name> <bare-function-type>
* ::= <data name>
* ::= <special-name>
*/

CppMangleState cms;
memset(&cms, 0, sizeof(cms));
cms.components.setDim(0);

OutBuffer buf;
buf.writestring(global.params.isOSX ? "__Z" : "_Z");

cpp_mangle_name(&buf, &cms, s);
if (p)
buf.writeByte(p);

FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ // add <bare-function-type>
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
Parameter::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
buf.writeByte(c);
}
buf.writeByte(0);
return (char *)buf.extractData();
}

/* ============= Type Encodings ============================================= */

void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
/* Make this the 'vendor extended type' when there is no
* C++ analog.
* u <source-name>
*/
if (!cms->substitute(buf, this))
{ assert(deco);
buf->printf("u%d%s", strlen(deco), deco);
void visit(TypeVector *t)
{
if (!substitute(t))
{
buf.writestring("U8__vector");
t->basetype->accept(this);
}
}
}

void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ char c;
char p = 0;

/* ABI spec says:
* v void
* w wchar_t
* b bool
* c char
* a signed char
* h unsigned char
* s short
* t unsigned short
* i int
* j unsigned int
* l long
* m unsigned long
* x long long, __int64
* y unsigned long long, __int64
* n __int128
* o unsigned __int128
* f float
* d double
* e long double, __float80
* g __float128
* z ellipsis
* u <source-name> # vendor extended type
*/

switch (ty)
void visit(TypeSArray *t)
{
case Tvoid: c = 'v'; break;
case Tint8: c = 'a'; break;
case Tuns8: c = 'h'; break;
case Tint16: c = 's'; break;
case Tuns16: c = 't'; break;
case Tint32: c = 'i'; break;
case Tuns32: c = 'j'; break;
case Tfloat32: c = 'f'; break;
case Tint64: c = 'x'; break;
case Tuns64: c = 'y'; break;
case Tfloat64: c = 'd'; break;
case Tfloat80: c = 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break;
case Tdchar: c = 'w'; break;

case Timaginary32: p = 'G'; c = 'f'; break;
case Timaginary64: p = 'G'; c = 'd'; break;
case Timaginary80: p = 'G'; c = 'e'; break;
case Tcomplex32: p = 'C'; c = 'f'; break;
case Tcomplex64: p = 'C'; c = 'd'; break;
case Tcomplex80: p = 'C'; c = 'e'; break;

default: assert(0);
if (!substitute(t))
{
buf.printf("A%llu_", t->dim ? t->dim->toInteger() : 0);
t->next->accept(this);
}
}
if (p || isConst())

void visit(TypeDArray *t)
{
if (cms->substitute(buf, this))
return;
visit((Type *)t);
}

if (isConst())
buf->writeByte('K');

if (p)
buf->writeByte(p);

buf->writeByte(c);
}


void TypeVector::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->writestring("U8__vector");
basetype->toCppMangle(buf, cms);
void visit(TypeAArray *t)
{
visit((Type *)t);
}
}

void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
{ buf->printf("A%llu_", dim ? dim->toInteger() : 0);
next->toCppMangle(buf, cms);
void visit(TypePointer *t)
{
if (!exist(t))
{
buf.writeByte('P');
t->next->accept(this);
store(t);
}
else
substitute(t);
}
}

void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}


void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}


void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->exist(this))
{ buf->writeByte('P');
next->toCppMangle(buf, cms);
cms->store(this);
void visit(TypeReference *t)
{
if (!exist(t))
{
buf.writeByte('R');
t->next->accept(this);
store(t);
}
else
substitute(t);
}
else
cms->substitute(buf, this);
}


void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->exist(this))
{ buf->writeByte('R');
next->toCppMangle(buf, cms);
cms->store(this);
void visit(TypeFunction *t)
{
/*
* <function-type> ::= F [Y] <bare-function-type> E
* <bare-function-type> ::= <signature type>+
* # types are possible return type, then parameter types
*/

/* ABI says:
"The type of a non-static member function is considered to be different,
for the purposes of substitution, from the type of a namespace-scope or
static member function whose type appears similar. The types of two
non-static member functions are considered to be different, for the
purposes of substitution, if the functions are members of different
classes. In other words, for the purposes of substitution, the class of
which the function is a member is considered part of the type of
function."
BUG: Right now, types of functions are never merged, so our simplistic
component matcher always finds them to be different.
We should use Type::equals on these, and use different
TypeFunctions for non-static member functions, and non-static
member functions of different classes.
*/
if (!exist(t))
{
buf.writeByte('F');
if (t->linkage == LINKc)
buf.writeByte('Y');
t->next->accept(this);
argsCppMangle(t->parameters, t->varargs);
buf.writeByte('E');
store(t);
}
else
substitute(t);
}
else
cms->substitute(buf, this);
}


void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{ /*
* <function-type> ::= F [Y] <bare-function-type> E
* <bare-function-type> ::= <signature type>+
* # types are possible return type, then parameter types
*/

/* ABI says:
"The type of a non-static member function is considered to be different,
for the purposes of substitution, from the type of a namespace-scope or
static member function whose type appears similar. The types of two
non-static member functions are considered to be different, for the
purposes of substitution, if the functions are members of different
classes. In other words, for the purposes of substitution, the class of
which the function is a member is considered part of the type of
function."
BUG: Right now, types of functions are never merged, so our simplistic
component matcher always finds them to be different.
We should use Type::equals on these, and use different
TypeFunctions for non-static member functions, and non-static
member functions of different classes.
*/
if (!cms->exist(this))
void visit(TypeDelegate *t)
{
buf->writeByte('F');
if (linkage == LINKc)
buf->writeByte('Y');
next->toCppMangle(buf, cms);
Parameter::argsCppMangle(buf, cms, parameters, varargs);
buf->writeByte('E');
cms->store(this);
visit((Type *)t);
}
else
cms->substitute(buf, this);
}

void visit(TypeStruct *t)
{
if (!exist(t))
{
if (t->isConst())
buf.writeByte('K');

void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}
if (!substitute(t->sym))
cpp_mangle_name(t->sym);

if (t->isConst())
store(t);
}
else
substitute(t);
}

void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->exist(this))
void visit(TypeEnum *t)
{
if (isConst())
buf->writeByte('K');
if (!exist(t))
{
if (t->isConst())
buf.writeByte('K');

if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
if (!substitute(t->sym))
cpp_mangle_name(t->sym);

if (isConst())
cms->store(this);
if (t->isConst())
store(t);
}
else
substitute(t);
}
else
cms->substitute(buf, this);
}

void visit(TypeTypedef *t)
{
visit((Type *)t);
}

void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->exist(this))
void visit(TypeClass *t)
{
if (isConst())
buf->writeByte('K');
if (!exist(t))
{
buf.writeByte('P');

if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
if (!substitute(t->sym))
cpp_mangle_name(t->sym);

if (isConst())
cms->store(this);
store(t);
}
else
substitute(t);
}
else
cms->substitute(buf, this);
}

struct ArgsCppMangleCtx
{
CppMangleVisitor *v;
size_t cnt;
};

void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
Type::toCppMangle(buf, cms);
}

void argsCppMangle(Parameters *arguments, int varargs)
{
size_t n = 0;
if (arguments)
{
ArgsCppMangleCtx ctx = { this, 0 };
Parameter::foreach(arguments, &argsCppMangleDg, &ctx);
n = ctx.cnt;
}
if (varargs)
buf.writestring("z");
else if (!n)
buf.writeByte('v'); // encode ( ) arguments
}

void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->exist(this))
static int argsCppMangleDg(void *ctx, size_t n, Parameter *arg)
{
buf->writeByte('P');
ArgsCppMangleCtx *p = (ArgsCppMangleCtx *)ctx;

Type *t = arg->type->merge2();
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
else if (arg->storageClass & STClazy)
{ // Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{ // Mangle static arrays as pointers
t = t->pointerTo();
}

if (!cms->substitute(buf, sym))
cpp_mangle_name(buf, cms, sym);
/* If it is a basic, enum or struct type,
* then don't mark it const
*/
if ((t->ty == Tenum || t->ty == Tstruct || t->isTypeBasic()) && t->isConst())
t->mutableOf()->accept(p->v);
else
t->accept(p->v);

cms->store(this);
p->cnt++;
return 0;
}
else
cms->substitute(buf, this);
}

struct ArgsCppMangleCtx
{
OutBuffer *buf;
CppMangleState *cms;
size_t cnt;
};

static int argsCppMangleDg(void *ctx, size_t n, Parameter *arg)
char *toCppMangle(Dsymbol *s)
{
ArgsCppMangleCtx *p = (ArgsCppMangleCtx *)ctx;

Type *t = arg->type->merge2();
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
else if (arg->storageClass & STClazy)
{ // Mangle as delegate
Type *td = new TypeFunction(NULL, t, 0, LINKd);
td = new TypeDelegate(td);
t = t->merge();
}
if (t->ty == Tsarray)
{ // Mangle static arrays as pointers
t = t->pointerTo();
}

/* If it is a basic, enum or struct type,
* then don't mark it const
/*
* <mangled-name> ::= _Z <encoding>
* <encoding> ::= <function name> <bare-function-type>
* ::= <data name>
* ::= <special-name>
*/
if ((t->ty == Tenum || t->ty == Tstruct || t->isTypeBasic()) && t->isConst())
t->mutableOf()->toCppMangle(p->buf, p->cms);
else
t->toCppMangle(p->buf, p->cms);

p->cnt++;
return 0;
}
CppMangleVisitor v(global.params.isOSX ? "__Z" : "_Z");

void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs)
{
size_t n = 0;
if (arguments)
{
ArgsCppMangleCtx ctx = { buf, cms, 0 };
foreach(arguments, &argsCppMangleDg, &ctx);
n = ctx.cnt;
v.cpp_mangle_name(s);

FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
{ // add <bare-function-type>
assert(fd->type->ty == Tfunction);
TypeFunction *tf = (TypeFunction *)fd->type;
v.argsCppMangle(tf->parameters, tf->varargs);
}
if (varargs)
buf->writestring("z");
else if (!n)
buf->writeByte('v'); // encode ( ) arguments
return v.finish();
}


#endif

4 changes: 2 additions & 2 deletions src/mangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "module.h"

#if CPP_MANGLE
char *cpp_mangle(Dsymbol *s);
char *toCppMangle(Dsymbol *s);
#endif

/******************************************************************************
Expand Down Expand Up @@ -146,7 +146,7 @@ const char *Declaration::mangle(bool isv)

case LINKcpp:
#if CPP_MANGLE
p = cpp_mangle(this);
p = toCppMangle(this);
#else
// Windows C++ mangling is done by C++ back end
p = ident->toChars();
Expand Down
45 changes: 0 additions & 45 deletions src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,6 @@ class Type : public RootObject
void modToBuffer(OutBuffer *buf);
char *modToChars();
virtual void toJson(JsonOut *json);
#if CPP_MANGLE
virtual void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
virtual bool isintegral();
virtual bool isfloating(); // real, imaginary, or complex
virtual bool isreal();
Expand Down Expand Up @@ -420,9 +417,6 @@ class TypeBasic : public Type
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
char *toChars();
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
bool isintegral();
bool isfloating();
bool isreal();
Expand Down Expand Up @@ -460,9 +454,6 @@ class TypeVector : public Type
void toJson(JsonOut *json);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL);
Type *reliesOnTident(TemplateParameters *tparams);
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
bool isintegral();
bool isfloating();
bool isscalar();
Expand Down Expand Up @@ -523,9 +514,6 @@ class TypeSArray : public TypeArray
int needsDestruction();
bool needsNested();
TypeTuple *toArgTypes();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
type *toCParamtype();
Expand Down Expand Up @@ -557,9 +545,6 @@ class TypeDArray : public TypeArray
TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers();
TypeTuple *toArgTypes();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
void accept(Visitor *v) { v->visit(this); }
Expand Down Expand Up @@ -596,9 +581,6 @@ class TypeAArray : public TypeArray
TypeTuple *toArgTypes();
MATCH implicitConvTo(Type *to);
MATCH constConv(Type *to);
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

// Back end
Symbol *aaGetSymbol(const char *func, int flags);
Expand All @@ -625,9 +607,6 @@ class TypePointer : public TypeNext
TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers();
TypeTuple *toArgTypes();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
void accept(Visitor *v) { v->visit(this); }
Expand All @@ -646,9 +625,6 @@ class TypeReference : public TypeNext
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
Expression *defaultInit(Loc loc);
int isZeroInit(Loc loc);
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
void accept(Visitor *v) { v->visit(this); }
};

Expand Down Expand Up @@ -709,9 +685,6 @@ class TypeFunction : public TypeNext
TypeInfoDeclaration *getTypeInfoDeclaration();
Type *reliesOnTident(TemplateParameters *tparams = NULL);
bool hasLazyParameters();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
bool parameterEscapes(Parameter *p);
Type *addStorageClass(StorageClass stc);

Expand Down Expand Up @@ -747,9 +720,6 @@ class TypeDelegate : public TypeNext
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident, int flag);
int hasPointers();
TypeTuple *toArgTypes();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
void accept(Visitor *v) { v->visit(this); }
Expand Down Expand Up @@ -897,9 +867,6 @@ class TypeStruct : public Type
MATCH constConv(Type *to);
unsigned deduceWild(Type *t, bool isRef);
Type *toHeadMutable();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
void accept(Visitor *v) { v->visit(this); }
Expand Down Expand Up @@ -945,9 +912,6 @@ class TypeEnum : public Type
int hasPointers();
TypeTuple *toArgTypes();
Type *nextOf();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
void accept(Visitor *v) { v->visit(this); }
Expand Down Expand Up @@ -996,9 +960,6 @@ class TypeTypedef : public Type
int hasPointers();
TypeTuple *toArgTypes();
int hasWild();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();
type *toCParamtype();
Expand Down Expand Up @@ -1037,9 +998,6 @@ class TypeClass : public Type
int hasPointers();
TypeTuple *toArgTypes();
int builtinTypeInfo();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif

type *toCtype();

Expand Down Expand Up @@ -1126,9 +1084,6 @@ class Parameter : public RootObject
int dyncast() { return DYNCAST_PARAMETER; } // kludge for template.isType()
static Parameters *arraySyntaxCopy(Parameters *args);
static char *argsTypesToChars(Parameters *args, int varargs);
#if CPP_MANGLE
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs);
#endif
static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *arguments, int varargs);
static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments);
static int isTPL(Parameters *arguments);
Expand Down