Tools and libraries to glue C/C++ APIs to high-level languages
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

118 lines
3.3 KiB

//
// Mono.VisualC.Interop.ABI.ItaniumAbi.cs: An implementation of the Itanium C++ ABI
//
// Author:
// Alexander Corrado (alexander.corrado@gmail.com)
//
// Copyright (C) 2010 Alexander Corrado
//
using System;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Mono.VisualC.Interop.Util;
namespace Mono.VisualC.Interop.ABI {
public class ItaniumAbi : CppAbi {
public ItaniumAbi ()
{
}
protected override CppTypeInfo MakeTypeInfo (IEnumerable<MethodInfo> virtualMethods)
{
return new ItaniumTypeInfo (this, virtualMethods, layout_type);
}
public override CallingConvention? GetCallingConvention (MethodInfo methodInfo)
{
return CallingConvention.Cdecl;
}
public override string GetMangledMethodName (MethodInfo methodInfo)
{
string methodName = methodInfo.Name;
MethodType methodType = GetMethodType (methodInfo);
ParameterInfo [] parameters = methodInfo.GetParameters ();
StringBuilder nm = new StringBuilder ("_ZN", 30);
nm.Append (class_name.Length).Append (class_name);
switch (methodType) {
case MethodType.NativeCtor:
nm.Append ("C1");
break;
case MethodType.NativeDtor:
nm.Append ("D1");
break;
default:
nm.Append (methodName.Length).Append (methodName);
break;
}
nm.Append ('E');
int argStart = (IsStatic (methodInfo)? 0 : 1);
if (parameters.Length == argStart) // no args (other than C++ "this" object)
nm.Append ('v');
else
for (int i = argStart; i < parameters.Length; i++)
nm.Append (GetTypeCode (GetMangleType (parameters [i], parameters [i].ParameterType)));
return nm.ToString ();
}
public virtual string GetTypeCode (CppType mangleType)
{
CppTypes element = mangleType.ElementType;
IEnumerable<CppModifiers> modifiers = mangleType.Modifiers;
StringBuilder code = new StringBuilder ();
var ptrOrRef = For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Reference);
var modifierCode = modifiers.Reverse ().Transform (
For.AnyInputIn (CppModifiers.Pointer, CppModifiers.Array).Emit ("P"),
For.AnyInputIn (CppModifiers.Reference).Emit ("R"),
// Itanium mangled names do not include const or volatile unless
// they modify the type pointed to by pointer or reference.
Choose.TopOne (
For.AllInputsIn (CppModifiers.Volatile, CppModifiers.Const).InAnyOrder ().After (ptrOrRef).Emit ("VK"),
For.AnyInputIn(CppModifiers.Volatile).After (ptrOrRef).Emit ("V"),
For.AnyInputIn(CppModifiers.Const).After (ptrOrRef).Emit ("K")
)
);
code.Append (string.Join(string.Empty, modifierCode.ToArray ()));
switch (element) {
case CppTypes.Int:
code.Append (modifiers.Transform (
For.AllInputsIn (CppModifiers.Unsigned, CppModifiers.Short).InAnyOrder ().Emit ('t')
).DefaultIfEmpty ('i').ToArray ());
break;
case CppTypes.Char:
code.Append ('c');
break;
case CppTypes.Class:
case CppTypes.Struct:
case CppTypes.Union:
case CppTypes.Enum:
code.Append(mangleType.ElementTypeName.Length);
code.Append(mangleType.ElementTypeName);
break;
}
return code.ToString ();
}
}
}