Mono.VisualC.Interop.ABI.MsvcAbi.GetMangledMethodName C# (CSharp) Method

GetMangledMethodName() protected method

protected GetMangledMethodName ( MethodInfo methodInfo ) : string
methodInfo System.Reflection.MethodInfo
return string
        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 ();
        }