Merge pull request #2880 from janvorli/fix-python-script
[platform/upstream/coreclr.git] / src / ilasm / asmparse.y
1 %{
2
3 // Licensed to the .NET Foundation under one or more agreements.
4 // The .NET Foundation licenses this file to you under the MIT license.
5 // See the LICENSE file in the project root for more information.
6
7 //
8 // File asmparse.y
9 //
10 #include "ilasmpch.h"
11
12 #include "grammar_before.cpp"
13
14 %}
15
16 %union {
17         CorRegTypeAttr classAttr;
18         CorMethodAttr methAttr;
19         CorFieldAttr fieldAttr;
20         CorMethodImpl implAttr;
21         CorEventAttr  eventAttr;
22         CorPropertyAttr propAttr;
23         CorPinvokeMap pinvAttr;
24         CorDeclSecurity secAct;
25         CorFileFlags fileAttr;
26         CorAssemblyFlags asmAttr;
27         CorAssemblyFlags asmRefAttr;
28         CorTypeAttr exptAttr;
29         CorManifestResourceFlags manresAttr;
30         double*  float64;
31         __int64* int64;
32         __int32  int32;
33         char*    string;
34         BinStr*  binstr;
35         Labels*  labels;
36         Instr*   instr;         // instruction opcode
37         NVPair*  pair;
38         pTyParList typarlist;
39         mdToken token;
40         TypeDefDescr* tdd;
41         CustomDescr*  cad;
42         unsigned short opcode;
43 };
44
45         /* These are returned by the LEXER and have values */
46 %token ERROR_ BAD_COMMENT_ BAD_LITERAL_                         /* bad strings,    */
47 %token <string>  ID             /* testing343 */
48 %token <string>  DOTTEDNAME     /* System.Object */
49 %token <binstr>  QSTRING        /* "Hello World\n" */
50 %token <string>  SQSTRING       /* 'Hello World\n' */
51 %token <int32>   INT32          /* 3425 0x34FA  0352  */
52 %token <int64>   INT64          /* 342534523534534      0x34FA434644554 */
53 %token <float64> FLOAT64        /* -334234 24E-34 */
54 %token <int32>   HEXBYTE        /* 05 1A FA */
55 %token <tdd>     TYPEDEF_T
56 %token <tdd>     TYPEDEF_M
57 %token <tdd>     TYPEDEF_F
58 %token <tdd>     TYPEDEF_TS
59 %token <tdd>     TYPEDEF_MR
60 %token <tdd>     TYPEDEF_CA
61
62
63         /* multi-character punctuation */
64 %token DCOLON                   /* :: */
65 %token ELIPSIS                  /* ... */
66
67         /* Keywords   Note the undersores are to avoid collisions as these are common names */
68 %token VOID_ BOOL_ CHAR_ UNSIGNED_ INT_ INT8_ INT16_ INT32_ INT64_ FLOAT_ FLOAT32_ FLOAT64_ BYTEARRAY_
69 %token UINT_ UINT8_ UINT16_ UINT32_ UINT64_  FLAGS_ CALLCONV_ MDTOKEN_
70 %token OBJECT_ STRING_ NULLREF_
71         /* misc keywords */ 
72 %token DEFAULT_ CDECL_ VARARG_ STDCALL_ THISCALL_ FASTCALL_ CLASS_ 
73 %token TYPEDREF_ UNMANAGED_ FINALLY_ HANDLER_ CATCH_ FILTER_ FAULT_
74 %token EXTENDS_ IMPLEMENTS_ TO_ AT_ TLS_ TRUE_ FALSE_ _INTERFACEIMPL
75
76         /* class, method, field attributes */
77
78 %token VALUE_ VALUETYPE_ NATIVE_ INSTANCE_ SPECIALNAME_ FORWARDER_
79 %token STATIC_ PUBLIC_ PRIVATE_ FAMILY_ FINAL_ SYNCHRONIZED_ INTERFACE_ SEALED_ NESTED_
80 %token ABSTRACT_ AUTO_ SEQUENTIAL_ EXPLICIT_ ANSI_ UNICODE_ AUTOCHAR_ IMPORT_ ENUM_
81 %token VIRTUAL_ NOINLINING_ AGGRESSIVEINLINING_ NOOPTIMIZATION_ UNMANAGEDEXP_ BEFOREFIELDINIT_
82 %token STRICT_ RETARGETABLE_ WINDOWSRUNTIME_ NOPLATFORM_
83 %token METHOD_ FIELD_ PINNED_ MODREQ_ MODOPT_ SERIALIZABLE_ PROPERTY_ TYPE_
84 %token ASSEMBLY_ FAMANDASSEM_ FAMORASSEM_ PRIVATESCOPE_ HIDEBYSIG_ NEWSLOT_ RTSPECIALNAME_ PINVOKEIMPL_
85 %token _CTOR _CCTOR LITERAL_ NOTSERIALIZED_ INITONLY_ REQSECOBJ_
86         /* method implementation attributes: NATIVE_ and UNMANAGED_ listed above */
87 %token CIL_ OPTIL_ MANAGED_ FORWARDREF_ PRESERVESIG_ RUNTIME_ INTERNALCALL_
88         /* PInvoke-specific keywords */
89 %token _IMPORT NOMANGLE_ LASTERR_ WINAPI_ AS_ BESTFIT_ ON_ OFF_ CHARMAPERROR_
90
91         /* intruction tokens (actually instruction groupings) */
92 %token <opcode> INSTR_NONE INSTR_VAR INSTR_I INSTR_I8 INSTR_R INSTR_BRTARGET INSTR_METHOD INSTR_FIELD 
93 %token <opcode> INSTR_TYPE INSTR_STRING INSTR_SIG INSTR_TOK 
94 %token <opcode> INSTR_SWITCH
95
96         /* assember directives */
97 %token _CLASS _NAMESPACE _METHOD _FIELD _DATA _THIS _BASE _NESTER
98 %token _EMITBYTE _TRY _MAXSTACK _LOCALS _ENTRYPOINT _ZEROINIT  
99 %token _EVENT _ADDON _REMOVEON _FIRE _OTHER 
100 %token _PROPERTY _SET _GET DEFAULT_ 
101 %token _PERMISSION _PERMISSIONSET
102
103                 /* security actions */
104 %token REQUEST_ DEMAND_ ASSERT_ DENY_ PERMITONLY_ LINKCHECK_ INHERITCHECK_ 
105 %token REQMIN_ REQOPT_ REQREFUSE_ PREJITGRANT_ PREJITDENY_ NONCASDEMAND_
106 %token NONCASLINKDEMAND_ NONCASINHERITANCE_ 
107
108         /* extern debug info specifier (to be used by precompilers only) */
109 %token _LINE P_LINE _LANGUAGE
110         /* custom value specifier */
111 %token _CUSTOM
112         /* local vars zeroinit specifier */
113 %token INIT_
114         /* class layout */
115 %token _SIZE _PACK
116 %token _VTABLE _VTFIXUP FROMUNMANAGED_ CALLMOSTDERIVED_ _VTENTRY RETAINAPPDOMAIN_
117         /* manifest */
118 %token _FILE NOMETADATA_ _HASH _ASSEMBLY _PUBLICKEY _PUBLICKEYTOKEN ALGORITHM_ _VER _LOCALE EXTERN_ 
119 %token _MRESOURCE 
120 %token _MODULE _EXPORT
121 %token LEGACY_ LIBRARY_ X86_ IA64_ AMD64_ ARM_
122         /* field marshaling */
123 %token MARSHAL_ CUSTOM_ SYSSTRING_ FIXED_ VARIANT_ CURRENCY_ SYSCHAR_ DECIMAL_ DATE_ BSTR_ TBSTR_ LPSTR_
124 %token LPWSTR_ LPTSTR_ OBJECTREF_ IUNKNOWN_ IDISPATCH_ STRUCT_ SAFEARRAY_ BYVALSTR_ LPVOID_ ANY_ ARRAY_ LPSTRUCT_
125 %token IIDPARAM_
126         /* parameter attributes */
127 %token IN_ OUT_ OPT_ PARAM_
128                 /* method implementations */
129 %token _OVERRIDE WITH_
130                 /* variant type specifics */
131 %token NULL_ ERROR_ HRESULT_ CARRAY_ USERDEFINED_ RECORD_ FILETIME_ BLOB_ STREAM_ STORAGE_
132 %token STREAMED_OBJECT_ STORED_OBJECT_ BLOB_OBJECT_ CF_ CLSID_ VECTOR_
133                 /* header flags */
134 %token _SUBSYSTEM _CORFLAGS ALIGNMENT_ _IMAGEBASE _STACKRESERVE
135
136         /* syntactic sugar */
137 %token _TYPEDEF _TEMPLATE _TYPELIST _MSCORLIB      
138
139         /* compilation control directives */
140 %token P_DEFINE P_UNDEF P_IFDEF P_IFNDEF P_ELSE P_ENDIF P_INCLUDE
141
142         /* nonTerminals */
143 %type <string> dottedName id methodName atOpt slashedName
144 %type <labels> labels
145 %type <int32> callConv callKind int32 customHead customHeadWithOwner vtfixupAttr paramAttr ddItemCount variantType repeatOpt truefalse typarAttrib typarAttribs
146 %type <int32> iidParamIndex genArity genArityNotEmpty
147 %type <float64> float64
148 %type <int64> int64
149 %type <binstr> sigArgs0 sigArgs1 sigArg type bound bounds1 bytes hexbytes nativeType marshalBlob initOpt compQstring caValue
150 %type <binstr> marshalClause
151 %type <binstr> fieldInit serInit fieldSerInit
152 %type <binstr> f32seq f64seq i8seq i16seq i32seq i64seq boolSeq sqstringSeq classSeq objSeq
153 %type <binstr> simpleType
154 %type <binstr> tyArgs0 tyArgs1 tyArgs2 typeList typeListNotEmpty tyBound
155 %type <binstr> customBlobDescr serializType customBlobArgs customBlobNVPairs
156 %type <binstr> secAttrBlob secAttrSetBlob
157 %type <int32> fieldOrProp intOrWildcard
158 %type <typarlist> typarsRest typars typarsClause
159 %type <token> className typeSpec ownerType customType memberRef methodRef mdtoken
160 %type <classAttr> classAttr
161 %type <methAttr> methAttr
162 %type <fieldAttr> fieldAttr
163 %type <implAttr> implAttr
164 %type <eventAttr> eventAttr
165 %type <propAttr> propAttr
166 %type <pinvAttr> pinvAttr
167 %type <pair> nameValPairs nameValPair
168 %type <secAct> secAction
169 %type <secAct> psetHead
170 %type <fileAttr> fileAttr
171 %type <fileAttr> fileEntry
172 %type <asmAttr> asmAttr
173 %type <exptAttr> exptAttr
174 %type <manresAttr> manresAttr
175 %type <cad> customDescr customDescrWithOwner
176 %type <instr> instr_none instr_var instr_i instr_i8 instr_r instr_brtarget instr_method instr_field
177 %type <instr> instr_type instr_string instr_sig instr_tok instr_switch
178 %type <instr> instr_r_head
179
180 %start decls
181
182 /**************************************************************************/
183 %%      
184
185 decls                   : /* EMPTY */
186                         | decls decl                                            
187                         ;
188 /* Module-level declarations */
189 decl                    : classHead '{' classDecls '}'                          { PASM->EndClass(); }
190                         | nameSpaceHead '{' decls '}'                           { PASM->EndNameSpace(); }
191                         | methodHead  methodDecls '}'                           { if(PASM->m_pCurMethod->m_ulLines[1] ==0)
192                                                                                   {  PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
193                                                                                      PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
194                                                                                   PASM->EndMethod(); }
195                         | fieldDecl
196                         | dataDecl
197                         | vtableDecl
198                         | vtfixupDecl
199                         | extSourceSpec
200                         | fileDecl
201                         | assemblyHead '{' assemblyDecls '}'                    { PASMM->EndAssembly(); }
202                         | assemblyRefHead '{' assemblyRefDecls '}'              { PASMM->EndAssembly(); }
203                         | exptypeHead '{' exptypeDecls '}'                      { PASMM->EndComType(); }
204                         | manifestResHead '{' manifestResDecls '}'              { PASMM->EndManifestRes(); }
205                         | moduleHead
206                         | secDecl
207                         | customAttrDecl
208                         | _SUBSYSTEM int32                                      { 
209 #ifdef _PREFAST_
210 #pragma warning(push)
211 #pragma warning(disable:22011) // Suppress PREFast warning about integer overflow/underflow
212 #endif
213                                                                                   PASM->m_dwSubsystem = $2;
214 #ifdef _PREFAST_
215 #pragma warning(pop)
216 #endif
217                                                                                 }
218                         | _CORFLAGS int32                                       { PASM->m_dwComImageFlags = $2; }
219                         | _FILE ALIGNMENT_ int32                                { PASM->m_dwFileAlignment = $3; 
220                                                                                   if(($3 & ($3 - 1))||($3 < 0x200)||($3 > 0x10000))
221                                                                                     PASM->report->error("Invalid file alignment, must be power of 2 from 0x200 to 0x10000\n");}
222                         | _IMAGEBASE int64                                      { PASM->m_stBaseAddress = (ULONGLONG)(*($2)); delete $2; 
223                                                                                   if(PASM->m_stBaseAddress & 0xFFFF)
224                                                                                     PASM->report->error("Invalid image base, must be 0x10000-aligned\n");}
225                         | _STACKRESERVE int64                                   { PASM->m_stSizeOfStackReserve = (size_t)(*($2)); delete $2; }
226                         | languageDecl
227                         | typedefDecl
228                         | compControl
229                         | _TYPELIST '{' classNameSeq '}'
230                         | _MSCORLIB                                             { PASM->m_fIsMscorlib = TRUE; }
231                         ;
232                         
233 classNameSeq            : /* EMPTY */
234                         | className classNameSeq
235                         ;                        
236
237 compQstring             : QSTRING                                               { $$ = $1; }
238                         | compQstring '+' QSTRING                               { $$ = $1; $$->append($3); delete $3; }
239                         ;
240
241 languageDecl            : _LANGUAGE SQSTRING                                    { LPCSTRToGuid($2,&(PASM->m_guidLang)); }
242                         | _LANGUAGE SQSTRING ',' SQSTRING                       { LPCSTRToGuid($2,&(PASM->m_guidLang)); 
243                                                                                   LPCSTRToGuid($4,&(PASM->m_guidLangVendor));}
244                         | _LANGUAGE SQSTRING ',' SQSTRING ',' SQSTRING          { LPCSTRToGuid($2,&(PASM->m_guidLang)); 
245                                                                                   LPCSTRToGuid($4,&(PASM->m_guidLangVendor));
246                                                                                   LPCSTRToGuid($4,&(PASM->m_guidDoc));}
247                         ;
248 /*  Basic tokens  */                        
249 id                      : ID                                  { $$ = $1; }
250                         | SQSTRING                            { $$ = $1; }
251                         ;
252
253 dottedName              : id                                  { $$ = $1; }
254                         | DOTTEDNAME                          { $$ = $1; }
255                         | dottedName '.' dottedName           { $$ = newStringWDel($1, '.', $3); }
256                         ;
257
258 int32                   : INT32                               { $$ = $1; }
259                         ;
260
261 int64                   : INT64                               { $$ = $1; }
262                         | INT32                               { $$ = neg ? new __int64($1) : new __int64((unsigned)$1); }
263                         ;
264
265 float64                 : FLOAT64                             { $$ = $1; }
266                         | FLOAT32_ '(' int32 ')'              { float f; *((__int32*) (&f)) = $3; $$ = new double(f); }
267                         | FLOAT64_ '(' int64 ')'              { $$ = (double*) $3; }
268                         ;
269
270 /*  Aliasing of types, type specs, methods, fields and custom attributes */                        
271 typedefDecl             : _TYPEDEF type AS_ dottedName                          { PASM->AddTypeDef($2,$4); }
272                         | _TYPEDEF className AS_ dottedName                     { PASM->AddTypeDef($2,$4); }
273                         | _TYPEDEF memberRef AS_ dottedName                     { PASM->AddTypeDef($2,$4); }
274                         | _TYPEDEF customDescr AS_ dottedName                   { $2->tkOwner = 0; PASM->AddTypeDef($2,$4); }
275                         | _TYPEDEF customDescrWithOwner AS_ dottedName          { PASM->AddTypeDef($2,$4); }
276                         ;
277                         
278 /*  Compilation control directives are processed within yylex(), 
279     displayed here just for grammar completeness */
280 compControl             : P_DEFINE dottedName                                   { DefineVar($2, NULL); }
281                         | P_DEFINE dottedName compQstring                       { DefineVar($2, $3); }
282                         | P_UNDEF dottedName                                    { UndefVar($2); }
283                         | P_IFDEF dottedName                                    { SkipToken = !IsVarDefined($2);
284                                                                                   IfEndif++;
285                                                                                 }                        
286                         | P_IFNDEF dottedName                                   { SkipToken = IsVarDefined($2);
287                                                                                   IfEndif++;
288                                                                                 } 
289                         | P_ELSE                                                { if(IfEndif == 1) SkipToken = !SkipToken;}
290                         | P_ENDIF                                               { if(IfEndif == 0)
291                                                                                     PASM->report->error("Unmatched #endif\n");
292                                                                                   else IfEndif--;
293                                                                                 }
294                         | P_INCLUDE QSTRING                                     { _ASSERTE(!"yylex should have dealt with this"); }
295                         | ';'                                                   { }
296                         ; 
297                                               
298 /* Custom attribute declarations  */
299 customDescr             : _CUSTOM customType                                    { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, NULL); }
300                         | _CUSTOM customType '=' compQstring                    { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, $4); }
301                         | _CUSTOM customType '=' '{' customBlobDescr '}'        { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $2, $5); }
302                         | customHead bytes ')'                                  { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $1, $2); }
303                         ;
304
305 customDescrWithOwner    : _CUSTOM '(' ownerType ')' customType                  { $$ = new CustomDescr($3, $5, NULL); }
306                         | _CUSTOM '(' ownerType ')' customType '=' compQstring  { $$ = new CustomDescr($3, $5, $7); }
307                         | _CUSTOM '(' ownerType ')' customType '=' '{' customBlobDescr '}'
308                                                                                 { $$ = new CustomDescr($3, $5, $8); }
309                         | customHeadWithOwner bytes ')'                         { $$ = new CustomDescr(PASM->m_tkCurrentCVOwner, $1, $2); }
310                         ;
311                         
312 customHead              : _CUSTOM customType '=' '('                            { $$ = $2; bParsingByteArray = TRUE; }
313                         ;
314
315 customHeadWithOwner     : _CUSTOM '(' ownerType ')' customType '=' '('        
316                                                                                 { PASM->m_pCustomDescrList = NULL;
317                                                                                   PASM->m_tkCurrentCVOwner = $3;
318                                                                                   $$ = $5; bParsingByteArray = TRUE; }
319                         ;
320
321 customType              : methodRef                         { $$ = $1; }
322                         ;
323
324 ownerType               : typeSpec                          { $$ = $1; }
325                         | memberRef                         { $$ = $1; }
326                         ;
327
328 /*  Verbal description of custom attribute initialization blob  */                        
329 customBlobDescr         : customBlobArgs customBlobNVPairs                      { $$ = $1; 
330                                                                                   $$->appendInt16(nCustomBlobNVPairs);
331                                                                                   $$->append($2);
332                                                                                   nCustomBlobNVPairs = 0; }
333                         ;
334                         
335 customBlobArgs          : /* EMPTY */                                           { $$ = new BinStr(); $$->appendInt16(VAL16(0x0001)); }
336                         | customBlobArgs serInit                                { $$ = $1;
337                                                                                   $$->appendFrom($2, (*($2->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); }
338                         | customBlobArgs compControl                            { $$ = $1; }
339                         ;
340                         
341 customBlobNVPairs       : /* EMPTY */                                           { $$ = new BinStr(); }
342                         | customBlobNVPairs fieldOrProp serializType dottedName '=' serInit
343                                                                                 { $$ = $1; $$->appendInt8($2);
344                                                                                   $$->append($3); 
345                                                                                   AppendStringWithLength($$,$4);
346                                                                                   $$->appendFrom($6, (*($6->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1);
347                                                                                   nCustomBlobNVPairs++; }
348                         | customBlobNVPairs compControl                         { $$ = $1; }
349                         ;
350
351 fieldOrProp             : FIELD_                                                { $$ = SERIALIZATION_TYPE_FIELD; }
352                         | PROPERTY_                                             { $$ = SERIALIZATION_TYPE_PROPERTY; }
353                         ;
354
355 customAttrDecl          : customDescr                                           { if($1->tkOwner && !$1->tkInterfacePair) 
356                                                                                     PASM->DefineCV($1);
357                                                                                   else if(PASM->m_pCustomDescrList)
358                                                                                     PASM->m_pCustomDescrList->PUSH($1); }
359                         | customDescrWithOwner                                  { PASM->DefineCV($1); }
360                         | TYPEDEF_CA                                            { CustomDescr* pNew = new CustomDescr($1->m_pCA);
361                                                                                   if(pNew->tkOwner == 0) pNew->tkOwner = PASM->m_tkCurrentCVOwner;
362                                                                                   if(pNew->tkOwner) 
363                                                                                     PASM->DefineCV(pNew);
364                                                                                   else if(PASM->m_pCustomDescrList)
365                                                                                     PASM->m_pCustomDescrList->PUSH(pNew); }
366                         ;
367                         
368 serializType            : simpleType                          { $$ = $1; }
369                         | TYPE_                               { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); }
370                         | OBJECT_                             { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TAGGED_OBJECT); }
371                         | ENUM_ CLASS_ SQSTRING               { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_ENUM);
372                                                                 AppendStringWithLength($$,$3); } 
373                         | ENUM_ className                     { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_ENUM);
374                                                                 AppendStringWithLength($$,PASM->ReflectionNotation($2)); } 
375                         | serializType '[' ']'                { $$ = $1; $$->insertInt8(ELEMENT_TYPE_SZARRAY); } 
376                         ;
377
378                         
379 /*  Module declaration */
380 moduleHead              : _MODULE                                               { PASMM->SetModuleName(NULL); PASM->m_tkCurrentCVOwner=1; }
381                         | _MODULE dottedName                                    { PASMM->SetModuleName($2); PASM->m_tkCurrentCVOwner=1; }
382                         | _MODULE EXTERN_ dottedName                            { BinStr* pbs = new BinStr();
383                                                                                   unsigned L = (unsigned)strlen($3);
384                                                                                   memcpy((char*)(pbs->getBuff(L)),$3,L);
385                                                                                   PASM->EmitImport(pbs); delete pbs;}
386                         ;
387                         
388 /*  VTable Fixup table declaration  */
389 vtfixupDecl             : _VTFIXUP '[' int32 ']' vtfixupAttr AT_ id             { /*PASM->SetDataSection(); PASM->EmitDataLabel($7);*/
390                                                                                   PASM->m_VTFList.PUSH(new VTFEntry((USHORT)$3, (USHORT)$5, $7)); }
391                         ;
392
393 vtfixupAttr             : /* EMPTY */                                           { $$ = 0; }
394                         | vtfixupAttr INT32_                                    { $$ = $1 | COR_VTABLE_32BIT; }
395                         | vtfixupAttr INT64_                                    { $$ = $1 | COR_VTABLE_64BIT; }
396                         | vtfixupAttr FROMUNMANAGED_                            { $$ = $1 | COR_VTABLE_FROM_UNMANAGED; }
397                         | vtfixupAttr CALLMOSTDERIVED_                          { $$ = $1 | COR_VTABLE_CALL_MOST_DERIVED; }
398                         | vtfixupAttr RETAINAPPDOMAIN_                          { $$ = $1 | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN; }
399                         ;
400
401 vtableDecl              : vtableHead bytes ')'   /* deprecated */               { PASM->m_pVTable = $2; }
402                         ;
403
404 vtableHead              : _VTABLE '=' '('        /* deprecated */               { bParsingByteArray = TRUE; }
405                         ;
406
407 /*  Namespace and class declaration  */                         
408 nameSpaceHead           : _NAMESPACE dottedName                                 { PASM->StartNameSpace($2); }
409                         ;
410
411 _class                  : _CLASS                                                { newclass = TRUE; }
412                         ;
413                         
414 classHeadBegin          : _class classAttr dottedName typarsClause              { if($4) FixupConstraints();
415                                                                                   PASM->StartClass($3, $2, $4); 
416                                                                                   TyParFixupList.RESET(false);
417                                                                                   newclass = FALSE;
418                                                                                 }
419                         ;
420 classHead               : classHeadBegin extendsClause implClause               { PASM->AddClass(); }
421                         ;
422
423 classAttr               : /* EMPTY */                       { $$ = (CorRegTypeAttr) 0; }
424                         | classAttr PUBLIC_                 { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdPublic); }
425                         | classAttr PRIVATE_                { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNotPublic); }
426                         | classAttr VALUE_                  { $$ = (CorRegTypeAttr) ($1 | 0x80000000 | tdSealed); }
427                         | classAttr ENUM_                   { $$ = (CorRegTypeAttr) ($1 | 0x40000000); }
428                         | classAttr INTERFACE_              { $$ = (CorRegTypeAttr) ($1 | tdInterface | tdAbstract); }
429                         | classAttr SEALED_                 { $$ = (CorRegTypeAttr) ($1 | tdSealed); }
430                         | classAttr ABSTRACT_               { $$ = (CorRegTypeAttr) ($1 | tdAbstract); }
431                         | classAttr AUTO_                   { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdAutoLayout); }
432                         | classAttr SEQUENTIAL_             { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdSequentialLayout); }
433                         | classAttr EXPLICIT_               { $$ = (CorRegTypeAttr) (($1 & ~tdLayoutMask) | tdExplicitLayout); }
434                         | classAttr ANSI_                   { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdAnsiClass); }
435                         | classAttr UNICODE_                { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdUnicodeClass); }
436                         | classAttr AUTOCHAR_               { $$ = (CorRegTypeAttr) (($1 & ~tdStringFormatMask) | tdAutoClass); }
437                         | classAttr IMPORT_                 { $$ = (CorRegTypeAttr) ($1 | tdImport); }
438                         | classAttr SERIALIZABLE_           { $$ = (CorRegTypeAttr) ($1 | tdSerializable); }
439                         | classAttr WINDOWSRUNTIME_         { $$ = (CorRegTypeAttr) ($1 | tdWindowsRuntime); }
440                         | classAttr NESTED_ PUBLIC_         { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedPublic); }
441                         | classAttr NESTED_ PRIVATE_        { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedPrivate); }
442                         | classAttr NESTED_ FAMILY_         { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamily); }
443                         | classAttr NESTED_ ASSEMBLY_       { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedAssembly); }
444                         | classAttr NESTED_ FAMANDASSEM_    { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamANDAssem); }
445                         | classAttr NESTED_ FAMORASSEM_     { $$ = (CorRegTypeAttr) (($1 & ~tdVisibilityMask) | tdNestedFamORAssem); }
446                         | classAttr BEFOREFIELDINIT_        { $$ = (CorRegTypeAttr) ($1 | tdBeforeFieldInit); }
447                         | classAttr SPECIALNAME_            { $$ = (CorRegTypeAttr) ($1 | tdSpecialName); }
448                         | classAttr RTSPECIALNAME_          { $$ = (CorRegTypeAttr) ($1); }
449                         | classAttr FLAGS_ '(' int32 ')'    { $$ = (CorRegTypeAttr) ($4); }
450                         ;
451
452 extendsClause           : /* EMPTY */                                           
453                         | EXTENDS_ typeSpec                                 { PASM->m_crExtends = $2; }
454                         ;
455
456 implClause              : /* EMPTY */
457                         | IMPLEMENTS_ implList
458                         ;
459
460 classDecls              : /* EMPTY */
461                         | classDecls classDecl
462                         ;
463                         
464 implList                : implList ',' typeSpec             { PASM->AddToImplList($3); }
465                         | typeSpec                          { PASM->AddToImplList($1); }
466                                         ;
467
468 /* Generic type parameters declaration  */                         
469 typeList                : /* EMPTY */                       { $$ = new BinStr(); }
470                         | typeListNotEmpty                  { $$ = $1; }
471                         ;
472                         
473 typeListNotEmpty        : typeSpec                          { $$ = new BinStr(); $$->appendInt32($1); }
474                         | typeListNotEmpty ',' typeSpec     { $$ = $1; $$->appendInt32($3); }
475                         ;
476
477 typarsClause            : /* EMPTY */                       { $$ = NULL; PASM->m_TyParList = NULL;}
478                         | '<' typars '>'                    { $$ = $2;   PASM->m_TyParList = $2;}
479                         ;
480
481 typarAttrib             : '+'                               { $$ = gpCovariant; }
482                         | '-'                               { $$ = gpContravariant; }
483                         | CLASS_                            { $$ = gpReferenceTypeConstraint; }
484                         | VALUETYPE_                        { $$ = gpNotNullableValueTypeConstraint; }
485                         | _CTOR                             { $$ = gpDefaultConstructorConstraint; }
486                         ;
487                   
488 typarAttribs            : /* EMPTY */                       { $$ = 0; }
489                         | typarAttrib typarAttribs          { $$ = $1 | $2; }                         
490                         ;
491
492 typars                  : typarAttribs tyBound dottedName typarsRest {$$ = new TyParList($1, $2, $3, $4);}
493                         | typarAttribs dottedName typarsRest   {$$ = new TyParList($1, NULL, $2, $3);}
494                         ;
495
496 typarsRest              : /* EMPTY */                       { $$ = NULL; }
497                         | ',' typars                        { $$ = $2; }
498                         ;
499
500 tyBound                 : '(' typeList ')'                  { $$ = $2; }
501                         ;
502                         
503 genArity                : /* EMPTY */                       { $$= 0; }
504                         | genArityNotEmpty                  { $$ = $1; }
505                         ;                        
506
507 genArityNotEmpty        : '<' '[' int32 ']' '>'             { $$ = $3; }
508                         ;
509
510 /*  Class body declarations  */                         
511 classDecl               : methodHead  methodDecls '}'       { if(PASM->m_pCurMethod->m_ulLines[1] ==0)
512                                                               {  PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
513                                                                  PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
514                                                               PASM->EndMethod(); }
515                         | classHead '{' classDecls '}'      { PASM->EndClass(); }
516                         | eventHead '{' eventDecls '}'      { PASM->EndEvent(); }
517                         | propHead '{' propDecls '}'        { PASM->EndProp(); }
518                         | fieldDecl
519                         | dataDecl
520                         | secDecl
521                         | extSourceSpec
522                         | customAttrDecl
523                         | _SIZE int32                           { PASM->m_pCurClass->m_ulSize = $2; }
524                         | _PACK int32                           { PASM->m_pCurClass->m_ulPack = $2; }
525                         | exportHead '{' exptypeDecls '}'       { PASMM->EndComType(); }
526                         | _OVERRIDE typeSpec DCOLON methodName WITH_ callConv type typeSpec DCOLON methodName '(' sigArgs0 ')'
527                                                                 { BinStr *sig1 = parser->MakeSig($6, $7, $12); 
528                                                                   BinStr *sig2 = new BinStr(); sig2->append(sig1); 
529                                                                   PASM->AddMethodImpl($2,$4,sig1,$8,$10,sig2);
530                                                                   PASM->ResetArgNameList(); 
531                                                                 } 
532                         | _OVERRIDE METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')' WITH_ METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')' 
533                                                                  { PASM->AddMethodImpl($5,$7,
534                                                                       ($8==0 ? parser->MakeSig($3,$4,$10) :
535                                                                       parser->MakeSig($3| IMAGE_CEE_CS_CALLCONV_GENERIC,$4,$10,$8)),
536                                                                       $16,$18,
537                                                                       ($19==0 ? parser->MakeSig($14,$15,$21) :
538                                                                       parser->MakeSig($14| IMAGE_CEE_CS_CALLCONV_GENERIC,$15,$21,$19))); 
539                                                                    PASM->ResetArgNameList();
540                                                                  }
541                         | languageDecl
542                         | compControl
543                         | PARAM_ TYPE_ '[' int32 ']'        { if(($4 > 0) && ($4 <= (int)PASM->m_pCurClass->m_NumTyPars))
544                                                                 PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[$4-1].CAList();
545                                                               else
546                                                                 PASM->report->error("Type parameter index out of range\n");
547                                                             }
548                         | PARAM_ TYPE_ dottedName           { int n = PASM->m_pCurClass->FindTyPar($3);
549                                                               if(n >= 0)
550                                                                 PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[n].CAList();
551                                                               else
552                                                                 PASM->report->error("Type parameter '%s' undefined\n",$3);
553                                                             }
554                         | _INTERFACEIMPL TYPE_ typeSpec customDescr   { $4->tkInterfacePair = $3;     
555                                                                         if(PASM->m_pCustomDescrList)
556                                                                             PASM->m_pCustomDescrList->PUSH($4);
557                                                                       }
558                         ;
559
560 /*  Field declaration  */                        
561 fieldDecl               : _FIELD repeatOpt fieldAttr type dottedName atOpt initOpt
562                                                             { $4->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
563                                                               PASM->AddField($5, $4, $3, $6, $7, $2); }
564                         ;
565
566 fieldAttr               : /* EMPTY */                       { $$ = (CorFieldAttr) 0; }
567                         | fieldAttr STATIC_                 { $$ = (CorFieldAttr) ($1 | fdStatic); }
568                         | fieldAttr PUBLIC_                 { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPublic); }
569                         | fieldAttr PRIVATE_                { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPrivate); }
570                         | fieldAttr FAMILY_                 { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamily); }
571                         | fieldAttr INITONLY_               { $$ = (CorFieldAttr) ($1 | fdInitOnly); }
572                         | fieldAttr RTSPECIALNAME_          { $$ = $1; } /*{ $$ = (CorFieldAttr) ($1 | fdRTSpecialName); }*/
573                         | fieldAttr SPECIALNAME_            { $$ = (CorFieldAttr) ($1 | fdSpecialName); }
574                                                 /* <STRIP>commented out because PInvoke for fields is not supported by EE
575                         | fieldAttr PINVOKEIMPL_ '(' compQstring AS_ compQstring pinvAttr ')'                   
576                                                             { $$ = (CorFieldAttr) ($1 | fdPinvokeImpl); 
577                                                               PASM->SetPinvoke($4,0,$6,$7); }
578                         | fieldAttr PINVOKEIMPL_ '(' compQstring  pinvAttr ')'                      
579                                                             { $$ = (CorFieldAttr) ($1 | fdPinvokeImpl); 
580                                                               PASM->SetPinvoke($4,0,NULL,$5); }
581                         | fieldAttr PINVOKEIMPL_ '(' pinvAttr ')'                       
582                                                             { PASM->SetPinvoke(new BinStr(),0,NULL,$4); 
583                                                               $$ = (CorFieldAttr) ($1 | fdPinvokeImpl); }
584                                                 </STRIP>*/
585                         | fieldAttr MARSHAL_ '(' marshalBlob ')'                 
586                                                             { PASM->m_pMarshal = $4; }
587                         | fieldAttr ASSEMBLY_               { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdAssembly); }
588                         | fieldAttr FAMANDASSEM_            { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamANDAssem); }
589                         | fieldAttr FAMORASSEM_             { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdFamORAssem); }
590                         | fieldAttr PRIVATESCOPE_           { $$ = (CorFieldAttr) (($1 & ~mdMemberAccessMask) | fdPrivateScope); }
591                         | fieldAttr LITERAL_                { $$ = (CorFieldAttr) ($1 | fdLiteral); }
592                         | fieldAttr NOTSERIALIZED_          { $$ = (CorFieldAttr) ($1 | fdNotSerialized); }
593                         | fieldAttr FLAGS_ '(' int32 ')'    { $$ = (CorFieldAttr) ($4); }
594                         ;
595
596 atOpt                   : /* EMPTY */                       { $$ = 0; } 
597                         | AT_ id                            { $$ = $2; }
598                         ;
599
600 initOpt                 : /* EMPTY */                       { $$ = NULL; }
601                         | '=' fieldInit                     { $$ = $2; }
602                                                 ;
603
604 repeatOpt               : /* EMPTY */                       { $$ = 0xFFFFFFFF; }
605                         | '[' int32 ']'                     { $$ = $2; }
606                                                 ;
607
608 /*  Method referencing  */
609 methodRef               : callConv type typeSpec DCOLON methodName tyArgs0 '(' sigArgs0 ')'
610                                                              { PASM->ResetArgNameList();
611                                                                if ($6 == NULL)
612                                                                {
613                                                                  if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
614                                                                  $$ = PASM->MakeMemberRef($3, $5, parser->MakeSig($1|iCallConv, $2, $8));
615                                                                }
616                                                                else
617                                                                {
618                                                                  mdToken mr;
619                                                                  if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
620                                                                  mr = PASM->MakeMemberRef($3, $5, 
621                                                                    parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $8, corCountArgs($6)));
622                                                                  $$ = PASM->MakeMethodSpec(mr, 
623                                                                    parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, $6));
624                                                                }
625                                                              }
626                         | callConv type typeSpec DCOLON methodName genArityNotEmpty '(' sigArgs0 ')'
627                                                              { PASM->ResetArgNameList();
628                                                                if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
629                                                                $$ = PASM->MakeMemberRef($3, $5, 
630                                                                  parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $8, $6));
631                                                              }
632                         | callConv type methodName tyArgs0 '(' sigArgs0 ')'
633                                                              { PASM->ResetArgNameList();
634                                                                if ($4 == NULL)
635                                                                {
636                                                                  if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
637                                                                  $$ = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1|iCallConv, $2, $6));
638                                                                }
639                                                                else
640                                                                {
641                                                                  mdToken mr;
642                                                                  if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
643                                                                  mr = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $6, corCountArgs($4)));
644                                                                  $$ = PASM->MakeMethodSpec(mr, 
645                                                                    parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, $4));
646                                                                }
647                                                              }
648                         | callConv type methodName genArityNotEmpty '(' sigArgs0 ')'
649                                                              { PASM->ResetArgNameList();
650                                                                if((iCallConv)&&(($1 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n"); 
651                                                                $$ = PASM->MakeMemberRef(mdTokenNil, $3, parser->MakeSig($1 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, $2, $6, $4));
652                                                              }
653                         | mdtoken                            { $$ = $1; }
654                         | TYPEDEF_M                          { $$ = $1->m_tkTypeSpec; }                                                             
655                         | TYPEDEF_MR                         { $$ = $1->m_tkTypeSpec; }                                                             
656                         ;
657                         
658 callConv                : INSTANCE_ callConv                  { $$ = ($2 | IMAGE_CEE_CS_CALLCONV_HASTHIS); }
659                         | EXPLICIT_ callConv                  { $$ = ($2 | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS); }
660                         | callKind                            { $$ = $1; }
661                         | CALLCONV_ '(' int32 ')'             { $$ = $3; }
662                         ;
663
664 callKind                : /* EMPTY */                         { $$ = IMAGE_CEE_CS_CALLCONV_DEFAULT; }
665                         | DEFAULT_                            { $$ = IMAGE_CEE_CS_CALLCONV_DEFAULT; }
666                         | VARARG_                             { $$ = IMAGE_CEE_CS_CALLCONV_VARARG; }
667                         | UNMANAGED_ CDECL_                   { $$ = IMAGE_CEE_CS_CALLCONV_C; }
668                         | UNMANAGED_ STDCALL_                 { $$ = IMAGE_CEE_CS_CALLCONV_STDCALL; }
669                         | UNMANAGED_ THISCALL_                { $$ = IMAGE_CEE_CS_CALLCONV_THISCALL; }
670                         | UNMANAGED_ FASTCALL_                { $$ = IMAGE_CEE_CS_CALLCONV_FASTCALL; }
671                         ;
672
673 mdtoken                 : MDTOKEN_ '(' int32 ')'             { $$ = $3; }
674                         ;
675
676 memberRef               : methodSpec methodRef               { $$ = $2; 
677                                                                PASM->delArgNameList(PASM->m_firstArgName);
678                                                                PASM->m_firstArgName = parser->m_ANSFirst.POP();
679                                                                PASM->m_lastArgName = parser->m_ANSLast.POP();
680                                                                PASM->SetMemberRefFixup($2,iOpcodeLen); }
681                         | FIELD_ type typeSpec DCOLON dottedName
682                                                              { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD); 
683                                                                $$ = PASM->MakeMemberRef($3, $5, $2); 
684                                                                PASM->SetMemberRefFixup($$,iOpcodeLen); }
685                         | FIELD_ type dottedName
686                                                              { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD); 
687                                                                $$ = PASM->MakeMemberRef(NULL, $3, $2); 
688                                                                PASM->SetMemberRefFixup($$,iOpcodeLen); }
689                         | FIELD_ TYPEDEF_F                   { $$ = $2->m_tkTypeSpec;
690                                                                PASM->SetMemberRefFixup($$,iOpcodeLen); }
691                         | FIELD_ TYPEDEF_MR                  { $$ = $2->m_tkTypeSpec;
692                                                                PASM->SetMemberRefFixup($$,iOpcodeLen); }
693                         | mdtoken                            { $$ = $1; 
694                                                                PASM->SetMemberRefFixup($$,iOpcodeLen); }
695                         ;
696
697 /*  Event declaration  */                        
698 eventHead               : _EVENT eventAttr typeSpec dottedName   { PASM->ResetEvent($4, $3, $2); }
699                         | _EVENT eventAttr dottedName            { PASM->ResetEvent($3, mdTypeRefNil, $2); }
700                         ;
701
702
703 eventAttr               : /* EMPTY */                       { $$ = (CorEventAttr) 0; }
704                         | eventAttr RTSPECIALNAME_          { $$ = $1; }/*{ $$ = (CorEventAttr) ($1 | evRTSpecialName); }*/
705                         | eventAttr SPECIALNAME_            { $$ = (CorEventAttr) ($1 | evSpecialName); }
706                         ;
707
708 eventDecls              : /* EMPTY */
709                         | eventDecls eventDecl
710                         ;
711
712 eventDecl               : _ADDON methodRef                 { PASM->SetEventMethod(0, $2); }
713                         | _REMOVEON methodRef              { PASM->SetEventMethod(1, $2); }
714                         | _FIRE methodRef                  { PASM->SetEventMethod(2, $2); }
715                         | _OTHER methodRef                 { PASM->SetEventMethod(3, $2); }
716                         | extSourceSpec
717                         | customAttrDecl
718                         | languageDecl
719                         | compControl
720                         ;
721
722 /*  Property declaration  */                         
723 propHead                : _PROPERTY propAttr callConv type dottedName '(' sigArgs0 ')' initOpt     
724                                                             { PASM->ResetProp($5, 
725                                                               parser->MakeSig((IMAGE_CEE_CS_CALLCONV_PROPERTY |
726                                                               ($3 & IMAGE_CEE_CS_CALLCONV_HASTHIS)),$4,$7), $2, $9);}
727                         ;
728
729 propAttr                : /* EMPTY */                       { $$ = (CorPropertyAttr) 0; }
730                         | propAttr RTSPECIALNAME_           { $$ = $1; }/*{ $$ = (CorPropertyAttr) ($1 | prRTSpecialName); }*/
731                         | propAttr SPECIALNAME_             { $$ = (CorPropertyAttr) ($1 | prSpecialName); }
732                         ;
733
734 propDecls               : /* EMPTY */
735                         | propDecls propDecl
736                         ;
737
738
739 propDecl                : _SET methodRef                    { PASM->SetPropMethod(0, $2); }
740                         | _GET methodRef                    { PASM->SetPropMethod(1, $2); }
741                         | _OTHER methodRef                  { PASM->SetPropMethod(2, $2); }
742                         | customAttrDecl
743                         | extSourceSpec
744                         | languageDecl
745                         | compControl
746                         ;
747
748 /*  Method declaration  */
749 methodHeadPart1         : _METHOD                           { PASM->ResetForNextMethod(); 
750                                                               uMethodBeginLine = PASM->m_ulCurLine;
751                                                               uMethodBeginColumn=PASM->m_ulCurColumn;
752                                                             }
753                         ;
754                         
755 marshalClause           : /* EMPTY */                       { $$ = NULL; }
756                         | MARSHAL_ '(' marshalBlob ')'       { $$ = $3; }
757                         ;
758
759 marshalBlob             : nativeType                        { $$ = $1; }
760                         | marshalBlobHead hexbytes '}'       { $$ = $2; }
761                         ;
762
763 marshalBlobHead         : '{'                                { bParsingByteArray = TRUE; } 
764                         ;
765
766 methodHead              : methodHeadPart1 methAttr callConv paramAttr type marshalClause methodName typarsClause'(' sigArgs0 ')' implAttr '{'
767                                                             { BinStr* sig;
768                                                               if ($8 == NULL) sig = parser->MakeSig($3, $5, $10);
769                                                               else {
770                                                                FixupTyPars($5);
771                                                                sig = parser->MakeSig($3 | IMAGE_CEE_CS_CALLCONV_GENERIC, $5, $10, $8->Count());
772                                                                FixupConstraints();
773                                                               }
774                                                               PASM->StartMethod($7, sig, $2, $6, $4, $8);
775                                                               TyParFixupList.RESET(false);
776                                                               PASM->SetImplAttr((USHORT)$12);  
777                                                               PASM->m_pCurMethod->m_ulLines[0] = uMethodBeginLine;
778                                                               PASM->m_pCurMethod->m_ulColumns[0]=uMethodBeginColumn; 
779                                                             }
780                         ;
781
782 methAttr                : /* EMPTY */                       { $$ = (CorMethodAttr) 0; }
783                         | methAttr STATIC_                  { $$ = (CorMethodAttr) ($1 | mdStatic); }
784                         | methAttr PUBLIC_                  { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPublic); }
785                         | methAttr PRIVATE_                 { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPrivate); }
786                         | methAttr FAMILY_                  { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamily); }
787                         | methAttr FINAL_                   { $$ = (CorMethodAttr) ($1 | mdFinal); }
788                         | methAttr SPECIALNAME_             { $$ = (CorMethodAttr) ($1 | mdSpecialName); }
789                         | methAttr VIRTUAL_                 { $$ = (CorMethodAttr) ($1 | mdVirtual); }
790                         | methAttr STRICT_                  { $$ = (CorMethodAttr) ($1 | mdCheckAccessOnOverride); }
791                         | methAttr ABSTRACT_                { $$ = (CorMethodAttr) ($1 | mdAbstract); }
792                         | methAttr ASSEMBLY_                { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdAssem); }
793                         | methAttr FAMANDASSEM_             { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamANDAssem); }
794                         | methAttr FAMORASSEM_              { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdFamORAssem); }
795                         | methAttr PRIVATESCOPE_            { $$ = (CorMethodAttr) (($1 & ~mdMemberAccessMask) | mdPrivateScope); }
796                         | methAttr HIDEBYSIG_               { $$ = (CorMethodAttr) ($1 | mdHideBySig); }
797                         | methAttr NEWSLOT_                 { $$ = (CorMethodAttr) ($1 | mdNewSlot); }
798                         | methAttr RTSPECIALNAME_           { $$ = $1; }/*{ $$ = (CorMethodAttr) ($1 | mdRTSpecialName); }*/
799                         | methAttr UNMANAGEDEXP_            { $$ = (CorMethodAttr) ($1 | mdUnmanagedExport); }
800                         | methAttr REQSECOBJ_               { $$ = (CorMethodAttr) ($1 | mdRequireSecObject); }
801                         | methAttr FLAGS_ '(' int32 ')'     { $$ = (CorMethodAttr) ($4); }
802                         | methAttr PINVOKEIMPL_ '(' compQstring AS_ compQstring pinvAttr ')'                    
803                                                             { PASM->SetPinvoke($4,0,$6,$7); 
804                                                               $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
805                         | methAttr PINVOKEIMPL_ '(' compQstring  pinvAttr ')'                       
806                                                             { PASM->SetPinvoke($4,0,NULL,$5); 
807                                                               $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
808                         | methAttr PINVOKEIMPL_ '(' pinvAttr ')'                        
809                                                             { PASM->SetPinvoke(new BinStr(),0,NULL,$4); 
810                                                               $$ = (CorMethodAttr) ($1 | mdPinvokeImpl); }
811                         ;
812
813 pinvAttr                : /* EMPTY */                       { $$ = (CorPinvokeMap) 0; }
814                         | pinvAttr NOMANGLE_                { $$ = (CorPinvokeMap) ($1 | pmNoMangle); }
815                         | pinvAttr ANSI_                    { $$ = (CorPinvokeMap) ($1 | pmCharSetAnsi); }
816                         | pinvAttr UNICODE_                 { $$ = (CorPinvokeMap) ($1 | pmCharSetUnicode); }
817                         | pinvAttr AUTOCHAR_                { $$ = (CorPinvokeMap) ($1 | pmCharSetAuto); }
818                         | pinvAttr LASTERR_                 { $$ = (CorPinvokeMap) ($1 | pmSupportsLastError); }
819                         | pinvAttr WINAPI_                  { $$ = (CorPinvokeMap) ($1 | pmCallConvWinapi); }
820                         | pinvAttr CDECL_                   { $$ = (CorPinvokeMap) ($1 | pmCallConvCdecl); }
821                         | pinvAttr STDCALL_                 { $$ = (CorPinvokeMap) ($1 | pmCallConvStdcall); }
822                         | pinvAttr THISCALL_                { $$ = (CorPinvokeMap) ($1 | pmCallConvThiscall); }
823                         | pinvAttr FASTCALL_                { $$ = (CorPinvokeMap) ($1 | pmCallConvFastcall); }
824                         | pinvAttr BESTFIT_ ':' ON_         { $$ = (CorPinvokeMap) ($1 | pmBestFitEnabled); }
825                         | pinvAttr BESTFIT_ ':' OFF_        { $$ = (CorPinvokeMap) ($1 | pmBestFitDisabled); }
826                         | pinvAttr CHARMAPERROR_ ':' ON_    { $$ = (CorPinvokeMap) ($1 | pmThrowOnUnmappableCharEnabled); }
827                         | pinvAttr CHARMAPERROR_ ':' OFF_   { $$ = (CorPinvokeMap) ($1 | pmThrowOnUnmappableCharDisabled); }
828                         | pinvAttr FLAGS_ '(' int32 ')'     { $$ = (CorPinvokeMap) ($4); }
829                         ;
830
831 methodName              : _CTOR                             { $$ = newString(COR_CTOR_METHOD_NAME); }
832                         | _CCTOR                            { $$ = newString(COR_CCTOR_METHOD_NAME); }
833                         | dottedName                        { $$ = $1; }
834                         ;
835
836 paramAttr               : /* EMPTY */                       { $$ = 0; }
837                         | paramAttr '[' IN_ ']'             { $$ = $1 | pdIn; }
838                         | paramAttr '[' OUT_ ']'            { $$ = $1 | pdOut; }
839                         | paramAttr '[' OPT_ ']'            { $$ = $1 | pdOptional; }
840                         | paramAttr '[' int32 ']'           { $$ = $3 + 1; } 
841                         ;
842         
843 implAttr                : /* EMPTY */                       { $$ = (CorMethodImpl) (miIL | miManaged); }
844                         | implAttr NATIVE_                  { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miNative); }
845                         | implAttr CIL_                     { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miIL); }
846                         | implAttr OPTIL_                   { $$ = (CorMethodImpl) (($1 & 0xFFF4) | miOPTIL); }
847                         | implAttr MANAGED_                 { $$ = (CorMethodImpl) (($1 & 0xFFFB) | miManaged); }
848                         | implAttr UNMANAGED_               { $$ = (CorMethodImpl) (($1 & 0xFFFB) | miUnmanaged); }
849                         | implAttr FORWARDREF_              { $$ = (CorMethodImpl) ($1 | miForwardRef); }
850                         | implAttr PRESERVESIG_             { $$ = (CorMethodImpl) ($1 | miPreserveSig); }
851                         | implAttr RUNTIME_                 { $$ = (CorMethodImpl) ($1 | miRuntime); }
852                         | implAttr INTERNALCALL_            { $$ = (CorMethodImpl) ($1 | miInternalCall); }
853                         | implAttr SYNCHRONIZED_            { $$ = (CorMethodImpl) ($1 | miSynchronized); }
854                         | implAttr NOINLINING_              { $$ = (CorMethodImpl) ($1 | miNoInlining); }
855                         | implAttr AGGRESSIVEINLINING_      { $$ = (CorMethodImpl) ($1 | miAggressiveInlining); }
856                         | implAttr NOOPTIMIZATION_          { $$ = (CorMethodImpl) ($1 | miNoOptimization); }
857                         | implAttr FLAGS_ '(' int32 ')'     { $$ = (CorMethodImpl) ($4); }
858                         ;
859
860 localsHead              : _LOCALS                           { PASM->delArgNameList(PASM->m_firstArgName); PASM->m_firstArgName = NULL;PASM->m_lastArgName = NULL; 
861                                                             }
862                         ;
863
864 methodDecls             : /* EMPTY */
865                         | methodDecls methodDecl
866                         ;
867
868 methodDecl              : _EMITBYTE int32                   { PASM->EmitByte($2); }
869                         | sehBlock                          { delete PASM->m_SEHD; PASM->m_SEHD = PASM->m_SEHDstack.POP(); }
870                         | _MAXSTACK int32                   { PASM->EmitMaxStack($2); }
871                         | localsHead '(' sigArgs0 ')'       { PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, $3)); 
872                                                             }
873                         | localsHead INIT_ '(' sigArgs0 ')' { PASM->EmitZeroInit(); 
874                                                               PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, $4)); 
875                                                             }
876                         | _ENTRYPOINT                       { PASM->EmitEntryPoint(); }
877                         | _ZEROINIT                         { PASM->EmitZeroInit(); }
878                         | dataDecl
879                         | instr
880                         | id ':'                            { PASM->AddLabel(PASM->m_CurPC,$1); /*PASM->EmitLabel($1);*/ }
881                         | secDecl
882                         | extSourceSpec
883                         | languageDecl
884                         | customAttrDecl
885                         | compControl
886                         | _EXPORT '[' int32 ']'             { if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
887                                                               {
888                                                                 PASM->m_pCurMethod->m_dwExportOrdinal = $3;
889                                                                 PASM->m_pCurMethod->m_szExportAlias = NULL;
890                                                                 if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
891                                                                 if(PASM->m_pCurMethod->m_wVTSlot  == 0) PASM->m_pCurMethod->m_wVTSlot = $3 + 0x8000;
892                                                               }
893                                                               else
894                                                                 PASM->report->warn("Duplicate .export directive, ignored\n");
895                                                             }
896                         | _EXPORT '[' int32 ']' AS_ id      { if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
897                                                               {
898                                                                 PASM->m_pCurMethod->m_dwExportOrdinal = $3;
899                                                                 PASM->m_pCurMethod->m_szExportAlias = $6;
900                                                                 if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
901                                                                 if(PASM->m_pCurMethod->m_wVTSlot  == 0) PASM->m_pCurMethod->m_wVTSlot = $3 + 0x8000;
902                                                               }
903                                                               else
904                                                                 PASM->report->warn("Duplicate .export directive, ignored\n");
905                                                             }
906                         | _VTENTRY int32 ':' int32          { PASM->m_pCurMethod->m_wVTEntry = (WORD)$2;
907                                                               PASM->m_pCurMethod->m_wVTSlot = (WORD)$4; }
908                         | _OVERRIDE typeSpec DCOLON methodName 
909                                                             { PASM->AddMethodImpl($2,$4,NULL,NULL,NULL,NULL); }
910
911                         | _OVERRIDE METHOD_ callConv type typeSpec DCOLON methodName genArity '(' sigArgs0 ')'
912                                                             { PASM->AddMethodImpl($5,$7,
913                                                               ($8==0 ? parser->MakeSig($3,$4,$10) :
914                                                               parser->MakeSig($3| IMAGE_CEE_CS_CALLCONV_GENERIC,$4,$10,$8))
915                                                               ,NULL,NULL,NULL); 
916                                                               PASM->ResetArgNameList();
917                                                             }
918                         | scopeBlock
919                         | PARAM_ TYPE_ '[' int32 ']'        { if(($4 > 0) && ($4 <= (int)PASM->m_pCurMethod->m_NumTyPars))
920                                                                 PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[$4-1].CAList();
921                                                               else
922                                                                 PASM->report->error("Type parameter index out of range\n");
923                                                             }
924                         | PARAM_ TYPE_ dottedName           { int n = PASM->m_pCurMethod->FindTyPar($3);
925                                                               if(n >= 0)
926                                                                 PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[n].CAList();
927                                                               else
928                                                                 PASM->report->error("Type parameter '%s' undefined\n",$3);
929                                                             }
930                         | PARAM_ '[' int32 ']' initOpt                            
931                                                             { if( $3 ) {
932                                                                 ARG_NAME_LIST* pAN=PASM->findArg(PASM->m_pCurMethod->m_firstArgName, $3 - 1);
933                                                                 if(pAN)
934                                                                 {
935                                                                     PASM->m_pCustomDescrList = &(pAN->CustDList);
936                                                                     pAN->pValue = $5;
937                                                                 }
938                                                                 else
939                                                                 {
940                                                                     PASM->m_pCustomDescrList = NULL;
941                                                                     if($5) delete $5;
942                                                                 }
943                                                               } else {
944                                                                 PASM->m_pCustomDescrList = &(PASM->m_pCurMethod->m_RetCustDList);
945                                                                 PASM->m_pCurMethod->m_pRetValue = $5;
946                                                               }
947                                                               PASM->m_tkCurrentCVOwner = 0;
948                                                             }
949                         ;
950
951 scopeBlock              : scopeOpen methodDecls '}'         { PASM->m_pCurMethod->CloseScope(); }
952                         ;
953
954 scopeOpen               : '{'                               { PASM->m_pCurMethod->OpenScope(); }
955                         ;
956
957 /* Structured exception handling directives  */                          
958 sehBlock                : tryBlock sehClauses
959                         ;
960
961 sehClauses              : sehClause sehClauses
962                         | sehClause
963                         ;
964
965 tryBlock                : tryHead scopeBlock                { PASM->m_SEHD->tryTo = PASM->m_CurPC; }
966                         | tryHead id TO_ id                 { PASM->SetTryLabels($2, $4); }
967                         | tryHead int32 TO_ int32           { if(PASM->m_SEHD) {PASM->m_SEHD->tryFrom = $2;
968                                                               PASM->m_SEHD->tryTo = $4;} }
969                         ;
970
971 tryHead                 : _TRY                              { PASM->NewSEHDescriptor();
972                                                               PASM->m_SEHD->tryFrom = PASM->m_CurPC; }
973                         ;
974
975
976 sehClause               : catchClause handlerBlock           { PASM->EmitTry(); }
977                         | filterClause handlerBlock          { PASM->EmitTry(); }
978                         | finallyClause handlerBlock         { PASM->EmitTry(); }
979                         | faultClause handlerBlock           { PASM->EmitTry(); }
980                         ;
981
982                                                                                                                                 
983 filterClause            : filterHead scopeBlock              { PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
984                         | filterHead id                      { PASM->SetFilterLabel($2); 
985                                                                PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
986                         | filterHead int32                   { PASM->m_SEHD->sehFilter = $2; 
987                                                                PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
988                         ;
989
990 filterHead              : FILTER_                            { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FILTER;
991                                                                PASM->m_SEHD->sehFilter = PASM->m_CurPC; } 
992                         ;
993
994 catchClause             : CATCH_ typeSpec                   {  PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_NONE;
995                                                                PASM->SetCatchClass($2); 
996                                                                PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
997                         ;
998
999 finallyClause           : FINALLY_                           { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FINALLY;
1000                                                                PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
1001                         ;
1002
1003 faultClause             : FAULT_                             { PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FAULT;
1004                                                                PASM->m_SEHD->sehHandler = PASM->m_CurPC; }
1005                         ;
1006
1007 handlerBlock            : scopeBlock                         { PASM->m_SEHD->sehHandlerTo = PASM->m_CurPC; }                 
1008                         | HANDLER_ id TO_ id                 { PASM->SetHandlerLabels($2, $4); }
1009                         | HANDLER_ int32 TO_ int32           { PASM->m_SEHD->sehHandler = $2;
1010                                                                PASM->m_SEHD->sehHandlerTo = $4; }
1011                         ;
1012
1013 /*  Data declaration  */
1014 dataDecl                : ddHead ddBody
1015                         ;
1016
1017 ddHead                  : _DATA tls id '='                   { PASM->EmitDataLabel($3); }
1018                         | _DATA tls  
1019                         ;
1020
1021 tls                     : /* EMPTY */                        { PASM->SetDataSection(); }
1022                         | TLS_                               { PASM->SetTLSSection(); }
1023                         | CIL_                               { PASM->SetILSection(); }
1024                         ;
1025
1026 ddBody                  : '{' ddItemList '}'
1027                         | ddItem
1028                         ;
1029
1030 ddItemList              : ddItem ',' ddItemList
1031                         | ddItem
1032                         ;
1033
1034 ddItemCount             : /* EMPTY */                        { $$ = 1; }
1035                         | '[' int32 ']'                      { $$ = $2;
1036                                                                if($2 <= 0) { PASM->report->error("Illegal item count: %d\n",$2);
1037                                                                   if(!PASM->OnErrGo) $$ = 1; }}
1038                         ;
1039
1040 ddItem                  : CHAR_ '*' '(' compQstring ')'      { PASM->EmitDataString($4); }
1041                         | '&' '(' id ')'                     { PASM->EmitDD($3); }
1042                         | bytearrayhead bytes ')'            { PASM->EmitData($2->ptr(),$2->length()); }
1043                         | FLOAT32_ '(' float64 ')' ddItemCount
1044                                                              { float f = (float) (*$3); float* p = new (nothrow) float[$5];
1045                                                                if(p != NULL) {
1046                                                                  for(int i=0; i < $5; i++) p[i] = f;
1047                                                                  PASM->EmitData(p, sizeof(float)*$5); delete $3; delete [] p; 
1048                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1049                                                                      sizeof(float)*$5); }
1050                         | FLOAT64_ '(' float64 ')' ddItemCount
1051                                                              { double* p = new (nothrow) double[$5];
1052                                                                if(p != NULL) {
1053                                                                  for(int i=0; i<$5; i++) p[i] = *($3);
1054                                                                  PASM->EmitData(p, sizeof(double)*$5); delete $3; delete [] p;
1055                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1056                                                                      sizeof(double)*$5); }
1057                         | INT64_ '(' int64 ')' ddItemCount
1058                                                              { __int64* p = new (nothrow) __int64[$5];
1059                                                                if(p != NULL) {
1060                                                                  for(int i=0; i<$5; i++) p[i] = *($3);
1061                                                                  PASM->EmitData(p, sizeof(__int64)*$5); delete $3; delete [] p;
1062                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1063                                                                      sizeof(__int64)*$5); }
1064                         | INT32_ '(' int32 ')' ddItemCount
1065                                                              { __int32* p = new (nothrow) __int32[$5];
1066                                                                if(p != NULL) {
1067                                                                  for(int i=0; i<$5; i++) p[i] = $3;
1068                                                                  PASM->EmitData(p, sizeof(__int32)*$5); delete [] p;
1069                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1070                                                                      sizeof(__int32)*$5); }
1071                         | INT16_ '(' int32 ')' ddItemCount
1072                                                              { __int16 i = (__int16) $3; FAIL_UNLESS(i == $3, ("Value %d too big\n", $3));
1073                                                                __int16* p = new (nothrow) __int16[$5];
1074                                                                if(p != NULL) {
1075                                                                  for(int j=0; j<$5; j++) p[j] = i;
1076                                                                  PASM->EmitData(p, sizeof(__int16)*$5); delete [] p;
1077                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1078                                                                      sizeof(__int16)*$5); }
1079                         | INT8_ '(' int32 ')' ddItemCount
1080                                                              { __int8 i = (__int8) $3; FAIL_UNLESS(i == $3, ("Value %d too big\n", $3));
1081                                                                __int8* p = new (nothrow) __int8[$5];
1082                                                                if(p != NULL) {
1083                                                                  for(int j=0; j<$5; j++) p[j] = i;
1084                                                                  PASM->EmitData(p, sizeof(__int8)*$5); delete [] p;
1085                                                                } else PASM->report->error("Out of memory emitting data block %d bytes\n",
1086                                                                      sizeof(__int8)*$5); }
1087                         | FLOAT32_ ddItemCount               { PASM->EmitData(NULL, sizeof(float)*$2); }
1088                         | FLOAT64_ ddItemCount               { PASM->EmitData(NULL, sizeof(double)*$2); }
1089                         | INT64_ ddItemCount                 { PASM->EmitData(NULL, sizeof(__int64)*$2); }
1090                         | INT32_ ddItemCount                 { PASM->EmitData(NULL, sizeof(__int32)*$2); }
1091                         | INT16_ ddItemCount                 { PASM->EmitData(NULL, sizeof(__int16)*$2); }
1092                         | INT8_ ddItemCount                  { PASM->EmitData(NULL, sizeof(__int8)*$2); }
1093                         ;
1094
1095 /*  Default values declaration for fields, parameters and verbal form of CA blob description  */
1096 fieldSerInit            : FLOAT32_ '(' float64 ')'           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4);
1097                                                                float f = (float)(*$3);
1098                                                                $$->appendInt32(*((__int32*)&f)); delete $3; }
1099                         | FLOAT64_ '(' float64 ')'           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8); 
1100                                                                $$->appendInt64((__int64 *)$3); delete $3; }
1101                         | FLOAT32_ '(' int32 ')'             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4); 
1102                                                                $$->appendInt32($3); }
1103                         | FLOAT64_ '(' int64 ')'             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8); 
1104                                                                $$->appendInt64((__int64 *)$3); delete $3; }
1105                         | INT64_ '(' int64 ')'               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I8); 
1106                                                                $$->appendInt64((__int64 *)$3); delete $3; } 
1107                         | INT32_ '(' int32 ')'               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I4); 
1108                                                                $$->appendInt32($3); }
1109                         | INT16_ '(' int32 ')'               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I2); 
1110                                                                $$->appendInt16($3); }
1111                         | INT8_ '(' int32 ')'                { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I1); 
1112                                                                $$->appendInt8($3); }
1113                         | UNSIGNED_ INT64_ '(' int64 ')'     { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); 
1114                                                                $$->appendInt64((__int64 *)$4); delete $4; } 
1115                         | UNSIGNED_ INT32_ '(' int32 ')'     { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); 
1116                                                                $$->appendInt32($4); }
1117                         | UNSIGNED_ INT16_ '(' int32 ')'     { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); 
1118                                                                $$->appendInt16($4); }
1119                         | UNSIGNED_ INT8_ '(' int32 ')'      { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); 
1120                                                                $$->appendInt8($4); }
1121                         | UINT64_ '(' int64 ')'              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); 
1122                                                                $$->appendInt64((__int64 *)$3); delete $3; } 
1123                         | UINT32_ '(' int32 ')'              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); 
1124                                                                $$->appendInt32($3); }
1125                         | UINT16_ '(' int32 ')'              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); 
1126                                                                $$->appendInt16($3); }
1127                         | UINT8_ '(' int32 ')'               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); 
1128                                                                $$->appendInt8($3); }
1129                         | CHAR_ '(' int32 ')'                { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CHAR); 
1130                                                                $$->appendInt16($3); }
1131                         | BOOL_ '(' truefalse ')'            { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_BOOLEAN); 
1132                                                                $$->appendInt8($3);}
1133                         | bytearrayhead bytes ')'            { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING);
1134                                                                $$->append($2); delete $2;}
1135                         ;
1136                         
1137 bytearrayhead           : BYTEARRAY_ '('                     { bParsingByteArray = TRUE; }
1138                         ;
1139
1140 bytes                   : /* EMPTY */                        { $$ = new BinStr(); }
1141                         | hexbytes                           { $$ = $1; }
1142                         ;
1143
1144 hexbytes                : HEXBYTE                            { __int8 i = (__int8) $1; $$ = new BinStr(); $$->appendInt8(i); }
1145                         | hexbytes HEXBYTE                   { __int8 i = (__int8) $2; $$ = $1; $$->appendInt8(i); }
1146                         ;
1147
1148 /*  Field/parameter initialization  */
1149 fieldInit               : fieldSerInit                       { $$ = $1; }
1150                         | compQstring                        { $$ = BinStrToUnicode($1,true); $$->insertInt8(ELEMENT_TYPE_STRING);}
1151                         | NULLREF_                           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CLASS); 
1152                                                                $$->appendInt32(0); }
1153                         ;                        
1154
1155 /*  Values for verbal form of CA blob description  */
1156 serInit                 : fieldSerInit                       { $$ = $1; }
1157                         | STRING_ '(' NULLREF_ ')'           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); $$->appendInt8(0xFF); }
1158                         | STRING_ '(' SQSTRING ')'           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); 
1159                                                                AppendStringWithLength($$,$3); delete [] $3;}
1160                         | TYPE_ '(' CLASS_ SQSTRING ')'      { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); 
1161                                                                AppendStringWithLength($$,$4); delete [] $4;}
1162                         | TYPE_ '(' className ')'            { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); 
1163                                                                AppendStringWithLength($$,PASM->ReflectionNotation($3));}
1164                         | TYPE_ '(' NULLREF_ ')'             { $$ = new BinStr(); $$->appendInt8(SERIALIZATION_TYPE_TYPE); $$->appendInt8(0xFF); }
1165                         | OBJECT_ '(' serInit ')'            { $$ = $3; $$->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);} 
1166                         | FLOAT32_ '[' int32 ']' '(' f32seq ')'
1167                                                              { $$ = $6; $$->insertInt32($3);
1168                                                                $$->insertInt8(ELEMENT_TYPE_R4);
1169                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1170                         | FLOAT64_ '[' int32 ']' '(' f64seq ')'
1171                                                              { $$ = $6; $$->insertInt32($3);
1172                                                                $$->insertInt8(ELEMENT_TYPE_R8);
1173                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1174                         | INT64_ '[' int32 ']' '(' i64seq ')'
1175                                                              { $$ = $6; $$->insertInt32($3);
1176                                                                $$->insertInt8(ELEMENT_TYPE_I8);
1177                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1178                         | INT32_ '[' int32 ']' '(' i32seq ')'
1179                                                              { $$ = $6; $$->insertInt32($3);
1180                                                                $$->insertInt8(ELEMENT_TYPE_I4);
1181                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1182                         | INT16_ '[' int32 ']' '(' i16seq ')'
1183                                                              { $$ = $6; $$->insertInt32($3);
1184                                                                $$->insertInt8(ELEMENT_TYPE_I2);
1185                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1186                         | INT8_ '[' int32 ']' '(' i8seq ')'
1187                                                              { $$ = $6; $$->insertInt32($3);
1188                                                                $$->insertInt8(ELEMENT_TYPE_I1);
1189                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1190                         | UINT64_ '[' int32 ']' '(' i64seq ')'
1191                                                              { $$ = $6; $$->insertInt32($3);
1192                                                                $$->insertInt8(ELEMENT_TYPE_U8);
1193                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1194                         | UINT32_ '[' int32 ']' '(' i32seq ')'
1195                                                              { $$ = $6; $$->insertInt32($3);
1196                                                                $$->insertInt8(ELEMENT_TYPE_U4);
1197                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1198                         | UINT16_ '[' int32 ']' '(' i16seq ')'
1199                                                              { $$ = $6; $$->insertInt32($3);
1200                                                                $$->insertInt8(ELEMENT_TYPE_U2);
1201                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1202                         | UINT8_ '[' int32 ']' '(' i8seq ')'
1203                                                              { $$ = $6; $$->insertInt32($3);
1204                                                                $$->insertInt8(ELEMENT_TYPE_U1);
1205                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1206                         | UNSIGNED_ INT64_ '[' int32 ']' '(' i64seq ')'
1207                                                              { $$ = $7; $$->insertInt32($4);
1208                                                                $$->insertInt8(ELEMENT_TYPE_U8);
1209                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1210                         | UNSIGNED_ INT32_ '[' int32 ']' '(' i32seq ')'
1211                                                              { $$ = $7; $$->insertInt32($4);
1212                                                                $$->insertInt8(ELEMENT_TYPE_U4);
1213                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1214                         | UNSIGNED_ INT16_ '[' int32 ']' '(' i16seq ')'
1215                                                              { $$ = $7; $$->insertInt32($4);
1216                                                                $$->insertInt8(ELEMENT_TYPE_U2);
1217                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1218                         | UNSIGNED_ INT8_ '[' int32 ']' '(' i8seq ')'
1219                                                              { $$ = $7; $$->insertInt32($4);
1220                                                                $$->insertInt8(ELEMENT_TYPE_U1);
1221                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1222                         | CHAR_ '[' int32 ']' '(' i16seq ')'
1223                                                              { $$ = $6; $$->insertInt32($3);
1224                                                                $$->insertInt8(ELEMENT_TYPE_CHAR);
1225                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1226                         | BOOL_ '[' int32 ']' '(' boolSeq ')'
1227                                                              { $$ = $6; $$->insertInt32($3);
1228                                                                $$->insertInt8(ELEMENT_TYPE_BOOLEAN);
1229                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1230                         | STRING_ '[' int32 ']' '(' sqstringSeq ')'
1231                                                              { $$ = $6; $$->insertInt32($3);
1232                                                                $$->insertInt8(ELEMENT_TYPE_STRING);
1233                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1234                         | TYPE_ '[' int32 ']' '(' classSeq ')'
1235                                                              { $$ = $6; $$->insertInt32($3);
1236                                                                $$->insertInt8(SERIALIZATION_TYPE_TYPE);
1237                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1238                         | OBJECT_ '[' int32 ']' '(' objSeq ')'
1239                                                              { $$ = $6; $$->insertInt32($3);
1240                                                                $$->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);
1241                                                                $$->insertInt8(ELEMENT_TYPE_SZARRAY); }
1242                         ;
1243
1244
1245 f32seq                  : /* EMPTY */                        { $$ = new BinStr(); }
1246                         | f32seq float64                     { $$ = $1;
1247                                                                float f = (float) (*$2); $$->appendInt32(*((__int32*)&f)); delete $2; }
1248                         | f32seq int32                       { $$ = $1; 
1249                                                                $$->appendInt32($2); }
1250                         ;
1251                                                                
1252 f64seq                  : /* EMPTY */                        { $$ = new BinStr(); }
1253                         | f64seq float64                     { $$ = $1; 
1254                                                                $$->appendInt64((__int64 *)$2); delete $2; }
1255                         | f64seq int64                       { $$ = $1; 
1256                                                                $$->appendInt64((__int64 *)$2); delete $2; }
1257                         ;
1258                         
1259 i64seq                  : /* EMPTY */                        { $$ = new BinStr(); }
1260                         | i64seq int64                       { $$ = $1; 
1261                                                                $$->appendInt64((__int64 *)$2); delete $2; }
1262                         ;
1263                         
1264 i32seq                  : /* EMPTY */                        { $$ = new BinStr(); }
1265                         | i32seq int32                       { $$ = $1; $$->appendInt32($2);}
1266                         ;
1267                         
1268 i16seq                  : /* EMPTY */                        { $$ = new BinStr(); }
1269                         | i16seq int32                       { $$ = $1; $$->appendInt16($2);}
1270                         ;
1271                         
1272 i8seq                   : /* EMPTY */                        { $$ = new BinStr(); }
1273                         | i8seq int32                        { $$ = $1; $$->appendInt8($2); }
1274                         ;
1275                         
1276 boolSeq                 : /* EMPTY */                        { $$ = new BinStr(); }
1277                         | boolSeq truefalse                  { $$ = $1; 
1278                                                                $$->appendInt8($2);}
1279                         ;
1280                         
1281 sqstringSeq             : /* EMPTY */                        { $$ = new BinStr(); }
1282                         | sqstringSeq NULLREF_               { $$ = $1; $$->appendInt8(0xFF); }
1283                         | sqstringSeq SQSTRING               { $$ = $1; 
1284                                                                AppendStringWithLength($$,$2); delete [] $2;}
1285                         ;
1286                         
1287 classSeq                : /* EMPTY */                        { $$ = new BinStr(); }
1288                         | classSeq NULLREF_                  { $$ = $1; $$->appendInt8(0xFF); }
1289                         | classSeq CLASS_ SQSTRING           { $$ = $1; 
1290                                                                AppendStringWithLength($$,$3); delete [] $3;}
1291                         | classSeq className                 { $$ = $1; 
1292                                                                AppendStringWithLength($$,PASM->ReflectionNotation($2));}
1293                         ;
1294                         
1295 objSeq                  : /* EMPTY */                        { $$ = new BinStr(); }
1296                         | objSeq serInit                     { $$ = $1; $$->append($2); delete $2; }
1297                         ;
1298
1299 /*  IL instructions and associated definitions  */
1300 methodSpec              : METHOD_                            { parser->m_ANSFirst.PUSH(PASM->m_firstArgName);
1301                                                                parser->m_ANSLast.PUSH(PASM->m_lastArgName);   
1302                                                                PASM->m_firstArgName = NULL;
1303                                                                PASM->m_lastArgName = NULL; }
1304                         ;
1305                         
1306 instr_none              : INSTR_NONE                         { $$ = SetupInstr($1); }
1307                         ;
1308
1309 instr_var               : INSTR_VAR                          { $$ = SetupInstr($1); }
1310                         ;
1311
1312 instr_i                 : INSTR_I                            { $$ = SetupInstr($1); }
1313                         ;
1314
1315 instr_i8                : INSTR_I8                           { $$ = SetupInstr($1); }
1316                         ;
1317
1318 instr_r                 : INSTR_R                            { $$ = SetupInstr($1); }
1319                         ;
1320
1321 instr_brtarget          : INSTR_BRTARGET                     { $$ = SetupInstr($1); }
1322                         ;
1323
1324 instr_method            : INSTR_METHOD                       { $$ = SetupInstr($1); 
1325                                                                if((!PASM->OnErrGo)&&
1326                                                                (($1 == CEE_NEWOBJ)||
1327                                                                 ($1 == CEE_CALLVIRT))) 
1328                                                                   iCallConv = IMAGE_CEE_CS_CALLCONV_HASTHIS;
1329                                                              }
1330                         ;
1331
1332 instr_field             : INSTR_FIELD                        { $$ = SetupInstr($1); }
1333                         ;
1334
1335 instr_type              : INSTR_TYPE                         { $$ = SetupInstr($1); }
1336                         ;
1337
1338 instr_string            : INSTR_STRING                       { $$ = SetupInstr($1); }
1339                         ;
1340
1341 instr_sig               : INSTR_SIG                          { $$ = SetupInstr($1); }
1342                         ;
1343
1344 instr_tok               : INSTR_TOK                          { $$ = SetupInstr($1); iOpcodeLen = PASM->OpcodeLen($$); }
1345                         ;
1346
1347 instr_switch            : INSTR_SWITCH                       { $$ = SetupInstr($1); }
1348                         ;
1349
1350 instr_r_head            : instr_r '('                        { $$ = $1; bParsingByteArray = TRUE; }
1351                         ;
1352
1353
1354 instr                   : instr_none                         { PASM->EmitOpcode($1); }
1355                         | instr_var int32                    { PASM->EmitInstrVar($1, $2); }
1356                         | instr_var id                       { PASM->EmitInstrVarByName($1, $2); }
1357                         | instr_i int32                      { PASM->EmitInstrI($1, $2); }
1358                         | instr_i8 int64                     { PASM->EmitInstrI8($1, $2); }
1359                         | instr_r float64                    { PASM->EmitInstrR($1, $2); delete ($2);}
1360                         | instr_r int64                      { double f = (double) (*$2); PASM->EmitInstrR($1, &f); }
1361                         | instr_r_head bytes ')'             { unsigned L = $2->length();
1362                                                                FAIL_UNLESS(L >= sizeof(float), ("%d hexbytes, must be at least %d\n",
1363                                                                            L,sizeof(float))); 
1364                                                                if(L < sizeof(float)) {YYERROR; } 
1365                                                                else {
1366                                                                    double f = (L >= sizeof(double)) ? *((double *)($2->ptr()))
1367                                                                                     : (double)(*(float *)($2->ptr())); 
1368                                                                    PASM->EmitInstrR($1,&f); }
1369                                                                delete $2; }
1370                         | instr_brtarget int32               { PASM->EmitInstrBrOffset($1, $2); }
1371                         | instr_brtarget id                  { PASM->EmitInstrBrTarget($1, $2); }
1372                         | instr_method methodRef
1373                                                              { PASM->SetMemberRefFixup($2,PASM->OpcodeLen($1));
1374                                                                PASM->EmitInstrI($1,$2);
1375                                                                PASM->m_tkCurrentCVOwner = $2;
1376                                                                PASM->m_pCustomDescrList = NULL;
1377                                                                iCallConv = 0;
1378                                                              }
1379                         | instr_field type typeSpec DCOLON dottedName
1380                                                              { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD); 
1381                                                                mdToken mr = PASM->MakeMemberRef($3, $5, $2);
1382                                                                PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
1383                                                                PASM->EmitInstrI($1,mr);
1384                                                                PASM->m_tkCurrentCVOwner = mr;
1385                                                                PASM->m_pCustomDescrList = NULL;
1386                                                              }
1387                         | instr_field type dottedName
1388                                                              { $2->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD); 
1389                                                                mdToken mr = PASM->MakeMemberRef(mdTokenNil, $3, $2);
1390                                                                PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
1391                                                                PASM->EmitInstrI($1,mr);
1392                                                                PASM->m_tkCurrentCVOwner = mr;
1393                                                                PASM->m_pCustomDescrList = NULL;
1394                                                              }
1395                         | instr_field mdtoken                { mdToken mr = $2;
1396                                                                PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
1397                                                                PASM->EmitInstrI($1,mr);
1398                                                                PASM->m_tkCurrentCVOwner = mr;
1399                                                                PASM->m_pCustomDescrList = NULL;
1400                                                              }
1401                         | instr_field TYPEDEF_F              { mdToken mr = $2->m_tkTypeSpec;
1402                                                                PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
1403                                                                PASM->EmitInstrI($1,mr);
1404                                                                PASM->m_tkCurrentCVOwner = mr;
1405                                                                PASM->m_pCustomDescrList = NULL;
1406                                                              }
1407                         | instr_field TYPEDEF_MR             { mdToken mr = $2->m_tkTypeSpec;
1408                                                                PASM->SetMemberRefFixup(mr, PASM->OpcodeLen($1));
1409                                                                PASM->EmitInstrI($1,mr);
1410                                                                PASM->m_tkCurrentCVOwner = mr;
1411                                                                PASM->m_pCustomDescrList = NULL;
1412                                                              }
1413                         | instr_type typeSpec                { PASM->EmitInstrI($1, $2); 
1414                                                                PASM->m_tkCurrentCVOwner = $2;
1415                                                                PASM->m_pCustomDescrList = NULL;
1416                                                              }
1417                         | instr_string compQstring           { PASM->EmitInstrStringLiteral($1, $2,TRUE); }
1418                         | instr_string ANSI_ '(' compQstring ')'
1419                                                              { PASM->EmitInstrStringLiteral($1, $4,FALSE); }
1420                         | instr_string bytearrayhead bytes ')'
1421                                                              { PASM->EmitInstrStringLiteral($1, $3,FALSE,TRUE); }
1422                         | instr_sig callConv type '(' sigArgs0 ')'      
1423                                                              { PASM->EmitInstrSig($1, parser->MakeSig($2, $3, $5)); 
1424                                                                PASM->ResetArgNameList();
1425                                                              }
1426                         | instr_tok ownerType /* ownerType ::= memberRef | typeSpec */
1427                                                              { PASM->EmitInstrI($1,$2);
1428                                                                PASM->m_tkCurrentCVOwner = $2;
1429                                                                PASM->m_pCustomDescrList = NULL;
1430                                                                iOpcodeLen = 0;
1431                                                              }
1432                         | instr_switch '(' labels ')'        { PASM->EmitInstrSwitch($1, $3); }
1433                         ;
1434                         
1435 labels                  : /* empty */                         { $$ = 0; }
1436                         | id ',' labels                       { $$ = new Labels($1, $3, TRUE); }
1437                         | int32 ',' labels                    { $$ = new Labels((char *)(UINT_PTR)$1, $3, FALSE); }
1438                         | id                                  { $$ = new Labels($1, NULL, TRUE); }
1439                         | int32                               { $$ = new Labels((char *)(UINT_PTR)$1, NULL, FALSE); }
1440                         ;
1441
1442 /*  Signatures  */
1443 tyArgs0                 : /* EMPTY */                        { $$ = NULL; }
1444                         | '<' tyArgs1 '>'                    { $$ = $2; }
1445                         ;
1446
1447 tyArgs1                 : /* EMPTY */                        { $$ = NULL; }
1448                         | tyArgs2                            { $$ = $1; }
1449                         ;
1450
1451 tyArgs2                 : type                               { $$ = $1; }
1452                         | tyArgs2 ',' type                   { $$ = $1; $$->append($3); delete $3; }
1453                         ;
1454
1455
1456 sigArgs0                : /* EMPTY */                        { $$ = new BinStr(); }
1457                         | sigArgs1                           { $$ = $1;}
1458                         ;
1459
1460 sigArgs1                : sigArg                             { $$ = $1; }
1461                         | sigArgs1 ',' sigArg                { $$ = $1; $$->append($3); delete $3; }
1462                         ;
1463
1464 sigArg                  : ELIPSIS                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_SENTINEL); }
1465                         | paramAttr type marshalClause        { $$ = new BinStr(); $$->append($2); PASM->addArgName(NULL, $2, $3, $1); }
1466                         | paramAttr type marshalClause id     { $$ = new BinStr(); $$->append($2); PASM->addArgName($4, $2, $3, $1);}
1467                         ;
1468
1469 /*  Class referencing  */
1470 className               : '[' dottedName ']' slashedName      { $$ = PASM->ResolveClassRef(PASM->GetAsmRef($2), $4, NULL); delete[] $2;}
1471                         | '[' mdtoken ']' slashedName         { $$ = PASM->ResolveClassRef($2, $4, NULL); }
1472                         | '[' '*' ']' slashedName             { $$ = PASM->ResolveClassRef(mdTokenNil, $4, NULL); }
1473                         | '[' _MODULE dottedName ']' slashedName   { $$ = PASM->ResolveClassRef(PASM->GetModRef($3),$5, NULL); delete[] $3;}
1474                         | slashedName                         { $$ = PASM->ResolveClassRef(1,$1,NULL); }
1475                         | mdtoken                             { $$ = $1; }
1476                         | TYPEDEF_T                           { $$ = $1->m_tkTypeSpec; }
1477                         | _THIS                               { if(PASM->m_pCurClass != NULL) $$ = PASM->m_pCurClass->m_cl;
1478                                                                 else { $$ = 0; PASM->report->error(".this outside class scope\n"); } 
1479                                                               }
1480                         | _BASE                               { if(PASM->m_pCurClass != NULL) {
1481                                                                   $$ = PASM->m_pCurClass->m_crExtends;
1482                                                                   if(RidFromToken($$) == 0)
1483                                                                     PASM->report->error(".base undefined\n");
1484                                                                 } else { $$ = 0; PASM->report->error(".base outside class scope\n"); } 
1485                                                               }
1486                         | _NESTER                             { if(PASM->m_pCurClass != NULL) {
1487                                                                   if(PASM->m_pCurClass->m_pEncloser != NULL) $$ = PASM->m_pCurClass->m_pEncloser->m_cl;
1488                                                                   else { $$ = 0; PASM->report->error(".nester undefined\n"); }
1489                                                                 } else { $$ = 0; PASM->report->error(".nester outside class scope\n"); } 
1490                                                               }
1491                         ;
1492
1493 slashedName             : dottedName                          { $$ = $1; }
1494                         | slashedName '/' dottedName          { $$ = newStringWDel($1, NESTING_SEP, $3); }
1495                         ;
1496
1497 typeSpec                : className                           { $$ = $1;}
1498                         | '[' dottedName ']'                  { $$ = PASM->GetAsmRef($2); delete[] $2;}
1499                         | '[' _MODULE dottedName ']'          { $$ = PASM->GetModRef($3); delete[] $3;}
1500                         | type                                { $$ = PASM->ResolveTypeSpec($1); }
1501                         ;
1502
1503 /*  Native types for marshaling signatures  */                         
1504 nativeType              : /* EMPTY */                         { $$ = new BinStr(); } 
1505                         | CUSTOM_ '(' compQstring ',' compQstring ',' compQstring ',' compQstring ')'
1506                                                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
1507                                                                 corEmitInt($$,$3->length()); $$->append($3);
1508                                                                 corEmitInt($$,$5->length()); $$->append($5);
1509                                                                 corEmitInt($$,$7->length()); $$->append($7);
1510                                                                 corEmitInt($$,$9->length()); $$->append($9); 
1511                                                                 PASM->report->warn("Deprecated 4-string form of custom marshaler, first two strings ignored\n");}
1512                         | CUSTOM_ '(' compQstring ',' compQstring ')'
1513                                                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
1514                                                                 corEmitInt($$,0);
1515                                                                 corEmitInt($$,0);
1516                                                                 corEmitInt($$,$3->length()); $$->append($3);
1517                                                                 corEmitInt($$,$5->length()); $$->append($5); }
1518                         | FIXED_ SYSSTRING_ '[' int32 ']'     { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FIXEDSYSSTRING);
1519                                                                 corEmitInt($$,$4); }
1520                         | FIXED_ ARRAY_ '[' int32 ']' nativeType
1521                                                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FIXEDARRAY);
1522                                                                 corEmitInt($$,$4); $$->append($6); }
1523                         | VARIANT_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VARIANT); 
1524                                                                 PASM->report->warn("Deprecated native type 'variant'\n"); }
1525                         | CURRENCY_                           { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_CURRENCY); }
1526                         | SYSCHAR_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SYSCHAR); 
1527                                                                 PASM->report->warn("Deprecated native type 'syschar'\n"); }
1528                         | VOID_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VOID); 
1529                                                                 PASM->report->warn("Deprecated native type 'void'\n"); }
1530                         | BOOL_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BOOLEAN); }
1531                         | INT8_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I1); }
1532                         | INT16_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I2); }
1533                         | INT32_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I4); }
1534                         | INT64_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_I8); }
1535                         | FLOAT32_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_R4); }
1536                         | FLOAT64_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_R8); }
1537                         | ERROR_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ERROR); }
1538                         | UNSIGNED_ INT8_                     { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U1); }
1539                         | UNSIGNED_ INT16_                    { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U2); }
1540                         | UNSIGNED_ INT32_                    { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U4); }
1541                         | UNSIGNED_ INT64_                    { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U8); }
1542                         | UINT8_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U1); }
1543                         | UINT16_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U2); }
1544                         | UINT32_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U4); }
1545                         | UINT64_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_U8); }
1546                         | nativeType '*'                      { $$ = $1; $$->insertInt8(NATIVE_TYPE_PTR); 
1547                                                                 PASM->report->warn("Deprecated native type '*'\n"); }
1548                         | nativeType '[' ']'                  { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX);
1549                                                                 $$->insertInt8(NATIVE_TYPE_ARRAY); }
1550                         | nativeType '[' int32 ']'            { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX); 
1551                                                                 $$->insertInt8(NATIVE_TYPE_ARRAY);
1552                                                                 corEmitInt($$,0);
1553                                                                 corEmitInt($$,$3); 
1554                                                                 corEmitInt($$,0); }
1555                         | nativeType '[' int32 '+' int32 ']'  { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX); 
1556                                                                 $$->insertInt8(NATIVE_TYPE_ARRAY);
1557                                                                 corEmitInt($$,$5);
1558                                                                 corEmitInt($$,$3);
1559                                                                 corEmitInt($$,ntaSizeParamIndexSpecified); }
1560                         | nativeType '[' '+' int32 ']'        { $$ = $1; if($$->length()==0) $$->appendInt8(NATIVE_TYPE_MAX); 
1561                                                                 $$->insertInt8(NATIVE_TYPE_ARRAY);
1562                                                                 corEmitInt($$,$4); }
1563                         | DECIMAL_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_DECIMAL); 
1564                                                                 PASM->report->warn("Deprecated native type 'decimal'\n"); }
1565                         | DATE_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_DATE); 
1566                                                                 PASM->report->warn("Deprecated native type 'date'\n"); }
1567                         | BSTR_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BSTR); }
1568                         | LPSTR_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPSTR); }
1569                         | LPWSTR_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPWSTR); }
1570                         | LPTSTR_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPTSTR); }
1571                         | OBJECTREF_                          { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_OBJECTREF); 
1572                                                                 PASM->report->warn("Deprecated native type 'objectref'\n"); }
1573                         | IUNKNOWN_  iidParamIndex            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_IUNKNOWN);
1574                                                                 if($2 != -1) corEmitInt($$,$2); }
1575                         | IDISPATCH_ iidParamIndex            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_IDISPATCH); 
1576                                                                 if($2 != -1) corEmitInt($$,$2); }
1577                         | STRUCT_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_STRUCT); }
1578                         | INTERFACE_ iidParamIndex            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_INTF);
1579                                                                 if($2 != -1) corEmitInt($$,$2); }
1580                         | SAFEARRAY_ variantType              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SAFEARRAY); 
1581                                                                 corEmitInt($$,$2); 
1582                                                                 corEmitInt($$,0);}
1583                         | SAFEARRAY_ variantType ',' compQstring { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_SAFEARRAY); 
1584                                                                 corEmitInt($$,$2); 
1585                                                                 corEmitInt($$,$4->length()); $$->append($4); }
1586                                                                 
1587                         | INT_                                { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_INT); }
1588                         | UNSIGNED_ INT_                      { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_UINT); }
1589                         | UINT_                               { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_UINT); }
1590                         | NESTED_ STRUCT_                     { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_NESTEDSTRUCT); 
1591                                                                 PASM->report->warn("Deprecated native type 'nested struct'\n"); }
1592                         | BYVALSTR_                           { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_BYVALSTR); }
1593                         | ANSI_ BSTR_                         { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ANSIBSTR); }
1594                         | TBSTR_                              { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_TBSTR); }
1595                         | VARIANT_ BOOL_                      { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_VARIANTBOOL); }
1596                         | METHOD_                             { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_FUNC); }
1597                         | AS_ ANY_                            { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_ASANY); }
1598                         | LPSTRUCT_                           { $$ = new BinStr(); $$->appendInt8(NATIVE_TYPE_LPSTRUCT); }
1599                         | TYPEDEF_TS                          { $$ = new BinStr(); $$->append($1->m_pbsTypeSpec); }
1600                         ;
1601                         
1602 iidParamIndex           : /* EMPTY */                         { $$ = -1; }
1603                         | '(' IIDPARAM_ '=' int32 ')'         { $$ = $4; }
1604                         ;                        
1605
1606 variantType             : /* EMPTY */                         { $$ = VT_EMPTY; }
1607                         | NULL_                               { $$ = VT_NULL; }
1608                         | VARIANT_                            { $$ = VT_VARIANT; }
1609                         | CURRENCY_                           { $$ = VT_CY; }
1610                         | VOID_                               { $$ = VT_VOID; }
1611                         | BOOL_                               { $$ = VT_BOOL; }
1612                         | INT8_                               { $$ = VT_I1; }
1613                         | INT16_                              { $$ = VT_I2; }
1614                         | INT32_                              { $$ = VT_I4; }
1615                         | INT64_                              { $$ = VT_I8; }
1616                         | FLOAT32_                            { $$ = VT_R4; }
1617                         | FLOAT64_                            { $$ = VT_R8; }
1618                         | UNSIGNED_ INT8_                     { $$ = VT_UI1; }
1619                         | UNSIGNED_ INT16_                    { $$ = VT_UI2; }
1620                         | UNSIGNED_ INT32_                    { $$ = VT_UI4; }
1621                         | UNSIGNED_ INT64_                    { $$ = VT_UI8; }
1622                         | UINT8_                              { $$ = VT_UI1; }
1623                         | UINT16_                             { $$ = VT_UI2; }
1624                         | UINT32_                             { $$ = VT_UI4; }
1625                         | UINT64_                             { $$ = VT_UI8; }
1626                         | '*'                                 { $$ = VT_PTR; }
1627                         | variantType '[' ']'                 { $$ = $1 | VT_ARRAY; }
1628                         | variantType VECTOR_                 { $$ = $1 | VT_VECTOR; }
1629                         | variantType '&'                     { $$ = $1 | VT_BYREF; }
1630                         | DECIMAL_                            { $$ = VT_DECIMAL; }
1631                         | DATE_                               { $$ = VT_DATE; }
1632                         | BSTR_                               { $$ = VT_BSTR; }
1633                         | LPSTR_                              { $$ = VT_LPSTR; }
1634                         | LPWSTR_                             { $$ = VT_LPWSTR; }
1635                         | IUNKNOWN_                           { $$ = VT_UNKNOWN; }
1636                         | IDISPATCH_                          { $$ = VT_DISPATCH; }
1637                         | SAFEARRAY_                          { $$ = VT_SAFEARRAY; }
1638                         | INT_                                { $$ = VT_INT; }
1639                         | UNSIGNED_ INT_                      { $$ = VT_UINT; }
1640                         | UINT_                               { $$ = VT_UINT; }
1641                         | ERROR_                              { $$ = VT_ERROR; }
1642                         | HRESULT_                            { $$ = VT_HRESULT; }
1643                         | CARRAY_                             { $$ = VT_CARRAY; }
1644                         | USERDEFINED_                        { $$ = VT_USERDEFINED; }
1645                         | RECORD_                             { $$ = VT_RECORD; }
1646                         | FILETIME_                           { $$ = VT_FILETIME; }
1647                         | BLOB_                               { $$ = VT_BLOB; }
1648                         | STREAM_                             { $$ = VT_STREAM; }
1649                         | STORAGE_                            { $$ = VT_STORAGE; }
1650                         | STREAMED_OBJECT_                    { $$ = VT_STREAMED_OBJECT; }
1651                         | STORED_OBJECT_                      { $$ = VT_STORED_OBJECT; }
1652                         | BLOB_OBJECT_                        { $$ = VT_BLOB_OBJECT; }
1653                         | CF_                                 { $$ = VT_CF; }
1654                         | CLSID_                              { $$ = VT_CLSID; }
1655                         ;
1656
1657 /*  Managed types for signatures  */                        
1658 type                    : CLASS_ className                    { if($2 == PASM->m_tkSysString)
1659                                                                 {     $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); }
1660                                                                 else if($2 == PASM->m_tkSysObject)
1661                                                                 {     $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_OBJECT); }
1662                                                                 else  
1663                                                                  $$ = parser->MakeTypeClass(ELEMENT_TYPE_CLASS, $2); } 
1664                         | OBJECT_                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_OBJECT); } 
1665                         | VALUE_ CLASS_ className             { $$ = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, $3); } 
1666                         | VALUETYPE_ className                { $$ = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, $2); } 
1667                         | type '[' ']'                        { $$ = $1; $$->insertInt8(ELEMENT_TYPE_SZARRAY); } 
1668                         | type '[' bounds1 ']'                { $$ = parser->MakeTypeArray(ELEMENT_TYPE_ARRAY, $1, $3); } 
1669                         | type '&'                            { $$ = $1; $$->insertInt8(ELEMENT_TYPE_BYREF); }
1670                         | type '*'                            { $$ = $1; $$->insertInt8(ELEMENT_TYPE_PTR); }
1671                         | type PINNED_                        { $$ = $1; $$->insertInt8(ELEMENT_TYPE_PINNED); }
1672                         | type MODREQ_ '(' typeSpec ')'       { $$ = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_REQD, $4);
1673                                                                 $$->append($1); }
1674                         | type MODOPT_ '(' typeSpec ')'       { $$ = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_OPT, $4);
1675                                                                 $$->append($1); }
1676                         | methodSpec callConv type '*' '(' sigArgs0 ')'  
1677                                                               { $$ = parser->MakeSig($2, $3, $6);
1678                                                                 $$->insertInt8(ELEMENT_TYPE_FNPTR); 
1679                                                                 PASM->delArgNameList(PASM->m_firstArgName);
1680                                                                 PASM->m_firstArgName = parser->m_ANSFirst.POP();
1681                                                                 PASM->m_lastArgName = parser->m_ANSLast.POP();
1682                                                               }
1683                         | type '<' tyArgs1 '>'                { if($3 == NULL) $$ = $1;
1684                                                                 else {
1685                                                                   $$ = new BinStr(); 
1686                                                                   $$->appendInt8(ELEMENT_TYPE_GENERICINST); 
1687                                                                   $$->append($1);
1688                                                                   corEmitInt($$, corCountArgs($3));
1689                                                                   $$->append($3); delete $1; delete $3; }}
1690                         | '!' '!' int32                       { //if(PASM->m_pCurMethod)  {
1691                                                                 //  if(($3 < 0)||((DWORD)$3 >= PASM->m_pCurMethod->m_NumTyPars))
1692                                                                 //    PASM->report->error("Invalid method type parameter '%d'\n",$3);
1693                                                                   $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_MVAR); corEmitInt($$, $3); 
1694                                                                 //} else PASM->report->error("Method type parameter '%d' outside method scope\n",$3);
1695                                                               }
1696                         | '!' int32                           { //if(PASM->m_pCurClass)  {
1697                                                                 //  if(($2 < 0)||((DWORD)$2 >= PASM->m_pCurClass->m_NumTyPars))
1698                                                                 //    PASM->report->error("Invalid type parameter '%d'\n",$2);
1699                                                                   $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_VAR); corEmitInt($$, $2); 
1700                                                                 //} else PASM->report->error("Type parameter '%d' outside class scope\n",$2);
1701                                                               }
1702                         | '!' '!' dottedName                  { int eltype = ELEMENT_TYPE_MVAR;
1703                                                                 int n=-1;
1704                                                                 if(PASM->m_pCurMethod) n = PASM->m_pCurMethod->FindTyPar($3);
1705                                                                 else {
1706                                                                   if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf($3);
1707                                                                   if(n == -1)
1708                                                                   { n = TyParFixupList.COUNT();
1709                                                                     TyParFixupList.PUSH($3);
1710                                                                     eltype = ELEMENT_TYPE_MVARFIXUP;
1711                                                                   }
1712                                                                 }
1713                                                                 if(n == -1) { PASM->report->error("Invalid method type parameter '%s'\n",$3);
1714                                                                 n = 0x1FFFFFFF; }
1715                                                                 $$ = new BinStr(); $$->appendInt8(eltype); corEmitInt($$,n); 
1716                                                               }
1717                         | '!' dottedName                      { int eltype = ELEMENT_TYPE_VAR;
1718                                                                 int n=-1;
1719                                                                 if(PASM->m_pCurClass && !newclass) n = PASM->m_pCurClass->FindTyPar($2);
1720                                                                 else {
1721                                                                   if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf($2);
1722                                                                   if(n == -1)
1723                                                                   { n = TyParFixupList.COUNT();
1724                                                                     TyParFixupList.PUSH($2);
1725                                                                     eltype = ELEMENT_TYPE_VARFIXUP;
1726                                                                   }
1727                                                                 }
1728                                                                 if(n == -1) { PASM->report->error("Invalid type parameter '%s'\n",$2);
1729                                                                 n = 0x1FFFFFFF; }
1730                                                                 $$ = new BinStr(); $$->appendInt8(eltype); corEmitInt($$,n); 
1731                                                               }
1732                         | TYPEDREF_                           { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_TYPEDBYREF); }
1733                         | VOID_                               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_VOID); }
1734                         | NATIVE_ INT_                        { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I); }
1735                         | NATIVE_ UNSIGNED_ INT_              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U); }
1736                         | NATIVE_ UINT_                       { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U); }
1737                         | simpleType                          { $$ = $1; }
1738                         | ELIPSIS type                        { $$ = $2; $$->insertInt8(ELEMENT_TYPE_SENTINEL); }
1739                         ;
1740                         
1741 simpleType              : CHAR_                               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_CHAR); }
1742                         | STRING_                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_STRING); } 
1743                         | BOOL_                               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_BOOLEAN); }
1744                         | INT8_                               { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I1); }
1745                         | INT16_                              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I2); }
1746                         | INT32_                              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I4); }
1747                         | INT64_                              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_I8); }
1748                         | FLOAT32_                            { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R4); }
1749                         | FLOAT64_                            { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_R8); }
1750                         | UNSIGNED_ INT8_                     { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); }
1751                         | UNSIGNED_ INT16_                    { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); }
1752                         | UNSIGNED_ INT32_                    { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); }
1753                         | UNSIGNED_ INT64_                    { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); }
1754                         | UINT8_                              { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U1); }
1755                         | UINT16_                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U2); }
1756                         | UINT32_                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U4); }
1757                         | UINT64_                             { $$ = new BinStr(); $$->appendInt8(ELEMENT_TYPE_U8); }
1758                         | TYPEDEF_TS                          { $$ = new BinStr(); $$->append($1->m_pbsTypeSpec); }
1759                         ;
1760                         
1761 bounds1                 : bound                               { $$ = $1; }
1762                         | bounds1 ',' bound                   { $$ = $1; $1->append($3); delete $3; }
1763                         ;
1764
1765 bound                   : /* EMPTY */                         { $$ = new BinStr(); $$->appendInt32(0x7FFFFFFF); $$->appendInt32(0x7FFFFFFF);  }
1766                         | ELIPSIS                             { $$ = new BinStr(); $$->appendInt32(0x7FFFFFFF); $$->appendInt32(0x7FFFFFFF);  }
1767                         | int32                               { $$ = new BinStr(); $$->appendInt32(0); $$->appendInt32($1); } 
1768                         | int32 ELIPSIS int32                 { FAIL_UNLESS($1 <= $3, ("lower bound %d must be <= upper bound %d\n", $1, $3));
1769                                                                 if ($1 > $3) { YYERROR; };        
1770                                                                 $$ = new BinStr(); $$->appendInt32($1); $$->appendInt32($3-$1+1); }   
1771                         | int32 ELIPSIS                       { $$ = new BinStr(); $$->appendInt32($1); $$->appendInt32(0x7FFFFFFF); } 
1772                         ;
1773
1774 /*  Security declarations  */                        
1775 secDecl                 : _PERMISSION secAction typeSpec '(' nameValPairs ')'
1776                                                               { PASM->AddPermissionDecl($2, $3, $5); }
1777                         | _PERMISSION secAction typeSpec '=' '{' customBlobDescr '}'
1778                                                               { PASM->AddPermissionDecl($2, $3, $6); }
1779                         | _PERMISSION secAction typeSpec      { PASM->AddPermissionDecl($2, $3, (NVPair *)NULL); }
1780                         | psetHead bytes ')'                  { PASM->AddPermissionSetDecl($1, $2); }
1781                         | _PERMISSIONSET secAction compQstring
1782                                                               { PASM->AddPermissionSetDecl($2,BinStrToUnicode($3,true));}
1783                         | _PERMISSIONSET secAction '=' '{' secAttrSetBlob '}'
1784                                                               { BinStr* ret = new BinStr();
1785                                                                 ret->insertInt8('.');
1786                                                                 corEmitInt(ret, nSecAttrBlobs);
1787                                                                 ret->append($5);
1788                                                                 PASM->AddPermissionSetDecl($2,ret);
1789                                                                 nSecAttrBlobs = 0; }
1790                         ;
1791                         
1792 secAttrSetBlob          : /* EMPTY */                         { $$ = new BinStr(); nSecAttrBlobs = 0;}
1793                         | secAttrBlob                         { $$ = $1; nSecAttrBlobs = 1; }
1794                         | secAttrBlob ',' secAttrSetBlob      { $$ = $1; $$->append($3); nSecAttrBlobs++; }
1795                         ;
1796                         
1797 secAttrBlob             : typeSpec '=' '{' customBlobNVPairs '}'
1798                                                               { $$ = PASM->EncodeSecAttr(PASM->ReflectionNotation($1),$4,nCustomBlobNVPairs); 
1799                                                                 nCustomBlobNVPairs = 0; }                                               
1800                         | CLASS_ SQSTRING '=' '{' customBlobNVPairs '}'
1801                                                               { $$ = PASM->EncodeSecAttr($2,$5,nCustomBlobNVPairs); 
1802                                                                 nCustomBlobNVPairs = 0; }
1803                         ;                                               
1804
1805 psetHead                : _PERMISSIONSET secAction '=' '('    { $$ = $2; bParsingByteArray = TRUE; }
1806                         | _PERMISSIONSET secAction BYTEARRAY_ '(' 
1807                                                               { $$ = $2; bParsingByteArray = TRUE; }
1808                         ;
1809
1810 nameValPairs            : nameValPair                         { $$ = $1; }
1811                         | nameValPair ',' nameValPairs        { $$ = $1->Concat($3); }
1812                         ;
1813
1814 nameValPair             : compQstring '=' caValue             { $1->appendInt8(0); $$ = new NVPair($1, $3); }
1815                         ;
1816
1817 truefalse               : TRUE_                               { $$ = 1; }
1818                         | FALSE_                              { $$ = 0; }
1819                         ;
1820
1821 caValue                 : truefalse                           { $$ = new BinStr();
1822                                                                 $$->appendInt8(SERIALIZATION_TYPE_BOOLEAN);
1823                                                                 $$->appendInt8($1); }
1824                         | int32                               { $$ = new BinStr();
1825                                                                 $$->appendInt8(SERIALIZATION_TYPE_I4);
1826                                                                 $$->appendInt32($1); }
1827                         | INT32_ '(' int32 ')'                { $$ = new BinStr();
1828                                                                 $$->appendInt8(SERIALIZATION_TYPE_I4);
1829                                                                 $$->appendInt32($3); }
1830                         | compQstring                         { $$ = new BinStr();
1831                                                                 $$->appendInt8(SERIALIZATION_TYPE_STRING);
1832                                                                 $$->append($1); delete $1;
1833                                                                 $$->appendInt8(0); }
1834                         | className '(' INT8_ ':' int32 ')'   { $$ = new BinStr();
1835                                                                 $$->appendInt8(SERIALIZATION_TYPE_ENUM);
1836                                                                 char* sz = PASM->ReflectionNotation($1);
1837                                                                 strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
1838                                                                 $$->appendInt8(1);
1839                                                                 $$->appendInt32($5); }
1840                         | className '(' INT16_ ':' int32 ')'  { $$ = new BinStr();
1841                                                                 $$->appendInt8(SERIALIZATION_TYPE_ENUM);
1842                                                                 char* sz = PASM->ReflectionNotation($1);
1843                                                                 strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
1844                                                                 $$->appendInt8(2);
1845                                                                 $$->appendInt32($5); }
1846                         | className '(' INT32_ ':' int32 ')'  { $$ = new BinStr();
1847                                                                 $$->appendInt8(SERIALIZATION_TYPE_ENUM);
1848                                                                 char* sz = PASM->ReflectionNotation($1);
1849                                                                 strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
1850                                                                 $$->appendInt8(4);
1851                                                                 $$->appendInt32($5); }
1852                         | className '(' int32 ')'             { $$ = new BinStr();
1853                                                                 $$->appendInt8(SERIALIZATION_TYPE_ENUM);
1854                                                                 char* sz = PASM->ReflectionNotation($1);
1855                                                                 strcpy_s((char *)$$->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
1856                                                                 $$->appendInt8(4);
1857                                                                 $$->appendInt32($3); }
1858                         ;
1859
1860 secAction               : REQUEST_                            { $$ = dclRequest; }
1861                         | DEMAND_                             { $$ = dclDemand; }
1862                         | ASSERT_                             { $$ = dclAssert; }
1863                         | DENY_                               { $$ = dclDeny; }
1864                         | PERMITONLY_                         { $$ = dclPermitOnly; }
1865                         | LINKCHECK_                          { $$ = dclLinktimeCheck; }
1866                         | INHERITCHECK_                       { $$ = dclInheritanceCheck; }
1867                         | REQMIN_                             { $$ = dclRequestMinimum; }
1868                         | REQOPT_                             { $$ = dclRequestOptional; }
1869                         | REQREFUSE_                          { $$ = dclRequestRefuse; }
1870                         | PREJITGRANT_                        { $$ = dclPrejitGrant; }
1871                         | PREJITDENY_                         { $$ = dclPrejitDenied; }
1872                         | NONCASDEMAND_                       { $$ = dclNonCasDemand; }
1873                         | NONCASLINKDEMAND_                   { $$ = dclNonCasLinkDemand; }
1874                         | NONCASINHERITANCE_                  { $$ = dclNonCasInheritance; }
1875                         ;
1876
1877 /*  External source declarations  */                        
1878 esHead                  : _LINE                               { PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = FALSE; }
1879                         | P_LINE                              { PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = TRUE; }
1880                         ;
1881                         
1882 extSourceSpec           : esHead int32 SQSTRING               { PENV->nExtLine = PENV->nExtLineEnd = $2;
1883                                                                 PENV->nExtCol = 0; PENV->nExtColEnd  = static_cast<unsigned>(-1);
1884                                                                 PASM->SetSourceFileName($3);}
1885                         | esHead int32                        { PENV->nExtLine = PENV->nExtLineEnd = $2;
1886                                                                 PENV->nExtCol = 0; PENV->nExtColEnd  = static_cast<unsigned>(-1); }
1887                         | esHead int32 ':' int32 SQSTRING     { PENV->nExtLine = PENV->nExtLineEnd = $2; 
1888                                                                 PENV->nExtCol=$4; PENV->nExtColEnd = static_cast<unsigned>(-1);
1889                                                                 PASM->SetSourceFileName($5);}
1890                         | esHead int32 ':' int32              { PENV->nExtLine = PENV->nExtLineEnd = $2; 
1891                                                                 PENV->nExtCol=$4; PENV->nExtColEnd = static_cast<unsigned>(-1);}
1892                         | esHead int32 ':' int32 ',' int32 SQSTRING     
1893                                                               { PENV->nExtLine = PENV->nExtLineEnd = $2; 
1894                                                                 PENV->nExtCol=$4; PENV->nExtColEnd = $6;
1895                                                                 PASM->SetSourceFileName($7);}
1896                         | esHead int32 ':' int32 ',' int32     
1897                                                               { PENV->nExtLine = PENV->nExtLineEnd = $2; 
1898                                                                 PENV->nExtCol=$4; PENV->nExtColEnd = $6; }
1899                         | esHead int32 ',' int32 ':' int32 SQSTRING     
1900                                                               { PENV->nExtLine = $2; PENV->nExtLineEnd = $4; 
1901                                                                 PENV->nExtCol=$6; PENV->nExtColEnd = static_cast<unsigned>(-1);
1902                                                                 PASM->SetSourceFileName($7);}
1903                         | esHead int32 ',' int32 ':' int32     
1904                                                               { PENV->nExtLine = $2; PENV->nExtLineEnd = $4; 
1905                                                                 PENV->nExtCol=$6; PENV->nExtColEnd = static_cast<unsigned>(-1); }
1906                         | esHead int32 ',' int32 ':' int32 ',' int32 SQSTRING     
1907                                                               { PENV->nExtLine = $2; PENV->nExtLineEnd = $4; 
1908                                                                 PENV->nExtCol=$6; PENV->nExtColEnd = $8;
1909                                                                 PASM->SetSourceFileName($9);}
1910                         | esHead int32 ',' int32 ':' int32 ',' int32     
1911                                                               { PENV->nExtLine = $2; PENV->nExtLineEnd = $4; 
1912                                                                 PENV->nExtCol=$6; PENV->nExtColEnd = $8; }
1913                         | esHead int32 QSTRING                { PENV->nExtLine = PENV->nExtLineEnd = $2 - 1;
1914                                                                 PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
1915                                                                 PASM->SetSourceFileName($3);}
1916                         ;
1917
1918 /*  Manifest declarations  */                         
1919 fileDecl                : _FILE fileAttr dottedName fileEntry hashHead bytes ')' fileEntry      
1920                                                               { PASMM->AddFile($3, $2|$4|$8, $6); }
1921                         | _FILE fileAttr dottedName fileEntry { PASMM->AddFile($3, $2|$4, NULL); }
1922                         ;
1923
1924 fileAttr                : /* EMPTY */                         { $$ = (CorFileFlags) 0; }
1925                         | fileAttr NOMETADATA_                { $$ = (CorFileFlags) ($1 | ffContainsNoMetaData); }
1926                         ;
1927
1928 fileEntry               : /* EMPTY */                         { $$ = (CorFileFlags) 0; }
1929                         | _ENTRYPOINT                         { $$ = (CorFileFlags) 0x80000000; }
1930                         ;
1931
1932 hashHead                : _HASH '=' '('                       { bParsingByteArray = TRUE; }
1933                         ;
1934
1935 assemblyHead            : _ASSEMBLY asmAttr dottedName        { PASMM->StartAssembly($3, NULL, (DWORD)$2, FALSE); }
1936                         ;
1937
1938 asmAttr                 : /* EMPTY */                         { $$ = (CorAssemblyFlags) 0; }
1939                         | asmAttr RETARGETABLE_               { $$ = (CorAssemblyFlags) ($1 | afRetargetable); }
1940                         | asmAttr WINDOWSRUNTIME_             { $$ = (CorAssemblyFlags) ($1 | afContentType_WindowsRuntime); }
1941                         | asmAttr NOPLATFORM_                 { $$ = (CorAssemblyFlags) ($1 | afPA_NoPlatform); }
1942                         | asmAttr LEGACY_ LIBRARY_            { $$ = $1; }
1943                         | asmAttr CIL_                        { SET_PA($$,$1,afPA_MSIL); }
1944                         | asmAttr X86_                        { SET_PA($$,$1,afPA_x86); }
1945                         | asmAttr IA64_                       { SET_PA($$,$1,afPA_IA64); }
1946                         | asmAttr AMD64_                      { SET_PA($$,$1,afPA_AMD64); }
1947                         | asmAttr ARM_                        { SET_PA($$,$1,afPA_ARM); }
1948                         ;
1949
1950 assemblyDecls           : /* EMPTY */
1951                         | assemblyDecls assemblyDecl
1952                         ;
1953
1954 assemblyDecl            : _HASH ALGORITHM_ int32              { PASMM->SetAssemblyHashAlg($3); }
1955                         | secDecl
1956                         | asmOrRefDecl
1957                         ;
1958                         
1959 intOrWildcard           : int32                               { $$ = $1; }
1960                         | '*'                                 { $$ = 0xFFFF; }
1961                         ;                        
1962
1963 asmOrRefDecl            : publicKeyHead bytes ')'             { PASMM->SetAssemblyPublicKey($2); }
1964                         | _VER intOrWildcard ':' intOrWildcard ':' intOrWildcard ':' intOrWildcard      
1965                                                               { PASMM->SetAssemblyVer((USHORT)$2, (USHORT)$4, (USHORT)$6, (USHORT)$8); }
1966                         | _LOCALE compQstring                 { $2->appendInt8(0); PASMM->SetAssemblyLocale($2,TRUE); }
1967                         | localeHead bytes ')'                { PASMM->SetAssemblyLocale($2,FALSE); }
1968                         | customAttrDecl
1969                         | compControl
1970                         ;
1971
1972 publicKeyHead           : _PUBLICKEY '=' '('                  { bParsingByteArray = TRUE; }
1973                         ;
1974
1975 publicKeyTokenHead      : _PUBLICKEYTOKEN '=' '('             { bParsingByteArray = TRUE; }
1976                         ;
1977
1978 localeHead              : _LOCALE '=' '('                     { bParsingByteArray = TRUE; }
1979                         ;
1980
1981 assemblyRefHead         : _ASSEMBLY EXTERN_ asmAttr dottedName     
1982                                                               { PASMM->StartAssembly($4, NULL, $3, TRUE); }
1983                         | _ASSEMBLY EXTERN_ asmAttr dottedName AS_ dottedName   
1984                                                               { PASMM->StartAssembly($4, $6, $3, TRUE); }
1985                         ;
1986
1987 assemblyRefDecls        : /* EMPTY */
1988                         | assemblyRefDecls assemblyRefDecl
1989                         ;
1990
1991 assemblyRefDecl         : hashHead bytes ')'                  { PASMM->SetAssemblyHashBlob($2); }
1992                         | asmOrRefDecl
1993                         | publicKeyTokenHead bytes ')'        { PASMM->SetAssemblyPublicKeyToken($2); }
1994                         | AUTO_                               { PASMM->SetAssemblyAutodetect(); }
1995                         ;
1996
1997 exptypeHead             : _CLASS EXTERN_ exptAttr dottedName  { PASMM->StartComType($4, $3);} 
1998                         ;
1999
2000 exportHead              : _EXPORT exptAttr dottedName   /* deprecated */      { PASMM->StartComType($3, $2); }
2001                         ;
2002
2003 exptAttr                : /* EMPTY */                         { $$ = (CorTypeAttr) 0; }
2004                         | exptAttr PRIVATE_                   { $$ = (CorTypeAttr) ($1 | tdNotPublic); }
2005                         | exptAttr PUBLIC_                    { $$ = (CorTypeAttr) ($1 | tdPublic); }
2006                         | exptAttr FORWARDER_                 { $$ = (CorTypeAttr) ($1 | tdForwarder); }
2007                         | exptAttr NESTED_ PUBLIC_            { $$ = (CorTypeAttr) ($1 | tdNestedPublic); }
2008                         | exptAttr NESTED_ PRIVATE_           { $$ = (CorTypeAttr) ($1 | tdNestedPrivate); }
2009                         | exptAttr NESTED_ FAMILY_            { $$ = (CorTypeAttr) ($1 | tdNestedFamily); }
2010                         | exptAttr NESTED_ ASSEMBLY_          { $$ = (CorTypeAttr) ($1 | tdNestedAssembly); }
2011                         | exptAttr NESTED_ FAMANDASSEM_       { $$ = (CorTypeAttr) ($1 | tdNestedFamANDAssem); }
2012                         | exptAttr NESTED_ FAMORASSEM_        { $$ = (CorTypeAttr) ($1 | tdNestedFamORAssem); }
2013                         ;
2014
2015 exptypeDecls            : /* EMPTY */
2016                         | exptypeDecls exptypeDecl
2017                         ;
2018
2019 exptypeDecl             : _FILE dottedName                    { PASMM->SetComTypeFile($2); }
2020                         | _CLASS EXTERN_ slashedName           { PASMM->SetComTypeComType($3); }
2021                         | _ASSEMBLY EXTERN_ dottedName        { PASMM->SetComTypeAsmRef($3); }
2022                         | MDTOKEN_ '(' int32 ')'              { if(!PASMM->SetComTypeImplementationTok($3))
2023                                                                   PASM->report->error("Invalid implementation of exported type\n"); }
2024                         | _CLASS  int32                       { if(!PASMM->SetComTypeClassTok($2))
2025                                                                   PASM->report->error("Invalid TypeDefID of exported type\n"); }
2026                         | customAttrDecl
2027                         | compControl
2028                         ;
2029
2030 manifestResHead         : _MRESOURCE manresAttr dottedName    { PASMM->StartManifestRes($3, $3, $2); }
2031                         | _MRESOURCE manresAttr dottedName AS_ dottedName
2032                                                               { PASMM->StartManifestRes($3, $5, $2); }
2033                         ;
2034
2035 manresAttr              : /* EMPTY */                         { $$ = (CorManifestResourceFlags) 0; }
2036                         | manresAttr PUBLIC_                  { $$ = (CorManifestResourceFlags) ($1 | mrPublic); }
2037                         | manresAttr PRIVATE_                 { $$ = (CorManifestResourceFlags) ($1 | mrPrivate); }
2038                         ;
2039
2040 manifestResDecls        : /* EMPTY */
2041                         | manifestResDecls manifestResDecl
2042                         ;
2043
2044 manifestResDecl         : _FILE dottedName AT_ int32          { PASMM->SetManifestResFile($2, (ULONG)$4); }
2045                         | _ASSEMBLY EXTERN_ dottedName        { PASMM->SetManifestResAsmRef($3); }
2046                         | customAttrDecl
2047                         | compControl
2048                         ;
2049
2050
2051 %%
2052
2053 #include "grammar_after.cpp"