%{ // // Mono::ILASM::ILParser // // (C) Sergey Chaban (serge@wildwestsoftware.com) // (C) 2003 Jackson Harper, All rights reserved // using PEAPI; using System; using System.IO; using System.Collections; using System.Globalization; using System.Reflection; using System.Security; using System.Security.Permissions; using MIPermission = Mono.ILASM.Permission; using MIPermissionSet = Mono.ILASM.PermissionSet; namespace Mono.ILASM { public class ILParser { private CodeGen codegen; private bool is_value_class; private bool is_enum_class; private bool pinvoke_info; private string pinvoke_mod; private string pinvoke_meth; private PEAPI.PInvokeAttr pinvoke_attr; private ILTokenizer tokenizer; static int yacc_verbose_flag; class NameValuePair { public string Name; public object Value; public NameValuePair (string name, object value) { this.Name = name; this.Value = value; } } class PermPair { public PEAPI.SecurityAction sec_action; public object perm; public PermPair (PEAPI.SecurityAction sec_action, object perm) { this.sec_action = sec_action; this.perm = perm; } } public bool CheckSecurityActionValidity (System.Security.Permissions.SecurityAction action, bool for_assembly) { if ((action == System.Security.Permissions.SecurityAction.RequestMinimum || action == System.Security.Permissions.SecurityAction.RequestOptional || action == System.Security.Permissions.SecurityAction.RequestRefuse) && !for_assembly) { Report.Warning (String.Format ("System.Security.Permissions.SecurityAction '{0}' is not valid for this declaration", action)); return false; } return true; } public void AddSecDecl (object perm, bool for_assembly) { PermPair pp = perm as PermPair; if (pp == null) { MIPermissionSet ps_20 = (MIPermissionSet) perm; codegen.AddPermission (ps_20.SecurityAction, ps_20); return; } if (!CheckSecurityActionValidity ((System.Security.Permissions.SecurityAction) pp.sec_action, for_assembly)) Report.Error (String.Format ("Invalid security action : {0}", pp.sec_action)); codegen.AddPermission (pp.sec_action, pp.perm); } public object ClassRefToObject (object class_ref, object val) { ExternTypeRef etr = class_ref as ExternTypeRef; if (etr == null) /* FIXME: report error? can be PrimitiveTypeRef or TypeRef */ return null; System.Type t = etr.GetReflectedType (); return (t.IsEnum ? Enum.Parse (t, String.Format ("{0}", val)) : val); } /* Converts a type_spec to a corresponding PermPair */ PermPair TypeSpecToPermPair (object action, object type_spec, ArrayList pairs) { ExternTypeRef etr = type_spec as ExternTypeRef; if (etr == null) /* FIXME: could be PrimitiveTypeRef or TypeRef Report what error? */ return null; System.Type t = etr.GetReflectedType (); object obj = Activator.CreateInstance (t, new object [] {(System.Security.Permissions.SecurityAction) (short) action}); if (pairs != null) foreach (NameValuePair pair in pairs) { PropertyInfo pi = t.GetProperty (pair.Name); pi.SetValue (obj, pair.Value, null); } IPermission iper = (IPermission) t.GetMethod ("CreatePermission").Invoke (obj, null); return new PermPair ((PEAPI.SecurityAction) action, iper); } public ILParser (CodeGen codegen, ILTokenizer tokenizer) { this.codegen = codegen; this.tokenizer = tokenizer; } public CodeGen CodeGen { get { return codegen; } } private BaseTypeRef GetTypeRef (BaseTypeRef b) { if (b is BaseClassRef) return ((BaseClassRef) b).Clone (); return b; } %} %token EOF /* ID - alpha-numeric identifier */ %token ID /* QSTRING - quoted string */ %token QSTRING /* SQSTRING - single quoted string */ %token SQSTRING /* COMP_NAME - A name with dots */ %token COMP_NAME /* INT32 - 32 bit integer */ %token INT32 /* INT64 - 64 bit integer */ %token INT64 /* FLOAT64 - floating point number */ %token FLOAT64 /* HEXBYTE - two digit hex number */ %token HEXBYTE /* Punctuation */ %token DOT "." %token OPEN_BRACE "{" %token CLOSE_BRACE "}" %token OPEN_BRACKET "[" %token CLOSE_BRACKET "]" %token OPEN_PARENS "(" %token CLOSE_PARENS ")" %token COMMA "," %token COLON ":" %token DOUBLE_COLON "::" %token SEMICOLON ";" %token ASSIGN "=" %token STAR "*" %token AMPERSAND "&" %token PLUS "+" %token SLASH "/" %token BANG "!" %token ELLIPSIS "..." %token DASH "-" %token OPEN_ANGLE_BRACKET "<" %token CLOSE_ANGLE_BRACKET ">" %token UNKNOWN /* INSTR_* instruction types */ %token INSTR_NONE %token INSTR_VAR %token INSTR_I %token INSTR_I8 %token INSTR_R %token INSTR_BRTARGET %token INSTR_METHOD %token INSTR_NEWOBJ %token INSTR_FIELD %token INSTR_TYPE %token INSTR_STRING %token INSTR_SIG %token INSTR_RVA %token INSTR_TOK %token INSTR_SWITCH %token INSTR_PHI %token INSTR_LOCAL %token INSTR_PARAM /* Mechanically generated - DO NOT EDIT! */ /* Directives */ %token D_ADDON %token D_ALGORITHM %token D_ASSEMBLY %token D_BACKING %token D_BLOB %token D_CAPABILITY %token D_CCTOR %token D_CLASS %token D_COMTYPE %token D_CONFIG %token D_IMAGEBASE %token D_CORFLAGS %token D_CTOR %token D_CUSTOM %token D_DATA %token D_EMITBYTE %token D_ENTRYPOINT %token D_EVENT %token D_EXELOC %token D_EXPORT %token D_FIELD %token D_FILE %token D_FIRE %token D_GET %token D_HASH %token D_IMPLICITCOM %token D_LANGUAGE %token D_LINE %token D_XLINE %token D_LOCALE %token D_LOCALS %token D_MANIFESTRES %token D_MAXSTACK %token D_METHOD %token D_MIME %token D_MODULE %token D_MRESOURCE %token D_NAMESPACE %token D_ORIGINATOR %token D_OS %token D_OTHER %token D_OVERRIDE %token D_PACK %token D_PARAM %token D_PERMISSION %token D_PERMISSIONSET %token D_PROCESSOR %token D_PROPERTY %token D_PUBLICKEY %token D_PUBLICKEYTOKEN %token D_REMOVEON %token D_SET %token D_SIZE %token D_STACKRESERVE %token D_SUBSYSTEM %token D_TITLE %token D_TRY %token D_VER %token D_VTABLE %token D_VTENTRY %token D_VTFIXUP %token D_ZEROINIT /* Keywords */ %token K_AT %token K_AS %token K_IMPLICITCOM %token K_IMPLICITRES %token K_NOAPPDOMAIN %token K_NOPROCESS %token K_NOMACHINE %token K_EXTERN %token K_INSTANCE %token K_EXPLICIT %token K_DEFAULT %token K_VARARG %token K_UNMANAGED %token K_CDECL %token K_STDCALL %token K_THISCALL %token K_FASTCALL %token K_MARSHAL %token K_IN %token K_OUT %token K_OPT // %token K_LCID %token K_RETVAL %token K_STATIC %token K_PUBLIC %token K_PRIVATE %token K_FAMILY %token K_INITONLY %token K_RTSPECIALNAME %token K_SPECIALNAME %token K_ASSEMBLY %token K_FAMANDASSEM %token K_FAMORASSEM %token K_PRIVATESCOPE %token K_LITERAL %token K_NOTSERIALIZED %token K_VALUE %token K_NOT_IN_GC_HEAP %token K_INTERFACE %token K_SEALED %token K_ABSTRACT %token K_AUTO %token K_SEQUENTIAL %token K_ANSI %token K_UNICODE %token K_AUTOCHAR %token K_BESTFIT %token K_IMPORT %token K_SERIALIZABLE %token K_NESTED %token K_LATEINIT %token K_EXTENDS %token K_IMPLEMENTS %token K_FINAL %token K_VIRTUAL %token K_HIDEBYSIG %token K_NEWSLOT %token K_UNMANAGEDEXP %token K_PINVOKEIMPL %token K_NOMANGLE %token K_OLE %token K_LASTERR %token K_WINAPI %token K_NATIVE %token K_IL %token K_CIL %token K_OPTIL %token K_MANAGED %token K_FORWARDREF %token K_RUNTIME %token K_INTERNALCALL %token K_SYNCHRONIZED %token K_NOINLINING %token K_CUSTOM %token K_FIXED %token K_SYSSTRING %token K_ARRAY %token K_VARIANT %token K_CURRENCY %token K_SYSCHAR %token K_VOID %token K_BOOL %token K_INT8 %token K_INT16 %token K_INT32 %token K_INT64 %token K_FLOAT32 %token K_FLOAT64 %token K_ERROR %token K_UNSIGNED %token K_UINT %token K_UINT8 %token K_UINT16 %token K_UINT32 %token K_UINT64 %token K_DECIMAL %token K_DATE %token K_BSTR %token K_LPSTR %token K_LPWSTR %token K_LPTSTR %token K_OBJECTREF %token K_IUNKNOWN %token K_IDISPATCH %token K_STRUCT %token K_SAFEARRAY %token K_INT %token K_BYVALSTR %token K_TBSTR %token K_LPVOID %token K_ANY %token K_FLOAT %token K_LPSTRUCT %token K_NULL %token K_PTR %token K_VECTOR %token K_HRESULT %token K_CARRAY %token K_USERDEFINED %token K_RECORD %token K_FILETIME %token K_BLOB %token K_STREAM %token K_STORAGE %token K_STREAMED_OBJECT %token K_STORED_OBJECT %token K_BLOB_OBJECT %token K_CF %token K_CLSID %token K_METHOD %token K_CLASS %token K_PINNED %token K_MODREQ %token K_MODOPT %token K_TYPEDREF %token K_TYPE %token K_WCHAR %token K_CHAR %token K_FROMUNMANAGED %token K_CALLMOSTDERIVED %token K_BYTEARRAY %token K_WITH %token K_INIT %token K_TO %token K_CATCH %token K_FILTER %token K_FINALLY %token K_FAULT %token K_HANDLER %token K_TLS %token K_FIELD %token K_PROPERTY %token K_REQUEST %token K_DEMAND %token K_ASSERT %token K_DENY %token K_PERMITONLY %token K_LINKCHECK %token K_INHERITCHECK %token K_REQMIN %token K_REQOPT %token K_REQREFUSE %token K_PREJITGRANT %token K_PREJITDENY %token K_NONCASDEMAND %token K_NONCASLINKDEMAND %token K_NONCASINHERITANCE %token K_READONLY %token K_NOMETADATA %token K_ALGORITHM %token K_FULLORIGIN // %token K_NAN // %token K_INF // %token K_PUBLICKEY %token K_ENABLEJITTRACKING %token K_DISABLEJITOPTIMIZER %token K_RETARGETABLE %token K_PRESERVESIG %token K_BEFOREFIELDINIT %token K_ALIGNMENT %token K_NULLREF %token K_VALUETYPE %token K_COMPILERCONTROLLED %token K_REQSECOBJ %token K_ENUM %token K_OBJECT %token K_STRING %token K_TRUE %token K_FALSE %token K_IS %token K_ON %token K_OFF %token K_CHARMAPERROR /* end generated */ %start il_file %% il_file : decls ; decls : /* EMPTY */ | decls decl ; decl : class_all | namespace_all | method_all | field_decl | data_decl | vtfixup_decl | file_decl | assembly_all | assemblyref_all | exptype_all | manifestres_all | module_head | sec_decl | customattr_decl { if (codegen.CurrentCustomAttrTarget != null) codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1); } | D_SUBSYSTEM int32 { codegen.SetSubSystem ((int) $2); } | D_CORFLAGS int32 { codegen.SetCorFlags ((int) $2); } | D_FILE K_ALIGNMENT int32 | D_IMAGEBASE int64 { codegen.SetImageBase ((long) $2); } | D_STACKRESERVE int64 { codegen.SetStackReserve ((long) $2); } | extsource_spec | language_decl ; extsource_spec : D_LINE int32 SQSTRING | D_LINE int32 | D_LINE int32 COLON int32 SQSTRING | D_LINE int32 COLON int32 ; language_decl : D_LANGUAGE SQSTRING | D_LANGUAGE SQSTRING COMMA SQSTRING | D_LANGUAGE SQSTRING COMMA SQSTRING COMMA SQSTRING ; vtfixup_decl : D_VTFIXUP OPEN_BRACKET int32 CLOSE_BRACKET vtfixup_attr K_AT id ; vtfixup_attr : /* EMPTY */ | vtfixup_attr K_INT32 | vtfixup_attr K_INT64 | vtfixup_attr K_FROMUNMANAGED | vtfixup_attr K_CALLMOSTDERIVED ; namespace_all : namespace_head OPEN_BRACE decls CLOSE_BRACE { codegen.CurrentNameSpace = null; } ; namespace_head : D_NAMESPACE comp_name { codegen.CurrentNameSpace = (string) $2; } ; class_all : class_head OPEN_BRACE class_decls CLOSE_BRACE { codegen.EndTypeDef (); } ; class_head : D_CLASS class_attr comp_name formal_typars_clause extends_clause impl_clause { codegen.BeginTypeDef ((TypeAttr) $2, (string) $3, $5 as BaseClassRef, $6 as ArrayList, null, (GenericParameters) $4); if (is_value_class) codegen.CurrentTypeDef.MakeValueClass (); if (is_enum_class) codegen.CurrentTypeDef.MakeEnumClass (); } ; class_attrs : class_attrs class_attr ; class_attr : /* EMPTY */ { // Reset some flags is_value_class = false; is_enum_class = false; $$ = new TypeAttr (); } | class_attr K_PUBLIC { $$ = (TypeAttr)$1 | TypeAttr.Public; } | class_attr K_PRIVATE { $$ = (TypeAttr)$1 | TypeAttr.Private; } | class_attr K_NESTED K_PRIVATE { $$ = (TypeAttr)$1 | TypeAttr.NestedPrivate; } | class_attr K_NESTED K_PUBLIC { $$ = (TypeAttr)$1 | TypeAttr.NestedPublic; } | class_attr K_NESTED K_FAMILY { $$ = (TypeAttr)$1 | TypeAttr.NestedFamily; } | class_attr K_NESTED K_ASSEMBLY { $$ = (TypeAttr)$1 | TypeAttr.NestedAssembly;} | class_attr K_NESTED K_FAMANDASSEM { $$ = (TypeAttr)$1 | TypeAttr.NestedFamAndAssem; } | class_attr K_NESTED K_FAMORASSEM { $$ = (TypeAttr)$1 | TypeAttr.NestedFamOrAssem; } | class_attr K_VALUE { is_value_class = true; } | class_attr K_ENUM { is_enum_class = true; is_value_class = true; } | class_attr K_INTERFACE { $$ = (TypeAttr)$1 | TypeAttr.Interface; } | class_attr K_SEALED { $$ = (TypeAttr)$1 | TypeAttr.Sealed; } | class_attr K_ABSTRACT { $$ = (TypeAttr)$1 | TypeAttr.Abstract; } | class_attr K_AUTO { } | class_attr K_SEQUENTIAL { $$ = (TypeAttr)$1 | TypeAttr.SequentialLayout; } | class_attr K_EXPLICIT { $$ = (TypeAttr)$1 | TypeAttr.ExplicitLayout; } | class_attr K_ANSI { } | class_attr K_UNICODE { $$ = (TypeAttr)$1 | TypeAttr.UnicodeClass; } | class_attr K_AUTOCHAR { $$ = (TypeAttr)$1 | TypeAttr.AutoClass; } | class_attr K_IMPORT { $$ = (TypeAttr)$1 | TypeAttr.Import; } | class_attr K_SERIALIZABLE { $$ = (TypeAttr)$1 | TypeAttr.Serializable; } | class_attr K_BEFOREFIELDINIT { $$ = (TypeAttr)$1 | TypeAttr.BeforeFieldInit; } | class_attr K_SPECIALNAME { $$ = (TypeAttr)$1 | TypeAttr.SpecialName; } | class_attr K_RTSPECIALNAME { $$ = (TypeAttr)$1 | TypeAttr.RTSpecialName; } ; extends_clause : /* EMPTY */ | K_EXTENDS generic_class_ref { $$ = $2; } ; impl_clause : /* EMPTY */ | impl_class_refs ; impl_class_refs : K_IMPLEMENTS generic_class_ref { ArrayList al = new ArrayList (); al.Add ($2); $$ = al; } | impl_class_refs COMMA generic_class_ref { ArrayList al = (ArrayList) $1; al.Insert (0, $3); $$ = al; } ; formal_typars_clause : /* EMPTY */ | OPEN_ANGLE_BRACKET formal_typars CLOSE_ANGLE_BRACKET { #if NET_2_0 || BOOTSTRAP_NET_2_0 $$ = $2; #else Report.Error ("Use ilasm2 for generics support."); #endif } ; typars_clause : /* EMPTY */ | OPEN_ANGLE_BRACKET typars CLOSE_ANGLE_BRACKET { #if NET_2_0 || BOOTSTRAP_NET_2_0 $$ = $2; #else Report.Error ("Use ilasm2 for generics support."); #endif } ; typars : type { GenericArguments ga = new GenericArguments (); ga.Add ((BaseTypeRef) $1); $$ = ga; } | typars COMMA type { ((GenericArguments) $1).Add ((BaseTypeRef) $3); $$ = $1; } ; constraints_clause : /* EMTPY */ | OPEN_PARENS constraints CLOSE_PARENS { $$ = $2; } ; constraints : generic_class_ref { ArrayList al = new ArrayList (); al.Add ($1); $$ = al; } | constraints COMMA generic_class_ref { ArrayList al = (ArrayList) $1; al.Add ($3); $$ = al; } ; generic_class_ref : class_ref { $$ = $1; } | K_CLASS class_ref typars_clause { if ($3 != null) $$ = ((BaseClassRef) $2).GetGenericTypeInst ((GenericArguments) $3); else $$ = $2; } | BANG int32 { GenParam gpar = new GenParam ((int) $2, "", GenParamType.Var); $$ = new GenericParamRef (gpar, $2.ToString ()); } | BANG BANG int32 { GenParam gpar = new GenParam ((int) $3, "", GenParamType.MVar); $$ = new GenericParamRef (gpar, $3.ToString ()); } | BANG id { int num = -1; string name = (string) $2; if (codegen.CurrentTypeDef != null) num = codegen.CurrentTypeDef.GetGenericParamNum (name); GenParam gpar = new GenParam (num, name, GenParamType.Var); $$ = new GenericParamRef (gpar, name); } | BANG BANG id { int num = -1; string name = (string) $3; if (codegen.CurrentMethodDef != null) num = codegen.CurrentMethodDef.GetGenericParamNum (name); GenParam gpar = new GenParam (num, name, GenParamType.MVar); $$ = new GenericParamRef (gpar, name); } ; formal_typars : formal_typar_attr constraints_clause formal_typar { GenericParameter gp = new GenericParameter ((string) $3, (PEAPI.GenericParamAttributes) $1, (ArrayList) $2); GenericParameters colln = new GenericParameters (); colln.Add (gp); $$ = colln; } | formal_typars COMMA formal_typar_attr constraints_clause formal_typar { GenericParameters colln = (GenericParameters) $1; colln.Add (new GenericParameter ((string) $5, (PEAPI.GenericParamAttributes) $3, (ArrayList) $4)); $$ = colln; } ; formal_typar_attr : /* EMPTY */ { $$ = new PEAPI.GenericParamAttributes (); } | formal_typar_attr D_CTOR { $$ = (PEAPI.GenericParamAttributes) $1 | PEAPI.GenericParamAttributes.DefaultConstructorConstrait; } | formal_typar_attr K_VALUETYPE { $$ = (PEAPI.GenericParamAttributes) $1 | PEAPI.GenericParamAttributes.NotNullableValueTypeConstraint; } | formal_typar_attr K_CLASS { $$ = (PEAPI.GenericParamAttributes) $1 | PEAPI.GenericParamAttributes.ReferenceTypeConstraint; } ; formal_typar : id { $$ = $1; } ; param_type_decl : D_PARAM K_TYPE id { if (codegen.CurrentMethodDef != null) codegen.CurrentCustomAttrTarget = codegen.CurrentMethodDef.GetGenericParam ((string) $3); else codegen.CurrentCustomAttrTarget = codegen.CurrentTypeDef.GetGenericParam ((string) $3); if (codegen.CurrentCustomAttrTarget == null) Report.Error (String.Format ("Type parameter '{0}' undefined.", (string) $3)); } | D_PARAM K_TYPE OPEN_BRACKET int32 CLOSE_BRACKET { int index = ((int) $4); if (codegen.CurrentMethodDef != null) codegen.CurrentCustomAttrTarget = codegen.CurrentMethodDef.GetGenericParam (index - 1); else codegen.CurrentCustomAttrTarget = codegen.CurrentTypeDef.GetGenericParam (index - 1); if (codegen.CurrentCustomAttrTarget == null) Report.Error (String.Format ("Type parameter '{0}' index out of range.", index)); } ; class_refs : class_ref { ArrayList class_list = new ArrayList (); class_list.Add ($1); $$ = class_list; } | class_refs COMMA class_ref { ArrayList class_list = (ArrayList) $1; class_list.Add ($3); } ; slashed_name : comp_name | slashed_name SLASH comp_name { $$ = String.Format ("{0}/{1}", $1, $3); } ; class_ref : OPEN_BRACKET slashed_name CLOSE_BRACKET slashed_name { if (codegen.IsThisAssembly ((string) $2)) { $$ = codegen.GetTypeRef ((string) $4); } else { $$ = codegen.ExternTable.GetTypeRef ((string) $2, (string) $4, false); } } | OPEN_BRACKET D_MODULE slashed_name CLOSE_BRACKET slashed_name { if (codegen.IsThisModule ((string) $3)) { $$ = codegen.GetTypeRef ((string) $5); } else { $$ = codegen.ExternTable.GetModuleTypeRef ((string) $3, (string) $5, false); } } | slashed_name { PrimitiveTypeRef prim = PrimitiveTypeRef.GetPrimitiveType ((string) $1); if (prim != null && !codegen.IsThisAssembly ("mscorlib")) $$ = prim; else $$ = codegen.GetTypeRef ((string) $1); } ; class_decls : /* EMPTY */ | class_decls class_decl ; class_decl : method_all | class_all | event_all | prop_all | field_decl | data_decl | sec_decl { AddSecDecl ($1, false); } | extsource_spec | customattr_decl { if (codegen.CurrentCustomAttrTarget != null) codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1); } | param_type_decl | D_SIZE int32 { codegen.CurrentTypeDef.SetSize ((int) $2); } | D_PACK int32 { codegen.CurrentTypeDef.SetPack ((int) $2); } | D_OVERRIDE type_spec DOUBLE_COLON method_name K_WITH call_conv type type_spec DOUBLE_COLON method_name type_list { // // My copy of the spec didn't have a type_list but // it seems pretty crucial // BaseTypeRef owner = (BaseTypeRef) $2; ArrayList arg_list = (ArrayList) $11; BaseTypeRef[] param_list; BaseMethodRef decl; if (arg_list != null) param_list = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); else param_list = new BaseTypeRef[0]; decl = owner.GetMethodRef ((BaseTypeRef) $7, (CallConv) $6, (string) $4, param_list, 0); // NOTICE: `owner' here might be wrong string sig = MethodDef.CreateSignature (owner, (string) $10, param_list, 0); codegen.CurrentTypeDef.AddOverride (sig, decl); } OPEN_PARENS sig_args CLOSE_PARENS | language_decl ; type : generic_class_ref { $$ = $1; } | K_OBJECT { $$ = new PrimitiveTypeRef (PrimitiveType.Object, "System.Object"); } | K_VALUE K_CLASS class_ref { BaseClassRef class_ref = (BaseClassRef) $3; class_ref.MakeValueClass (); $$ = class_ref; } | K_VALUETYPE OPEN_BRACKET slashed_name CLOSE_BRACKET slashed_name typars_clause { ExternTypeRef ext_ref = codegen.ExternTable.GetTypeRef ((string) $3, (string) $5, true); if ($6 != null) $$ = ext_ref.GetGenericTypeInst ((GenericArguments) $6); else $$ = ext_ref; } | K_VALUETYPE slashed_name typars_clause { TypeRef t_ref = codegen.GetTypeRef ((string) $2); t_ref.MakeValueClass (); if ($3 != null) $$ = t_ref.GetGenericTypeInst ((GenericArguments) $3); else $$ = t_ref; } | type OPEN_BRACKET CLOSE_BRACKET { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); base_type.MakeArray (); $$ = base_type; } | type OPEN_BRACKET bounds CLOSE_BRACKET { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); ArrayList bound_list = (ArrayList) $3; base_type.MakeBoundArray (bound_list); $$ = base_type; } | type AMPERSAND { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); base_type.MakeManagedPointer (); $$ = base_type; } | type STAR { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); base_type.MakeUnmanagedPointer (); $$ = base_type; } | type K_PINNED { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); base_type.MakePinned (); $$ = base_type; } | type K_MODREQ OPEN_PARENS class_ref CLOSE_PARENS { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); BaseClassRef class_ref = (BaseClassRef) $4; base_type.MakeCustomModified (codegen, CustomModifier.modreq, class_ref); $$ = base_type; } | type K_MODOPT OPEN_PARENS class_ref CLOSE_PARENS { BaseTypeRef base_type = GetTypeRef ((BaseTypeRef) $1); BaseClassRef class_ref = (BaseClassRef) $4; base_type.MakeCustomModified (codegen, CustomModifier.modopt, class_ref); $$ = base_type; } | K_METHOD call_conv type STAR OPEN_PARENS sig_args CLOSE_PARENS { $$ = new MethodPointerTypeRef ((CallConv) $2, (BaseTypeRef) $3, (ArrayList) $6); } | primitive_type ; ; primitive_type : K_INT8 { $$ = new PrimitiveTypeRef (PrimitiveType.Int8, "System.SByte"); } | K_INT16 { $$ = new PrimitiveTypeRef (PrimitiveType.Int16, "System.Int16"); } | K_INT32 { $$ = new PrimitiveTypeRef (PrimitiveType.Int32, "System.Int32"); } | K_INT64 { $$ = new PrimitiveTypeRef (PrimitiveType.Int64, "System.Int64"); } | K_FLOAT32 { $$ = new PrimitiveTypeRef (PrimitiveType.Float32, "System.Single"); } | K_FLOAT64 { $$ = new PrimitiveTypeRef (PrimitiveType.Float64, "System.Double"); } | K_UNSIGNED K_INT8 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt8, "System.Byte"); } | K_UINT8 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt8, "System.Byte"); } | K_UNSIGNED K_INT16 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt16, "System.UInt16"); } | K_UINT16 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt16, "System.UInt16"); } | K_UNSIGNED K_INT32 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt32, "System.UInt32"); } | K_UINT32 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt32, "System.UInt32"); } | K_UNSIGNED K_INT64 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt64, "System.UInt64"); } | K_UINT64 { $$ = new PrimitiveTypeRef (PrimitiveType.UInt64, "System.UInt64"); } | K_NATIVE K_INT { // TODO: Is this the proper full name $$ = new PrimitiveTypeRef (PrimitiveType.NativeInt, "System.IntPtr"); } | K_NATIVE K_UNSIGNED K_INT { $$ = new PrimitiveTypeRef (PrimitiveType.NativeUInt, "System.UIntPtr"); } | K_NATIVE K_UINT { $$ = new PrimitiveTypeRef (PrimitiveType.NativeUInt, "System.UIntPtr"); } | K_TYPEDREF { $$ = new PrimitiveTypeRef (PrimitiveType.TypedRef, "System.TypedReference"); } | K_CHAR { $$ = new PrimitiveTypeRef (PrimitiveType.Char, "System.Char"); } | K_WCHAR { $$ = new PrimitiveTypeRef (PrimitiveType.Char, "System.Char"); } | K_VOID { $$ = new PrimitiveTypeRef (PrimitiveType.Void, "System.Void"); } | K_BOOL { $$ = new PrimitiveTypeRef (PrimitiveType.Boolean, "System.Boolean"); } | K_STRING { $$ = new PrimitiveTypeRef (PrimitiveType.String, "System.String"); } ; bounds : bound { ArrayList bound_list = new ArrayList (); bound_list.Add ($1); $$ = bound_list; } | bounds COMMA bound { ArrayList bound_list = (ArrayList) $1; bound_list.Add ($3); } ; bound : /* EMPTY */ { // This is shortref for no lowerbound or size $$ = new DictionaryEntry (TypeRef.Ellipsis, TypeRef.Ellipsis); } | ELLIPSIS { // No lower bound or size $$ = new DictionaryEntry (TypeRef.Ellipsis, TypeRef.Ellipsis); } | int32 { /* Only size specified */ int size = (int) $1; if (size < 0) /* size cannot be < 0, so emit as (0, ...) ilasm.net emits it like this */ $$ = new DictionaryEntry (0, TypeRef.Ellipsis); else $$ = new DictionaryEntry (TypeRef.Ellipsis, size); } | int32 ELLIPSIS int32 { // lower and upper bound int lower = (int) $1; int upper = (int) $3; if (lower > upper) Report.Error ("Lower bound " + lower + " must be <= upper bound " + upper); $$ = new DictionaryEntry ($1, $3); } | int32 ELLIPSIS { // Just lower bound $$ = new DictionaryEntry ($1, TypeRef.Ellipsis); } ; call_conv : K_INSTANCE call_conv { $$ = (CallConv) $2 | CallConv.Instance; } | K_EXPLICIT call_conv { $$ = (CallConv) $2 | CallConv.InstanceExplicit; } | call_kind ; call_kind : /* EMPTY */ { $$ = new CallConv (); } | K_DEFAULT { $$ = CallConv.Default; } | K_VARARG { $$ = CallConv.Vararg; } | K_UNMANAGED K_CDECL { $$ = CallConv.Cdecl; } | K_UNMANAGED K_STDCALL { $$ = CallConv.Stdcall; } | K_UNMANAGED K_THISCALL { $$ = CallConv.Thiscall; } | K_UNMANAGED K_FASTCALL { $$ = CallConv.Fastcall; } ; native_type : /* EMPTY */ | K_CUSTOM OPEN_PARENS comp_qstring COMMA comp_qstring CLOSE_PARENS { $$ = new CustomMarshaller ((string) $3, (string) $5); } | K_FIXED K_SYSSTRING OPEN_BRACKET int32 CLOSE_BRACKET { $$ = new FixedSysString ((uint) (int)$4); } | K_FIXED K_ARRAY OPEN_BRACKET int32 CLOSE_BRACKET { $$ = new FixedArray ((int) $4); } | K_VARIANT | K_CURRENCY { $$ = NativeType.Currency; } | K_SYSCHAR | K_VOID { $$ = NativeType.Void; } | K_BOOL { $$ = NativeType.Boolean; } | K_INT8 { $$ = NativeType.Int8; } | K_INT16 { $$ = NativeType.Int16; } | K_INT32 { $$ = NativeType.Int32; } | K_INT64 { $$ = NativeType.Int64; } | K_FLOAT32 { $$ = NativeType.Float32; } | K_FLOAT64 { $$ = NativeType.Float64; } | K_ERROR { $$ = NativeType.Error; } | K_UNSIGNED K_INT8 { $$ = NativeType.UInt8; } | K_UINT8 { $$ = NativeType.UInt8; } | K_UNSIGNED K_INT16 { $$ = NativeType.UInt16; } | K_UINT16 { $$ = NativeType.UInt16; } | K_UNSIGNED K_INT32 { $$ = NativeType.UInt32; } | K_UINT32 { $$ = NativeType.UInt32; } | K_UNSIGNED K_INT64 { $$ = NativeType.UInt64; } | K_UINT64 { $$ = NativeType.UInt64; } | native_type STAR | native_type OPEN_BRACKET CLOSE_BRACKET { $$ = new NativeArray ((NativeType) $1); } | native_type OPEN_BRACKET int32 CLOSE_BRACKET { $$ = new NativeArray ((NativeType) $1, (int) $3, 0, 0); } | native_type OPEN_BRACKET int32 PLUS int32 CLOSE_BRACKET { //FIXME: Allowed only for methods, !fields $$ = new NativeArray ((NativeType) $1, (int) $3, (int) $5); } | native_type OPEN_BRACKET PLUS int32 CLOSE_BRACKET { //FIXME: Allowed only for methods, !fields $$ = new NativeArray ((NativeType) $1, -1, (int) $4); } | K_DECIMAL | K_DATE | K_BSTR { $$ = NativeType.BStr; } | K_LPSTR { $$ = NativeType.LPStr; } | K_LPWSTR { $$ = NativeType.LPWStr; } | K_LPTSTR { $$ = NativeType.LPTStr; } | K_OBJECTREF | K_IUNKNOWN { $$ = NativeType.IUnknown; } | K_IDISPATCH { $$ = NativeType.IDispatch; } | K_STRUCT { $$ = NativeType.Struct; } | K_INTERFACE { $$ = NativeType.Interface; } | K_SAFEARRAY variant_type { if ($2 == null) $$ = new SafeArray (); else $$ = new SafeArray ((SafeArrayType) $2); } | K_SAFEARRAY variant_type COMMA comp_qstring | K_INT { $$ = NativeType.Int; } | K_UNSIGNED K_INT { $$ = NativeType.UInt; } | K_NESTED K_STRUCT | K_BYVALSTR { $$ = NativeType.ByValStr; } | K_ANSI K_BSTR { $$ = NativeType.AnsiBStr; } | K_TBSTR { $$ = NativeType.TBstr; } | K_VARIANT K_BOOL { $$ = NativeType.VariantBool; } | K_METHOD { $$ = NativeType.FuncPtr; } | K_AS K_ANY { $$ = NativeType.AsAny; } | K_LPSTRUCT { $$ = NativeType.LPStruct; } ; variant_type : /* EMPTY */ | K_NULL | K_VARIANT { $$ = SafeArrayType.variant; } | K_CURRENCY { $$ = SafeArrayType.currency; } | K_VOID | K_BOOL { $$ = SafeArrayType.boolean; } | K_INT8 { $$ = SafeArrayType.int8; } | K_INT16 { $$ = SafeArrayType.int16; } | K_INT32 { $$ = SafeArrayType.int32; } | K_INT64 | K_FLOAT32 { $$ = SafeArrayType.float32; } | K_FLOAT64 { $$ = SafeArrayType.float64; } | K_UNSIGNED K_INT8 { $$ = SafeArrayType.uint8; } | K_UNSIGNED K_INT16 { $$ = SafeArrayType.uint16; } | K_UNSIGNED K_INT32 { $$ = SafeArrayType.uint32; } | K_UNSIGNED K_INT64 | STAR | variant_type OPEN_BRACKET CLOSE_BRACKET | variant_type K_VECTOR | variant_type AMPERSAND | K_DECIMAL { $$ = SafeArrayType.Decimal; } | K_DATE { $$ = SafeArrayType.date; } | K_BSTR { $$ = SafeArrayType.bstr; } | K_LPSTR | K_LPWSTR | K_IUNKNOWN { $$ = SafeArrayType.unknown; } | K_IDISPATCH { $$ = SafeArrayType.unknown; } | K_SAFEARRAY | K_INT { $$ = SafeArrayType.Int; } | K_UNSIGNED K_INT { $$ = SafeArrayType.UInt; } | K_ERROR { $$ = SafeArrayType.error; } | K_HRESULT | K_CARRAY | K_USERDEFINED | K_RECORD | K_FILETIME | K_BLOB | K_STREAM | K_STORAGE | K_STREAMED_OBJECT | K_STORED_OBJECT | K_BLOB_OBJECT | K_CF | K_CLSID ; field_decl : D_FIELD repeat_opt field_attr type id at_opt init_opt { FieldDef field_def = new FieldDef((FieldAttr) $3, (string) $5, (BaseTypeRef) $4); codegen.AddFieldDef (field_def); codegen.CurrentCustomAttrTarget = field_def; if ($2 != null) { field_def.SetOffset ((uint) (int)$2); } if ($6 != null) { field_def.AddDataValue ((string) $6); } if ($7 != null) { field_def.SetValue ((Constant) $7); } } ; repeat_opt : /* EMPTY */ | OPEN_BRACKET int32 CLOSE_BRACKET { $$ = $2; } ; field_attr : /* EMPTY */ { $$ = new FieldAttr (); } | field_attr K_PUBLIC { $$ = (FieldAttr) $1 | FieldAttr.Public; } | field_attr K_PRIVATE { $$ = (FieldAttr) $1 | FieldAttr.Private; } | field_attr K_FAMILY { $$ = (FieldAttr) $1 | FieldAttr.Family; } | field_attr K_ASSEMBLY { $$ = (FieldAttr) $1 | FieldAttr.Assembly; } | field_attr K_FAMANDASSEM { $$ = (FieldAttr) $1 | FieldAttr.FamAndAssem; } | field_attr K_FAMORASSEM { $$ = (FieldAttr) $1 | FieldAttr.FamOrAssem; } | field_attr K_PRIVATESCOPE { // This is just 0x0000 } | field_attr K_STATIC { $$ = (FieldAttr) $1 | FieldAttr.Static; } | field_attr K_INITONLY { $$ = (FieldAttr) $1 | FieldAttr.Initonly; } | field_attr K_RTSPECIALNAME { $$ = (FieldAttr) $1 | FieldAttr.RTSpecialName; } | field_attr K_SPECIALNAME { $$ = (FieldAttr) $1 | FieldAttr.SpecialName; } | field_attr K_MARSHAL OPEN_PARENS native_type CLOSE_PARENS { codegen.AddFieldMarshalInfo ((NativeType) $4); $$ = (FieldAttr) $1 | FieldAttr.HasFieldMarshal; } | field_attr K_LITERAL { $$ = (FieldAttr) $1 | FieldAttr.Literal; } | field_attr K_NOTSERIALIZED { $$ = (FieldAttr) $1 | FieldAttr.Notserialized; } ; at_opt : /* EMPTY */ | K_AT id { $$ = $2; } ; init_opt : /* EMPTY */ | ASSIGN field_init { $$ = $2; } ; field_init_primitive : K_FLOAT32 OPEN_PARENS float64 CLOSE_PARENS { $$ = new FloatConst (Convert.ToSingle ($3)); } | K_FLOAT64 OPEN_PARENS float64 CLOSE_PARENS { $$ = new DoubleConst (Convert.ToDouble ($3)); } | K_FLOAT32 OPEN_PARENS int64 CLOSE_PARENS { $$ = new FloatConst (BitConverter.ToSingle (BitConverter.GetBytes ((long)$3), BitConverter.IsLittleEndian ? 0 : 4)); } | K_FLOAT64 OPEN_PARENS int64 CLOSE_PARENS { $$ = new DoubleConst (BitConverter.Int64BitsToDouble ((long)$3)); } | K_INT64 OPEN_PARENS int64 CLOSE_PARENS { $$ = new IntConst (Convert.ToInt64 ($3)); } | K_UINT64 OPEN_PARENS int64 CLOSE_PARENS { $$ = new UIntConst (Convert.ToUInt64 ((ulong)(long) $3)); } | K_INT32 OPEN_PARENS int64 CLOSE_PARENS { $$ = new IntConst ((int)((long)$3)); } | K_UINT32 OPEN_PARENS int64 CLOSE_PARENS { $$ = new UIntConst ((uint)((long)$3)); } | K_INT16 OPEN_PARENS int64 CLOSE_PARENS { $$ = new IntConst ((short)((long) $3)); } | K_UINT16 OPEN_PARENS int64 CLOSE_PARENS { $$ = new UIntConst ((ushort)((long) $3)); } | K_CHAR OPEN_PARENS int64 CLOSE_PARENS { $$ = new CharConst (Convert.ToChar ($3)); } | K_WCHAR OPEN_PARENS int64 CLOSE_PARENS { $$ = new CharConst (Convert.ToChar ($3)); } | K_INT8 OPEN_PARENS int64 CLOSE_PARENS { $$ = new IntConst ((sbyte)((long) ($3))); } | K_UINT8 OPEN_PARENS int64 CLOSE_PARENS { $$ = new UIntConst ((byte)((long) ($3))); } | K_BOOL OPEN_PARENS truefalse CLOSE_PARENS { $$ = new BoolConst ((bool) $3); } ; field_init : field_init_primitive | K_BYTEARRAY bytes_list { $$ = new ByteArrConst ((byte[]) $2); } | comp_qstring { // ******** THIS IS NOT IN THE DOCUMENTATION ******** // $$ = new StringConst ((string) $1); } | K_NULLREF { $$ = new NullConst (); } ; data_decl : data_head data_body { DataDef datadef = (DataDef) $1; if ($2 is ArrayList) { ArrayList const_list = (ArrayList) $2; DataConstant[] const_arr = new DataConstant[const_list.Count]; for (int i=0; i", false); } } | type ; scope_block : scope_block_begin method_decls CLOSE_BRACE { $$ = new HandlerBlock ((LabelInfo) $1, codegen.CurrentMethodDef.AddLabel ()); } ; scope_block_begin : OPEN_BRACE { $$ = codegen.CurrentMethodDef.AddLabel (); } ; seh_block : try_block seh_clauses { TryBlock try_block = (TryBlock) $1; ArrayList clause_list = (ArrayList) $2; foreach (object clause in clause_list) try_block.AddSehClause ((ISehClause) clause); codegen.CurrentMethodDef.AddInstr (try_block); } ; try_block : D_TRY scope_block { $$ = new TryBlock ((HandlerBlock) $2, tokenizer.Location); } | D_TRY id K_TO id { LabelInfo from = codegen.CurrentMethodDef.AddLabelRef ((string) $2); LabelInfo to = codegen.CurrentMethodDef.AddLabelRef ((string) $4); $$ = new TryBlock (new HandlerBlock (from, to), tokenizer.Location); } | D_TRY int32 K_TO int32 { LabelInfo from = codegen.CurrentMethodDef.AddLabel ((int) $2); LabelInfo to = codegen.CurrentMethodDef.AddLabel ((int) $4); $$ = new TryBlock (new HandlerBlock (from, to), tokenizer.Location); } ; seh_clauses : seh_clause { ArrayList clause_list = new ArrayList (); clause_list.Add ($1); $$ = clause_list; } | seh_clauses seh_clause { ArrayList clause_list = (ArrayList) $1; clause_list.Add ($2); } ; seh_clause : K_CATCH class_ref handler_block { if ($2.GetType () == typeof (PrimitiveTypeRef)) Report.Error ("Exception not be of a primitive type."); BaseClassRef type = (BaseClassRef) $2; CatchBlock cb = new CatchBlock (type); cb.SetHandlerBlock ((HandlerBlock) $3); $$ = cb; } | K_FINALLY handler_block { FinallyBlock fb = new FinallyBlock (); fb.SetHandlerBlock ((HandlerBlock) $2); $$ = fb; } | K_FAULT handler_block { FaultBlock fb = new FaultBlock (); fb.SetHandlerBlock ((HandlerBlock) $2); $$ = fb; } | filter_clause handler_block { FilterBlock fb = (FilterBlock) $1; fb.SetHandlerBlock ((HandlerBlock) $2); } ; filter_clause : K_FILTER scope_block { HandlerBlock block = (HandlerBlock) $2; FilterBlock fb = new FilterBlock (block); $$ = fb; } | K_FILTER id { LabelInfo from = codegen.CurrentMethodDef.AddLabelRef ((string) $2); FilterBlock fb = new FilterBlock (new HandlerBlock (from, null)); $$ = fb; } | K_FILTER int32 { LabelInfo from = codegen.CurrentMethodDef.AddLabel ((int) $2); FilterBlock fb = new FilterBlock (new HandlerBlock (from, null)); $$ = fb; } ; handler_block : scope_block { } | K_HANDLER id K_TO id { LabelInfo from = codegen.CurrentMethodDef.AddLabelRef ((string) $2); LabelInfo to = codegen.CurrentMethodDef.AddLabelRef ((string) $4); $$ = new HandlerBlock (from, to); } | K_HANDLER int32 K_TO int32 { LabelInfo from = codegen.CurrentMethodDef.AddLabelRef ((string) $2); LabelInfo to = codegen.CurrentMethodDef.AddLabelRef ((string) $4); $$ = new HandlerBlock (from, to); } ; instr : INSTR_NONE { codegen.CurrentMethodDef.AddInstr ( new SimpInstr ((Op) $1, tokenizer.Location)); } | INSTR_LOCAL int32 { codegen.CurrentMethodDef.AddInstr ( new IntInstr ((IntOp) $1, (int) $2, tokenizer.Location)); } | INSTR_LOCAL id { int slot = codegen.CurrentMethodDef.GetNamedLocalSlot ((string) $2); codegen.CurrentMethodDef.AddInstr ( new IntInstr ((IntOp) $1, slot, tokenizer.Location)); } | INSTR_PARAM int32 { codegen.CurrentMethodDef.AddInstr ( new IntInstr ((IntOp) $1, (int) $2, tokenizer.Location)); } | INSTR_PARAM id { int pos = codegen.CurrentMethodDef.GetNamedParamPos ((string) $2); if (pos < 0) Report.Error (String.Format ("Undeclared identifier '{0}'", (string) $2)); codegen.CurrentMethodDef.AddInstr ( new IntInstr ((IntOp) $1, pos, tokenizer.Location)); } | INSTR_I int32 { codegen.CurrentMethodDef.AddInstr (new IntInstr ((IntOp) $1, (int) $2, tokenizer.Location)); } | INSTR_I id { int slot = codegen.CurrentMethodDef.GetNamedLocalSlot ((string) $2); codegen.CurrentMethodDef.AddInstr (new IntInstr ((IntOp) $1, slot, tokenizer.Location)); } | INSTR_I8 int64 { if ($1 is MiscInstr) { switch ((MiscInstr) $1) { case MiscInstr.ldc_i8: codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (long) $2, tokenizer.Location)); break; } } } | INSTR_R float64 { switch ((MiscInstr) $1) { case MiscInstr.ldc_r4: case MiscInstr.ldc_r8: codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (double) $2, tokenizer.Location)); break; } } | INSTR_R int64 { long l = (long) $2; switch ((MiscInstr) $1) { case MiscInstr.ldc_r4: case MiscInstr.ldc_r8: codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (double) l, tokenizer.Location)); break; } } | INSTR_R bytes_list { switch ((MiscInstr) $1) { case MiscInstr.ldc_r4: float s = BitConverter.ToSingle ((byte []) $2, 0); codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, s, tokenizer.Location)); break; case MiscInstr.ldc_r8: double d = BitConverter.ToDouble ((byte []) $2, 0); codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, d, tokenizer.Location)); break; } } | INSTR_BRTARGET int32 { LabelInfo target = codegen.CurrentMethodDef.AddLabel ((int) $2); codegen.CurrentMethodDef.AddInstr (new BranchInstr ((BranchOp) $1, target, tokenizer.Location)); } | INSTR_BRTARGET id { LabelInfo target = codegen.CurrentMethodDef.AddLabelRef ((string) $2); codegen.CurrentMethodDef.AddInstr (new BranchInstr ((BranchOp) $1, target, tokenizer.Location)); } | INSTR_METHOD method_ref { codegen.CurrentMethodDef.AddInstr (new MethodInstr ((MethodOp) $1, (BaseMethodRef) $2, tokenizer.Location)); } | INSTR_FIELD type type_spec DOUBLE_COLON id { BaseTypeRef owner = (BaseTypeRef) $3; GenericParamRef gpr = $2 as GenericParamRef; if (gpr != null && codegen.CurrentMethodDef != null) codegen.CurrentMethodDef.ResolveGenParam ((PEAPI.GenParam) gpr.PeapiType); IFieldRef fieldref = owner.GetFieldRef ( (BaseTypeRef) $2, (string) $5); codegen.CurrentMethodDef.AddInstr (new FieldInstr ((FieldOp) $1, fieldref, tokenizer.Location)); } | INSTR_FIELD type id { GlobalFieldRef fieldref = codegen.GetGlobalFieldRef ((BaseTypeRef) $2, (string) $3); codegen.CurrentMethodDef.AddInstr (new FieldInstr ((FieldOp) $1, fieldref, tokenizer.Location)); } | INSTR_TYPE type_spec { codegen.CurrentMethodDef.AddInstr (new TypeInstr ((TypeOp) $1, (BaseTypeRef) $2, tokenizer.Location)); } | INSTR_STRING comp_qstring { if ((MiscInstr) $1 == MiscInstr.ldstr) codegen.CurrentMethodDef.AddInstr (new LdstrInstr ((string) $2, tokenizer.Location)); } | INSTR_STRING K_BYTEARRAY ASSIGN bytes_list { byte[] bs = (byte[]) $4; if ((MiscInstr) $1 == MiscInstr.ldstr) codegen.CurrentMethodDef.AddInstr (new LdstrInstr (bs, tokenizer.Location)); } | INSTR_STRING K_BYTEARRAY bytes_list { byte[] bs = (byte[]) $3; if ((MiscInstr) $1 == MiscInstr.ldstr) codegen.CurrentMethodDef.AddInstr (new LdstrInstr (bs, tokenizer.Location)); } | INSTR_SIG call_conv type OPEN_PARENS type_list CLOSE_PARENS { ArrayList arg_list = (ArrayList) $5; BaseTypeRef[] arg_array = null; if (arg_list != null) arg_array = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); codegen.CurrentMethodDef.AddInstr (new CalliInstr ((CallConv) $2, (BaseTypeRef) $3, arg_array, tokenizer.Location)); } | INSTR_TOK owner_type { if ((MiscInstr) $1 == MiscInstr.ldtoken) { if ($2 is BaseMethodRef) codegen.CurrentMethodDef.AddInstr (new LdtokenInstr ((BaseMethodRef) $2, tokenizer.Location)); else if ($2 is IFieldRef) codegen.CurrentMethodDef.AddInstr (new LdtokenInstr ((IFieldRef) $2, tokenizer.Location)); else codegen.CurrentMethodDef.AddInstr (new LdtokenInstr ((BaseTypeRef) $2, tokenizer.Location)); } } | INSTR_SWITCH OPEN_PARENS labels CLOSE_PARENS { codegen.CurrentMethodDef.AddInstr (new SwitchInstr ((ArrayList) $3, tokenizer.Location)); } ; method_ref : call_conv type method_name typars_clause OPEN_PARENS type_list CLOSE_PARENS { ArrayList arg_list = (ArrayList) $6; GenericArguments ga = (GenericArguments) $4; BaseTypeRef[] param_list; if (arg_list != null) param_list = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); else param_list = new BaseTypeRef[0]; BaseMethodRef methref = codegen.GetGlobalMethodRef ((BaseTypeRef) $2, (CallConv) $1, (string) $3, param_list, (ga != null ? ga.Count : 0)); if (ga != null) methref = methref.GetGenericMethodRef (ga); $$ = methref; } | call_conv type type_spec DOUBLE_COLON method_name typars_clause OPEN_PARENS type_list CLOSE_PARENS { BaseTypeRef owner = (BaseTypeRef) $3; ArrayList arg_list = (ArrayList) $8; GenericArguments ga = (GenericArguments) $6; BaseTypeRef[] param_list; BaseMethodRef methref; if (arg_list != null) param_list = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); else param_list = new BaseTypeRef[0]; if (codegen.IsThisAssembly ("mscorlib")) { PrimitiveTypeRef prim = owner as PrimitiveTypeRef; if (prim != null && prim.SigMod == "") owner = codegen.GetTypeRef (prim.Name); } if (owner.UseTypeSpec) { methref = new TypeSpecMethodRef (owner, (CallConv) $1, (BaseTypeRef) $2, (string) $5, param_list, (ga != null ? ga.Count : 0)); } else { methref = owner.GetMethodRef ((BaseTypeRef) $2, (CallConv) $1, (string) $5, param_list, (ga != null ? ga.Count : 0)); } if (ga != null) methref = methref.GetGenericMethodRef (ga); $$ = methref; } ; labels : /* EMPTY */ | id { ArrayList label_list = new ArrayList (); label_list.Add ($1); $$ = label_list; } | int32 { ArrayList label_list = new ArrayList (); label_list.Add ($1); $$ = label_list; } | labels COMMA id { ArrayList label_list = (ArrayList) $1; label_list.Add ($3); } | labels COMMA int32 { ArrayList label_list = (ArrayList) $1; label_list.Add ($3); } ; owner_type : type_spec | member_ref ; member_ref : K_METHOD method_ref { $$ = $2; } | K_FIELD type type_spec DOUBLE_COLON id { BaseTypeRef owner = (BaseTypeRef) $3; $$ = owner.GetFieldRef ( (BaseTypeRef) $2, (string) $5); } | K_FIELD type id { $$ = codegen.GetGlobalFieldRef ((BaseTypeRef) $2, (string) $3); } ; event_all : event_head OPEN_BRACE event_decls CLOSE_BRACE { codegen.CurrentTypeDef.EndEventDef (); } ; event_head : D_EVENT event_attr type_spec comp_name { EventDef event_def = new EventDef ((FeatureAttr) $2, (BaseTypeRef) $3, (string) $4); codegen.CurrentTypeDef.BeginEventDef (event_def); codegen.CurrentCustomAttrTarget = event_def; } | D_EVENT event_attr id ; event_attr : /* EMPTY */ { $$ = new FeatureAttr (); } | event_attr K_RTSPECIALNAME { $$ = (FeatureAttr) $1 & FeatureAttr.Rtspecialname; } | event_attr K_SPECIALNAME { $$ = (FeatureAttr) $1 & FeatureAttr.Specialname; } ; event_decls : /* EMPTY */ | event_decls event_decl ; event_decl : D_ADDON method_ref { codegen.CurrentTypeDef.CurrentEvent.AddAddon ( (MethodRef) $2); } | D_REMOVEON method_ref { codegen.CurrentTypeDef.CurrentEvent.AddRemoveon ( (MethodRef) $2); } | D_FIRE method_ref { codegen.CurrentTypeDef.CurrentEvent.AddFire ( (MethodRef) $2); } | D_OTHER method_ref { codegen.CurrentTypeDef.CurrentEvent.AddOther ( (MethodRef) $2); } | customattr_decl { if (codegen.CurrentCustomAttrTarget != null) codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1); } | extsource_spec | language_decl ; prop_all : prop_head OPEN_BRACE prop_decls CLOSE_BRACE { codegen.CurrentTypeDef.EndPropertyDef (); } ; prop_head : D_PROPERTY prop_attr type comp_name OPEN_PARENS type_list CLOSE_PARENS init_opt { PropertyDef prop_def = new PropertyDef ((FeatureAttr) $2, (BaseTypeRef) $3, (string) $4, (ArrayList) $6); codegen.CurrentTypeDef.BeginPropertyDef (prop_def); codegen.CurrentCustomAttrTarget = prop_def; if ($8 != null) { prop_def.AddInitValue ((Constant) $8); } } ; prop_attr : /* EMPTY */ { $$ = new FeatureAttr (); } | prop_attr K_RTSPECIALNAME { $$ = (FeatureAttr) $1 | FeatureAttr.Rtspecialname; } | prop_attr K_SPECIALNAME { $$ = (FeatureAttr) $1 | FeatureAttr.Specialname; } | prop_attr K_INSTANCE { $$ = (FeatureAttr) $1 | FeatureAttr.Instance; } ; prop_decls : /* EMPTY */ | prop_decls prop_decl ; prop_decl : D_SET method_ref { codegen.CurrentTypeDef.CurrentProperty.AddSet ((MethodRef) $2); } | D_GET method_ref { codegen.CurrentTypeDef.CurrentProperty.AddGet ((MethodRef) $2); } | D_OTHER method_ref { codegen.CurrentTypeDef.CurrentProperty.AddOther ((MethodRef) $2); } | customattr_decl { if (codegen.CurrentCustomAttrTarget != null) codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1); } | extsource_spec | language_decl ; customattr_decl : D_CUSTOM custom_type { $$ = new CustomAttr ((BaseMethodRef) $2, null); } | D_CUSTOM custom_type ASSIGN comp_qstring | D_CUSTOM custom_type ASSIGN bytes_list { $$ = new CustomAttr ((BaseMethodRef) $2, (byte[]) $4); } | D_CUSTOM OPEN_PARENS owner_type CLOSE_PARENS custom_type | D_CUSTOM OPEN_PARENS owner_type CLOSE_PARENS custom_type ASSIGN comp_qstring | D_CUSTOM OPEN_PARENS owner_type CLOSE_PARENS custom_type ASSIGN bytes_list ; custom_type : call_conv type type_spec DOUBLE_COLON D_CTOR OPEN_PARENS type_list CLOSE_PARENS { BaseTypeRef owner = (BaseTypeRef) $3; ArrayList arg_list = (ArrayList) $7; BaseTypeRef[] param_list; if (arg_list != null) param_list = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); else param_list = new BaseTypeRef[0]; $$ = owner.GetMethodRef ((BaseTypeRef) $2, (CallConv) $1, (string) $5, param_list, 0); } | call_conv type D_CTOR OPEN_PARENS type_list CLOSE_PARENS { ArrayList arg_list = (ArrayList) $5; BaseTypeRef[] param_list; if (arg_list != null) param_list = (BaseTypeRef[]) arg_list.ToArray (typeof (BaseTypeRef)); else param_list = new BaseTypeRef[0]; $$ = codegen.GetGlobalMethodRef ((BaseTypeRef) $2, (CallConv) $1, (string) $3, param_list, 0); } ; sec_decl : D_PERMISSION sec_action type_spec OPEN_PARENS nameval_pairs CLOSE_PARENS { $$ = TypeSpecToPermPair ($2, $3, (ArrayList) $5); } | D_PERMISSION sec_action type_spec { $$ = TypeSpecToPermPair ($2, $3, null); } | D_PERMISSIONSET sec_action ASSIGN bytes_list { System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding (); PermissionSetAttribute psa = new PermissionSetAttribute ((System.Security.Permissions.SecurityAction) (short) $2); psa.XML = ue.GetString ((byte []) $4); $$ = new PermPair ((PEAPI.SecurityAction) $2, psa.CreatePermissionSet ()); } | D_PERMISSIONSET sec_action comp_qstring { PermissionSetAttribute psa = new PermissionSetAttribute ((System.Security.Permissions.SecurityAction) (short) $2); psa.XML = (string) $3; $$ = new PermPair ((PEAPI.SecurityAction) $2, psa.CreatePermissionSet ()); } | D_PERMISSIONSET sec_action ASSIGN OPEN_BRACE permissions CLOSE_BRACE { #if NET_2_0 $$ = new MIPermissionSet ((PEAPI.SecurityAction) $2, (ArrayList) $5); #else Report.Error ("Use ilasm2 for 2.0 style declarative security attributes."); #endif } ; permissions : permission { ArrayList list = new ArrayList (); list.Add ($1); $$ = list; } | permissions COMMA permission { ArrayList list = (ArrayList) $1; list.Add ($3); $$ = list; } ; permission : class_ref ASSIGN OPEN_BRACE permission_members CLOSE_BRACE { $$ = new MIPermission ((BaseTypeRef) $1, (ArrayList) $4); } ; permission_members : permission_member { ArrayList list = new ArrayList (); list.Add ($1); $$ = list; } | permission_members permission_member { ArrayList list = (ArrayList) $1; list.Add ($2); $$ = list; } ; permission_member : prop_or_field primitive_type perm_mbr_nameval_pair { NameValuePair pair = (NameValuePair) $3; $$ = new PermissionMember ((MemberTypes) $1, (BaseTypeRef) $2, pair.Name, pair.Value); } | prop_or_field K_ENUM class_ref perm_mbr_nameval_pair { NameValuePair pair = (NameValuePair) $4; $$ = new PermissionMember ((MemberTypes) $1, (BaseTypeRef) $3, pair.Name, pair.Value); } ; perm_mbr_nameval_pair : SQSTRING ASSIGN field_init_primitive { $$ = new NameValuePair ((string) $1, (PEAPI.Constant) $3); } | SQSTRING ASSIGN K_BYTEARRAY bytes_list { $$ = new NameValuePair ((string) $1, new ByteArrConst ((byte[]) $4)); } | SQSTRING ASSIGN K_STRING OPEN_PARENS SQSTRING CLOSE_PARENS { $$ = new NameValuePair ((string) $1, new StringConst ((string) $5)); } ; prop_or_field : K_PROPERTY { $$ = MemberTypes.Property; } | K_FIELD { $$ = MemberTypes.Field; } ; nameval_pairs : nameval_pair { ArrayList pairs = new ArrayList (); pairs.Add ($1); $$ = pairs; } | nameval_pairs COMMA nameval_pair { ArrayList pairs = (ArrayList) $1; pairs.Add ($3); $$ = pairs; } ; nameval_pair : comp_qstring ASSIGN cavalue { $$ = new NameValuePair ((string) $1, $3); } ; cavalue : truefalse | int32 | int32 OPEN_PARENS int32 CLOSE_PARENS { $$ = $3; } | comp_qstring | class_ref OPEN_PARENS K_INT8 COLON int32 CLOSE_PARENS { $$ = ClassRefToObject ($1, (byte) (int) $5); } | class_ref OPEN_PARENS K_INT16 COLON int32 CLOSE_PARENS { $$ = ClassRefToObject ($1, (short) (int) $5); } | class_ref OPEN_PARENS K_INT32 COLON int32 CLOSE_PARENS { $$ = ClassRefToObject ($1, (int) $5); } | class_ref OPEN_PARENS int32 CLOSE_PARENS { $$ = ClassRefToObject ($1, (int) $3); } ; sec_action : K_REQUEST { $$ = PEAPI.SecurityAction.Request; } | K_DEMAND { $$ = PEAPI.SecurityAction.Demand; } | K_ASSERT { $$ = PEAPI.SecurityAction.Assert; } | K_DENY { $$ = PEAPI.SecurityAction.Deny; } | K_PERMITONLY { $$ = PEAPI.SecurityAction.PermitOnly; } | K_LINKCHECK { $$ = PEAPI.SecurityAction.LinkDemand; } | K_INHERITCHECK { $$ = PEAPI.SecurityAction.InheritDemand; } | K_REQMIN { $$ = PEAPI.SecurityAction.RequestMinimum; } | K_REQOPT { $$ = PEAPI.SecurityAction.RequestOptional; } | K_REQREFUSE { $$ = PEAPI.SecurityAction.RequestRefuse; } | K_PREJITGRANT { $$ = PEAPI.SecurityAction.PreJitGrant; } | K_PREJITDENY { $$ = PEAPI.SecurityAction.PreJitDeny; } | K_NONCASDEMAND { $$ = PEAPI.SecurityAction.NonCasDemand; } | K_NONCASLINKDEMAND { $$ = PEAPI.SecurityAction.NonCasLinkDemand; } | K_NONCASINHERITANCE { $$ = PEAPI.SecurityAction.NonCasInheritance; } /* FIXME: Should we have LinkDemandChoice, InheritDemandChoice and DemandChoice ? */ ; module_head : D_MODULE { } | D_MODULE comp_name { codegen.SetModuleName ((string) $2); } | D_MODULE K_EXTERN comp_name { codegen.ExternTable.AddModule ((string) $3); } ; file_decl : D_FILE file_attr comp_name file_entry D_HASH ASSIGN bytes_list file_entry { codegen.SetFileRef (new FileRef ((string) $3, (byte []) $7, (bool) $2, (bool) $8)); } | D_FILE file_attr comp_name file_entry { // We need to compute the hash ourselves. :-( // AssemblyName an = AssemblyName.GetName ((string) $3); } ; file_attr : /* EMPTY */ { $$ = true; } | file_attr K_NOMETADATA { $$ = false; } ; file_entry : /* EMPTY */ { $$ = false; } | D_ENTRYPOINT { $$ = true; } ; assembly_all : assembly_head OPEN_BRACE assembly_decls CLOSE_BRACE { codegen.CurrentCustomAttrTarget = null; codegen.CurrentDeclSecurityTarget = null; } ; assembly_head : D_ASSEMBLY asm_attr slashed_name { codegen.SetThisAssembly ((string) $3, (PEAPI.AssemAttr) $2); codegen.CurrentCustomAttrTarget = codegen.ThisAssembly; codegen.CurrentDeclSecurityTarget = codegen.ThisAssembly; } ; asm_attr : /* EMPTY */ { $$ = new PEAPI.AssemAttr (); } /*| asm_attr K_NOAPPDOMAIN | asm_attr K_NOPROCESS | asm_attr K_NOMACHINE*/ | asm_attr K_RETARGETABLE { $$ = ((PEAPI.AssemAttr) $1) | PEAPI.AssemAttr.Retargetable; } ; assembly_decls : /* EMPTY */ | assembly_decls assembly_decl ; assembly_decl : D_PUBLICKEY ASSIGN bytes_list { codegen.ThisAssembly.SetPublicKey ((byte []) $3); } | D_VER int32 COLON int32 COLON int32 COLON int32 { codegen.ThisAssembly.SetVersion ((int) $2, (int) $4, (int) $6, (int) $8); } | D_LOCALE comp_qstring { codegen.ThisAssembly.SetLocale ((string) $2); } | D_LOCALE ASSIGN bytes_list | D_HASH K_ALGORITHM int32 { codegen.ThisAssembly.SetHashAlgorithm ((int) $3); } | customattr_decl { codegen.ThisAssembly.AddCustomAttribute ((CustomAttr) $1); } | sec_decl { AddSecDecl ($1, true); } ; asm_or_ref_decl : D_PUBLICKEY ASSIGN bytes_list | D_VER int32 COLON int32 COLON int32 COLON int32 | D_LOCALE comp_qstring | D_LOCALE ASSIGN bytes_list | customattr_decl ; assemblyref_all : assemblyref_head OPEN_BRACE assemblyref_decls CLOSE_BRACE ; assemblyref_head : D_ASSEMBLY K_EXTERN asm_attr slashed_name { System.Reflection.AssemblyName asmb_name = new System.Reflection.AssemblyName (); asmb_name.Name = (string) $4; codegen.BeginAssemblyRef ((string) $4, asmb_name, (PEAPI.AssemAttr) $3); } | D_ASSEMBLY K_EXTERN asm_attr slashed_name K_AS slashed_name { System.Reflection.AssemblyName asmb_name = new System.Reflection.AssemblyName (); asmb_name.Name = (string) $4; codegen.BeginAssemblyRef ((string) $6, asmb_name, (PEAPI.AssemAttr) $3); } ; assemblyref_decls : /* EMPTY */ | assemblyref_decls assemblyref_decl ; assemblyref_decl : D_VER int32 COLON int32 COLON int32 COLON int32 { codegen.CurrentAssemblyRef.SetVersion ((int) $2, (int) $4, (int) $6, (int) $8); } | D_PUBLICKEY ASSIGN bytes_list { codegen.CurrentAssemblyRef.SetPublicKey ((byte []) $3); } | D_PUBLICKEYTOKEN ASSIGN bytes_list { codegen.CurrentAssemblyRef.SetPublicKeyToken ((byte []) $3); } | D_LOCALE comp_qstring { codegen.CurrentAssemblyRef.SetLocale ((string) $2); } | D_LOCALE ASSIGN bytes_list | D_HASH ASSIGN bytes_list { codegen.CurrentAssemblyRef.SetHash ((byte []) $3); } | customattr_decl { if (codegen.CurrentCustomAttrTarget != null) codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1); } ; exptype_all : exptype_head OPEN_BRACE exptype_decls CLOSE_BRACE ; exptype_head : D_CLASS K_EXTERN expt_attr comp_name ; expt_attr : /* EMPTY */ | expt_attr K_PRIVATE | expt_attr K_PUBLIC | expt_attr K_NESTED K_PUBLIC | expt_attr K_NESTED K_PRIVATE | expt_attr K_NESTED K_FAMILY | expt_attr K_NESTED K_ASSEMBLY | expt_attr K_NESTED K_FAMANDASSEM | expt_attr K_NESTED K_FAMORASSEM ; exptype_decls : /* EMPTY */ | exptype_decls exptype_decl ; exptype_decl : D_FILE comp_name | D_CLASS K_EXTERN comp_name | D_CLASS int32 | customattr_decl ; manifestres_all : manifestres_head OPEN_BRACE manifestres_decls CLOSE_BRACE ; manifestres_head : D_MRESOURCE manres_attr comp_name { FileStream s = new FileStream ((string) $3, FileMode.Open, FileAccess.Read); byte [] buff = new byte [s.Length]; s.Read (buff, 0, (int) s.Length); s.Close (); codegen.AddManifestResource (new ManifestResource ((string) $3, buff, ($2 == null) ? 0 : (uint) $2)); } ; manres_attr : /* EMPTY */ | manres_attr K_PUBLIC { $$ = ManifestResource.PublicResource; } | manres_attr K_PRIVATE { $$ = ManifestResource.PrivateResource; } ; manifestres_decls : /* EMPTY */ | manifestres_decls manifestres_decl ; manifestres_decl : D_FILE comp_name K_AT int32 | D_ASSEMBLY K_EXTERN slashed_name | customattr_decl ; comp_qstring : QSTRING | comp_qstring PLUS QSTRING { $$ = String.Format ("{0}{1}", $1, $3); } ; int32 : INT64 { long l = (long) $1; byte[] intb = BitConverter.GetBytes (l); $$ = BitConverter.ToInt32 (intb, BitConverter.IsLittleEndian ? 0 : 4); } ; int64 : INT64 ; float64 : FLOAT64 | K_FLOAT32 OPEN_PARENS INT32 CLOSE_PARENS { int i = (int) $3; byte[] intb = BitConverter.GetBytes (i); $$ = (double) BitConverter.ToSingle (intb, BitConverter.IsLittleEndian ? 0 : 4); } | K_FLOAT32 OPEN_PARENS INT64 CLOSE_PARENS { long l = (long) $3; byte[] intb = BitConverter.GetBytes (l); $$ = (double) BitConverter.ToSingle (intb, BitConverter.IsLittleEndian ? 0 : 4); } | K_FLOAT64 OPEN_PARENS INT64 CLOSE_PARENS { byte[] intb = BitConverter.GetBytes ((long) $3); $$ = BitConverter.ToDouble (intb, BitConverter.IsLittleEndian ? 0 : 4); } | K_FLOAT64 OPEN_PARENS INT32 CLOSE_PARENS { byte[] intb = BitConverter.GetBytes ((int) $3); $$ = (double) BitConverter.ToSingle (intb, BitConverter.IsLittleEndian ? 0 : 4); } ; hexbyte : HEXBYTE { } ; bytes_list : OPEN_PARENS { tokenizer.InByteArray = true; } bytes CLOSE_PARENS { $$ = $3; tokenizer.InByteArray = false; } ; bytes : /* EMPTY */ { $$ = new byte[0]; } | hexbytes { ArrayList byte_list = (ArrayList) $1; $$ = byte_list.ToArray (typeof (byte)); } ; hexbytes : hexbyte { ArrayList byte_list = new ArrayList (); byte_list.Add (Convert.ToByte ($1)); $$ = byte_list; } | hexbytes hexbyte { ArrayList byte_list = (ArrayList) $1; byte_list.Add (Convert.ToByte ($2)); } ; truefalse : K_TRUE { $$ = true; } | K_FALSE { $$ = false; } ; id : ID | SQSTRING ; comp_name : id | comp_name DOT comp_name { $$ = (string) $1 + '.' + (string) $3; } | COMP_NAME ; %% }