private string name;
private string signature;
private Hashtable vararg_sig_table;
- private BaseTypeRef ret_type;
+ private ParamDef ret_param;
private ArrayList param_list;
private ArrayList inst_list;
private ArrayList customattr_list;
private string pinvoke_name;
private PEAPI.PInvokeAttr pinvoke_attr;
private SourceMethod source;
- private PEAPI.NativeType ret_native_type;
private TypeDef type_def;
private GenericParameters gen_params;
+ private Location start;
public MethodDef (CodeGen codegen, PEAPI.MethAttr meth_attr,
PEAPI.CallConv call_conv, PEAPI.ImplAttr impl_attr,
this.call_conv = call_conv;
this.impl_attr = impl_attr;
this.name = name;
- this.ret_type = ret_type;
this.param_list = param_list;
this.type_def = type_def;
this.gen_params = gen_params;
+ this.ret_param = new ParamDef (PEAPI.ParamAttr.Default, "", ret_type);
+ this.start = (Location) start.Clone ();
inst_list = new ArrayList ();
label_table = new Hashtable ();
}
public BaseTypeRef RetType {
- get { return ret_type; }
+ get { return ret_param.Type; }
}
public PEAPI.CallConv CallConv {
get { return (meth_attr & PEAPI.MethAttr.Abstract) != 0; }
}
+ public Location StartLocation {
+ get { return start; }
+ }
+
+ public DeclSecurity DeclSecurity {
+ get {
+ if (decl_sec == null)
+ decl_sec = new DeclSecurity ();
+ return decl_sec;
+ }
+ }
+
+ public string FullName {
+ get {
+ if (type_def == null)
+ return Name;
+ return type_def.FullName + "." + Name;
+ }
+ }
+
public BaseTypeRef[] ParamTypeList () {
if (param_list == null)
return gen_params.GetGenericParamNum (id);
}
- public void AddParamDefaultValue (int index, PEAPI.Constant defval)
- {
- if (param_list [index] != null) {
- ((ParamDef)param_list [index]).AddDefaultValue (defval);
- }
- }
-
public void AddCustomAttribute (CustomAttr customattr)
{
if (customattr_list == null)
customattr_list.Add (customattr);
}
- public void AddPermissionSet (PEAPI.SecurityAction sec_action, PermissionSet ps)
- {
- if (decl_sec == null)
- decl_sec = new DeclSecurity ();
-
- decl_sec.AddPermissionSet (sec_action, ps);
- }
-
- public void AddPermission (PEAPI.SecurityAction sec_action, IPermission iper)
- {
- if (decl_sec == null)
- decl_sec = new DeclSecurity ();
-
- decl_sec.AddPermission (sec_action, iper);
- }
-
public void AddRetTypeMarshalInfo (PEAPI.NativeType native_type)
{
- this.ret_native_type = native_type;
+ this.ret_param.AddMarshalInfo (native_type);
}
public void AddLocals (ArrayList local_list)
public int GetNamedParamPos (string name)
{
int pos = -1;
+ if (param_list == null)
+ return -1;
+
if (!IsStatic)
pos ++;
foreach (ParamDef param in param_list) {
return pos;
}
+ /* index - 0: return type
+ * 1: params start from this
+ */
public ParamDef GetParam (int index)
{
+ if (index == 0)
+ return ret_param;
+
+ if ((param_list == null) || (index < 0) || (index > param_list.Count))
+ return null;
+
+ index --; /* param_list has params zero-based */
+
if (param_list [index] != null)
return (ParamDef)param_list [index];
else
if (gen_params != null)
gen_params.ResolveConstraints (type_params, gen_params);
- BaseGenericTypeRef gtr = ret_type as BaseGenericTypeRef;
+ BaseGenericTypeRef gtr = RetType as BaseGenericTypeRef;
if (gtr != null)
gtr.Resolve (type_params, gen_params);
PEAPI.Param [] param_array = GenerateParams (code_gen);
FixAttributes ();
- ret_type.Resolve (code_gen);
+ ret_param.Define (code_gen);
if (classdef == null)
methoddef = code_gen.PEFile.AddMethod (meth_attr, impl_attr,
- name, ret_type.PeapiType, param_array);
+ name, ret_param.PeapiParam, param_array);
else
methoddef = classdef.AddMethod (meth_attr, impl_attr,
- name, ret_type.PeapiType, param_array);
+ name, ret_param.PeapiParam, param_array);
methoddef.AddCallConv (call_conv);
- if (ret_native_type != null)
- methoddef.AddRetTypeMarshallInfo (ret_native_type);
-
is_resolved = true;
return methoddef;
if (gen_params != null)
gen_params.Resolve (code_gen, methoddef);
- if (IsAbstract)
- return;
+ if (type_def == null) {
+ //Global method
+ meth_attr &= ~PEAPI.MethAttr.Abstract;
+ meth_attr |= PEAPI.MethAttr.Static;
+ } else {
+ if ((inst_list.Count > 0) && type_def.IsInterface && !IsStatic)
+ Report.Error (start, "Method cannot have body if it is non-static declared in an interface");
+
+ if (IsAbstract) {
+ if (!type_def.IsAbstract)
+ Report.Error (start, String.Format ("Abstract method '{0}' in non-abstract class '{1}'",
+ Name, type_def.FullName));
+ if (inst_list.Count > 0)
+ Report.Error (start, "Method cannot have body if it is abstract.");
+ return;
+ }
+ }
if (entry_point)
methoddef.DeclareEntryPoint ();
(pinvoke_name != null ? pinvoke_name : name), pinvoke_attr);
}
- if (inst_list.Count < 1)
- return;
+ if ((impl_attr & PEAPI.ImplAttr.Runtime) == PEAPI.ImplAttr.Runtime) {
+ if (inst_list.Count > 0)
+ Report.Error (start, String.Format ("Method cannot have body if it is non-IL runtime-supplied, '{0}'",
+ FullName));
+ } else {
+ if (((impl_attr & PEAPI.ImplAttr.Native) != 0) ||
+ ((impl_attr & PEAPI.ImplAttr.Unmanaged) != 0))
+ Report.Error (start, String.Format ("Cannot compile native/unmanaged method, '{0}'",
+ FullName));
+ }
+
+ if (inst_list.Count > 0) {
+ /* Has body */
+ if ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0)
+ Report.Error (start, String.Format ("Method cannot have body if it is an internal call, '{0}'",
+ FullName));
+
+ if (pinvoke_info)
+ Report.Error (start, String.Format ("Method cannot have body if it is pinvoke, '{0}'",
+ FullName));
+ } else {
+ if (pinvoke_info ||
+ ((impl_attr & PEAPI.ImplAttr.Runtime) != 0) ||
+ ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0))
+ /* No body required */
+ return;
+
+ Report.Warning (start, "Method has no body, 'ret' emitted.");
+ AddInstr (new SimpInstr (PEAPI.Op.ret, start));
+ }
PEAPI.CILInstructions cil = methoddef.CreateCodeBuffer ();
/// Create all the labels