protected override string GetMangledMethodName(MethodInfo methodInfo)
{
string methodName = methodInfo.Name;
MethodType methodType = GetMethodType (methodInfo);
ParameterInfo [] parameters = methodInfo.GetParameters ();
StringBuilder nm = new StringBuilder ("?", 30);
if (methodType == MethodType.NativeCtor)
nm.Append ("?0");
else if (methodType == MethodType.NativeDtor)
nm.Append ("?1");
else
nm.Append (methodName).Append ('@');
// FIXME: This has to include not only the name of the immediate containing class,
// but also all names of containing classes and namespaces up the hierarchy.
nm.Append (class_name).Append ("@@");
// function modifiers are a matrix of consecutive uppercase letters
// depending on access type and virtual (far)/static (far)/far modifiers
// first, access type
char funcModifier = 'Q'; // (public)
if (IsProtected (methodInfo))
funcModifier = 'I';
else if (IsPrivate (methodInfo)) // (probably don't need this)
funcModifier = 'A';
// now, offset based on other modifiers
if (IsStatic (methodInfo))
funcModifier += (char)2;
else if (IsVirtual (methodInfo))
funcModifier += (char)4;
nm.Append (funcModifier);
// FIXME: deal with other storage classes for "this" i.e. the "volatile" in -> int foo () volatile;
if (!IsStatic (methodInfo)) {
if (IsConst (methodInfo))
nm.Append ('B');
else
nm.Append ('A');
}
switch (GetCallingConvention (methodInfo)) {
case CallingConvention.Cdecl:
nm.Append ('A');
break;
case CallingConvention.ThisCall:
nm.Append ('E');
break;
case CallingConvention.StdCall:
nm.Append ('G');
break;
case CallingConvention.FastCall:
nm.Append ('I');
break;
}
// FIXME: handle const, volatile modifiers on return type
// FIXME: the manual says this is only omitted for simple types.. are we doing the right thing here?
CppType returnType = GetMangleType (methodInfo.ReturnTypeCustomAttributes, methodInfo.ReturnType);
if (returnType.ElementType == CppTypes.Class ||
returnType.ElementType == CppTypes.Struct ||
returnType.ElementType == CppTypes.Union)
nm.Append ("?A");
if (methodType == MethodType.NativeCtor || methodType == MethodType.NativeDtor)
nm.Append ('@');
else
nm.Append (GetTypeCode (returnType));
int argStart = (IsStatic (methodInfo)? 0 : 1);
if (parameters.Length == argStart) { // no args (other than C++ "this" object)
nm.Append ("XZ");
return nm.ToString ();
} else
for (int i = argStart; i < parameters.Length; i++)
nm.Append (GetTypeCode (GetMangleType (parameters [i], parameters [i].ParameterType)));
nm.Append ("@Z");
return nm.ToString ();
}