7815892cb87807ffa8764a46de7cb4c8fdd6b825
[oota-llvm.git] / tools / llvm-upgrade / UpgradeParser.y.cvs
1 //===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements the bison parser for LLVM 1.9 assembly language.
11 //
12 //===----------------------------------------------------------------------===//
13
14 %{
15 #include "ParserInternals.h"
16 #include <llvm/ADT/StringExtras.h>
17 #include <algorithm>
18 #include <map>
19 #include <utility>
20 #include <iostream>
21
22 #define YYERROR_VERBOSE 1
23 #define YYINCLUDED_STDLIB_H
24 #define YYDEBUG 1
25
26 int yylex();                       // declaration" of xxx warnings.
27 int yyparse();
28 extern int yydebug;
29
30 static std::string CurFilename;
31 static std::ostream *O = 0;
32 std::istream* LexInput = 0;
33 unsigned SizeOfPointer = 32;
34 static uint64_t unique = 1;
35
36 typedef std::vector<TypeInfo> TypeVector;
37 static TypeVector EnumeratedTypes;
38 typedef std::map<std::string,TypeInfo> TypeMap;
39 static TypeMap NamedTypes;
40
41 void destroy(ValueList* VL) {
42   while (!VL->empty()) {
43     ValueInfo& VI = VL->back();
44     VI.destroy();
45     VL->pop_back();
46   }
47   delete VL;
48 }
49
50 void UpgradeAssembly(const std::string &infile, std::istream& in, 
51                      std::ostream &out, bool debug)
52 {
53   Upgradelineno = 1; 
54   CurFilename = infile;
55   LexInput = &in;
56   yydebug = debug;
57   O = &out;
58
59   if (yyparse()) {
60     std::cerr << "Parse failed.\n";
61     exit(1);
62   }
63 }
64
65 static void ResolveType(TypeInfo& Ty) {
66   if (Ty.oldTy == UnresolvedTy) {
67     TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
68     if (I != NamedTypes.end()) {
69       Ty.oldTy = I->second.oldTy;
70       Ty.elemTy = I->second.elemTy;
71     } else {
72       std::string msg("Can't resolve type: ");
73       msg += *Ty.newTy;
74       yyerror(msg.c_str());
75     }
76   } else if (Ty.oldTy == NumericTy) {
77     unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
78     if (ref < EnumeratedTypes.size()) {
79       Ty.oldTy = EnumeratedTypes[ref].oldTy;
80       Ty.elemTy = EnumeratedTypes[ref].elemTy;
81     } else {
82       std::string msg("Can't resolve type: ");
83       msg += *Ty.newTy;
84       yyerror(msg.c_str());
85     }
86   }
87   // otherwise its already resolved.
88 }
89
90 static const char* getCastOpcode(
91   std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy) 
92 {
93   unsigned SrcBits = SrcTy.getBitWidth();
94   unsigned DstBits = DstTy.getBitWidth();
95   const char* opcode = "bitcast";
96   // Run through the possibilities ...
97   if (DstTy.isIntegral()) {                        // Casting to integral
98     if (SrcTy.isIntegral()) {                      // Casting from integral
99       if (DstBits < SrcBits)
100         opcode = "trunc";
101       else if (DstBits > SrcBits) {                // its an extension
102         if (SrcTy.isSigned())
103           opcode ="sext";                          // signed -> SEXT
104         else
105           opcode = "zext";                         // unsigned -> ZEXT
106       } else {
107         opcode = "bitcast";                        // Same size, No-op cast
108       }
109     } else if (SrcTy.isFloatingPoint()) {          // Casting from floating pt
110       if (DstTy.isSigned()) 
111         opcode = "fptosi";                         // FP -> sint
112       else
113         opcode = "fptoui";                         // FP -> uint 
114     } else if (SrcTy.isPacked()) {
115       assert(DstBits == SrcTy.getBitWidth() &&
116                "Casting packed to integer of different width");
117         opcode = "bitcast";                        // same size, no-op cast
118     } else {
119       assert(SrcTy.isPointer() &&
120              "Casting from a value that is not first-class type");
121       opcode = "ptrtoint";                         // ptr -> int
122     }
123   } else if (DstTy.isFloatingPoint()) {           // Casting to floating pt
124     if (SrcTy.isIntegral()) {                     // Casting from integral
125       if (SrcTy.isSigned())
126         opcode = "sitofp";                         // sint -> FP
127       else
128         opcode = "uitofp";                         // uint -> FP
129     } else if (SrcTy.isFloatingPoint()) {         // Casting from floating pt
130       if (DstBits < SrcBits) {
131         opcode = "fptrunc";                        // FP -> smaller FP
132       } else if (DstBits > SrcBits) {
133         opcode = "fpext";                          // FP -> larger FP
134       } else  {
135         opcode ="bitcast";                         // same size, no-op cast
136       }
137     } else if (SrcTy.isPacked()) {
138       assert(DstBits == SrcTy.getBitWidth() &&
139              "Casting packed to floating point of different width");
140         opcode = "bitcast";                        // same size, no-op cast
141     } else {
142       assert(0 && "Casting pointer or non-first class to float");
143     }
144   } else if (DstTy.isPacked()) {
145     if (SrcTy.isPacked()) {
146       assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
147              "Casting packed to packed of different widths");
148       opcode = "bitcast";                          // packed -> packed
149     } else if (DstTy.getBitWidth() == SrcBits) {
150       opcode = "bitcast";                          // float/int -> packed
151     } else {
152       assert(!"Illegal cast to packed (wrong type or size)");
153     }
154   } else if (DstTy.isPointer()) {
155     if (SrcTy.isPointer()) {
156       opcode = "bitcast";                          // ptr -> ptr
157     } else if (SrcTy.isIntegral()) {
158       opcode = "inttoptr";                         // int -> ptr
159     } else {
160       assert(!"Casting invalid type to pointer");
161     }
162   } else {
163     assert(!"Casting to type that is not first-class");
164   }
165   return opcode;
166 }
167
168 static std::string getCastUpgrade(
169   const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
170 {
171   std::string Result;
172   std::string Source = Src;
173   if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
174     // fp -> ptr cast is no longer supported but we must upgrade this
175     // by doing a double cast: fp -> int -> ptr
176     if (isConst)
177       Source = "ulong fptoui(" + Source + " to ulong)";
178     else {
179       *O << "    %cast_upgrade" << unique << " = fptoui " << Source 
180          << " to ulong\n";
181       Source = "ulong %cast_upgrade" + llvm::utostr(unique);
182     }
183     // Update the SrcTy for the getCastOpcode call below
184     SrcTy.destroy();
185     SrcTy.newTy = new std::string("ulong");
186     SrcTy.oldTy = ULongTy;
187   } else if (DstTy.oldTy == BoolTy) {
188     // cast ptr %x to  bool was previously defined as setne ptr %x, null
189     // The ptrtoint semantic is to truncate, not compare so we must retain
190     // the original intent by replace the cast with a setne
191     const char* comparator = SrcTy.isPointer() ? ", null" : 
192       (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
193     if (isConst) 
194       Result = "setne (" + Source + comparator + ")";
195     else
196       Result = "setne " + Source + comparator;
197     return Result; // skip cast processing below
198   }
199   ResolveType(SrcTy);
200   ResolveType(DstTy);
201   std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
202   if (isConst)
203     Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
204   else
205     Result += Opcode + " " + Source + " to " + *DstTy.newTy;
206   return Result;
207 }
208
209 const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
210   const char* op = opcode.c_str();
211   TypeInfo Ty = TI;
212   ResolveType(Ty);
213   if (Ty.isPacked())
214     Ty.oldTy = Ty.getElementType();
215   if (opcode == "div")
216     if (Ty.isFloatingPoint())
217       op = "fdiv";
218     else if (Ty.isUnsigned())
219       op = "udiv";
220     else if (Ty.isSigned())
221       op = "sdiv";
222     else
223       yyerror("Invalid type for div instruction");
224   else if (opcode == "rem")
225     if (Ty.isFloatingPoint())
226       op = "frem";
227     else if (Ty.isUnsigned())
228       op = "urem";
229     else if (Ty.isSigned())
230       op = "srem";
231     else
232       yyerror("Invalid type for rem instruction");
233   return op;
234 }
235 %}
236
237 %file-prefix="UpgradeParser"
238
239 %union {
240   std::string*    String;
241   TypeInfo        Type;
242   ValueInfo       Value;
243   ConstInfo       Const;
244   ValueList*      ValList;
245 }
246
247 %token <Type>   VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
248 %token <Type>   FLOAT DOUBLE LABEL 
249 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
250 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
251 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
252 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
253 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
254 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK 
255 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
256 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
257 %token <String> ALIGN UNINITIALIZED
258 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
259 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
260 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
261 %token <String> DATALAYOUT
262 %token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
263 %token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
264 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE  // Binary Comparators
265 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
266 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
267 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
268 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP 
269 %token <String> PTRTOINT INTTOPTR BITCAST
270
271 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign 
272 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
273 %type <String> ArgTypeListI ConstExpr DefinitionList
274 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
275 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
276 %type <String> Function FunctionProto BasicBlock TypeListI
277 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
278 %type <String> OptTailCall InstVal OptVolatile Unwind
279 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
280 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
281 %type <String> Name ConstValueRef ConstVector External
282 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps 
283
284 %type <ValList> ValueRefList ValueRefListE IndexList
285
286 %type <Type> IntType SIntType UIntType FPType TypesV Types 
287 %type <Type> PrimType UpRTypesV UpRTypes
288
289 %type <String> IntVal EInt64Val 
290 %type <Const>  ConstVal
291
292 %type <Value> ValueRef ResolvedVal 
293
294 %start Module
295
296 %%
297
298 // Handle constant integer size restriction and conversion...
299 IntVal : SINTVAL | UINTVAL ;
300 EInt64Val : ESINT64VAL | EUINT64VAL;
301
302 // Operations that are notably excluded from this list include:
303 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
304 ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV 
305              | REM | UREM | SREM | FREM;
306 LogicalOps   : AND | OR | XOR;
307 SetCondOps   : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
308 ShiftOps     : SHL | SHR | ASHR | LSHR;
309 CastOps      : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI | 
310                UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
311              ;
312
313 // These are some types that allow classification if we only want a particular 
314 // thing... for example, only a signed, unsigned, or integral type.
315 SIntType :  LONG |  INT |  SHORT | SBYTE;
316 UIntType : ULONG | UINT | USHORT | UBYTE;
317 IntType  : SIntType | UIntType;
318 FPType   : FLOAT | DOUBLE;
319
320 // OptAssign - Value producing statements have an optional assignment component
321 OptAssign : Name '=' {
322     $$ = $1;
323   }
324   | /*empty*/ {
325     $$ = new std::string(""); 
326   };
327
328 OptLinkage 
329   : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT 
330   | EXTERN_WEAK 
331   | /*empty*/   { $$ = new std::string(""); } ;
332
333 OptCallingConv 
334   : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK 
335   | X86_FASTCALLCC_TOK 
336   | CC_TOK EUINT64VAL { 
337     *$1 += *$2; 
338     delete $2;
339     $$ = $1; 
340     }
341   | /*empty*/ { $$ = new std::string(""); } ;
342
343 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
344 // a comma before it.
345 OptAlign 
346   : /*empty*/        { $$ = new std::string(); }
347   | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
348          ;
349 OptCAlign 
350   : /*empty*/            { $$ = new std::string(); } 
351   | ',' ALIGN EUINT64VAL { 
352     $2->insert(0, ", "); 
353     *$2 += " " + *$3;
354     delete $3;
355     $$ = $2;
356   };
357
358 SectionString 
359   : SECTION STRINGCONSTANT { 
360     *$1 += " " + *$2;
361     delete $2;
362     $$ = $1;
363   };
364
365 OptSection : /*empty*/     { $$ = new std::string(); } 
366            | SectionString;
367
368 GlobalVarAttributes 
369     : /* empty */ { $$ = new std::string(); } 
370     | ',' GlobalVarAttribute GlobalVarAttributes  {
371       $2->insert(0, ", ");
372       if (!$3->empty())
373         *$2 += " " + *$3;
374       delete $3;
375       $$ = $2;
376     };
377
378 GlobalVarAttribute 
379     : SectionString 
380     | ALIGN EUINT64VAL {
381       *$1 += " " + *$2;
382       delete $2;
383       $$ = $1;
384     };
385
386 //===----------------------------------------------------------------------===//
387 // Types includes all predefined types... except void, because it can only be
388 // used in specific contexts (function returning void for example).  To have
389 // access to it, a user must explicitly use TypesV.
390 //
391
392 // TypesV includes all of 'Types', but it also includes the void type.
393 TypesV    : Types    | VOID ;
394 UpRTypesV : UpRTypes | VOID ; 
395 Types     : UpRTypes ;
396
397 // Derived types are added later...
398 //
399 PrimType : BOOL | SBYTE | UBYTE | SHORT  | USHORT | INT   | UINT ;
400 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
401 UpRTypes 
402   : OPAQUE { 
403     $$.newTy = $1; 
404     $$.oldTy = OpaqueTy; 
405   } 
406   | SymbolicValueRef { 
407     $$.newTy = $1;
408     $$.oldTy = UnresolvedTy;
409   }
410   | PrimType { 
411     $$ = $1; 
412   }
413   | '\\' EUINT64VAL {                   // Type UpReference
414     $2->insert(0, "\\");
415     $$.newTy = $2;
416     $$.oldTy = NumericTy;
417   }
418   | UpRTypesV '(' ArgTypeListI ')' {           // Function derived type?
419     *$1.newTy += "( " + *$3 + " )";
420     delete $3;
421     $$.newTy = $1.newTy;
422     $$.oldTy = FunctionTy;
423   }
424   | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type?
425     $2->insert(0,"[ ");
426     *$2 += " x " + *$4.newTy + " ]";
427     delete $4.newTy;
428     $$.newTy = $2;
429     $$.oldTy = ArrayTy;
430     $$.elemTy = $4.oldTy;
431   }
432   | '<' EUINT64VAL 'x' UpRTypes '>' {          // Packed array type?
433     $2->insert(0,"< ");
434     *$2 += " x " + *$4.newTy + " >";
435     delete $4.newTy;
436     $$.newTy = $2;
437     $$.oldTy = PackedTy;
438     $$.elemTy = $4.oldTy;
439   }
440   | '{' TypeListI '}' {                        // Structure type?
441     $2->insert(0, "{ ");
442     *$2 += " }";
443     $$.newTy = $2;
444     $$.oldTy = StructTy;
445   }
446   | '{' '}' {                                  // Empty structure type?
447     $$.newTy = new std::string("{}");
448     $$.oldTy = StructTy;
449   }
450   | UpRTypes '*' {                             // Pointer type?
451     *$1.newTy += '*';
452     $$.elemTy = $1.oldTy;
453     $1.oldTy = PointerTy;
454     $$ = $1;
455   };
456
457 // TypeList - Used for struct declarations and as a basis for function type 
458 // declaration type lists
459 //
460 TypeListI 
461   : UpRTypes {
462     $$ = $1.newTy;
463   }
464   | TypeListI ',' UpRTypes {
465     *$1 += ", " + *$3.newTy;
466     delete $3.newTy;
467     $$ = $1;
468   };
469
470 // ArgTypeList - List of types for a function type declaration...
471 ArgTypeListI 
472   : TypeListI 
473   | TypeListI ',' DOTDOTDOT {
474     *$1 += ", ...";
475     delete $3;
476     $$ = $1;
477   }
478   | DOTDOTDOT {
479     $$ = $1;
480   }
481   | /*empty*/ {
482     $$ = new std::string();
483   };
484
485 // ConstVal - The various declarations that go into the constant pool.  This
486 // production is used ONLY to represent constants that show up AFTER a 'const',
487 // 'constant' or 'global' token at global scope.  Constants that can be inlined
488 // into other expressions (such as integers and constexprs) are handled by the
489 // ResolvedVal, ValueRef and ConstValueRef productions.
490 //
491 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
492     $$.type = $1;
493     $$.cnst = new std::string(*$1.newTy);
494     *$$.cnst += " [ " + *$3 + " ]";
495     delete $3;
496   }
497   | Types '[' ']' {
498     $$.type = $1;
499     $$.cnst = new std::string(*$1.newTy);
500     *$$.cnst += "[ ]";
501   }
502   | Types 'c' STRINGCONSTANT {
503     $$.type = $1;
504     $$.cnst = new std::string(*$1.newTy);
505     *$$.cnst += " c" + *$3;
506     delete $3;
507   }
508   | Types '<' ConstVector '>' { // Nonempty unsized arr
509     $$.type = $1;
510     $$.cnst = new std::string(*$1.newTy);
511     *$$.cnst += " < " + *$3 + " >";
512     delete $3;
513   }
514   | Types '{' ConstVector '}' {
515     $$.type = $1;
516     $$.cnst = new std::string(*$1.newTy);
517     *$$.cnst += " { " + *$3 + " }";
518     delete $3;
519   }
520   | Types '{' '}' {
521     $$.type = $1;
522     $$.cnst = new std::string(*$1.newTy);
523     *$$.cnst += " {}";
524   }
525   | Types NULL_TOK {
526     $$.type = $1;
527     $$.cnst = new std::string(*$1.newTy);
528     *$$.cnst +=  " " + *$2;
529     delete $2;
530   }
531   | Types UNDEF {
532     $$.type = $1;
533     $$.cnst = new std::string(*$1.newTy);
534     *$$.cnst += " " + *$2;
535     delete $2;
536   }
537   | Types SymbolicValueRef {
538     $$.type = $1;
539     $$.cnst = new std::string(*$1.newTy);
540     *$$.cnst += " " + *$2;
541     delete $2;
542   }
543   | Types ConstExpr {
544     $$.type = $1;
545     $$.cnst = new std::string(*$1.newTy);
546     *$$.cnst += " " + *$2;
547     delete $2;
548   }
549   | Types ZEROINITIALIZER {
550     $$.type = $1;
551     $$.cnst = new std::string(*$1.newTy);
552     *$$.cnst += " " + *$2;
553     delete $2;
554   }
555   | SIntType EInt64Val {      // integral constants
556     $$.type = $1;
557     $$.cnst = new std::string(*$1.newTy);
558     *$$.cnst += " " + *$2;
559     delete $2;
560   }
561   | UIntType EUINT64VAL {            // integral constants
562     $$.type = $1;
563     $$.cnst = new std::string(*$1.newTy);
564     *$$.cnst += " " + *$2;
565     delete $2;
566   }
567   | BOOL TRUETOK {                      // Boolean constants
568     $$.type = $1;
569     $$.cnst = new std::string(*$1.newTy);
570     *$$.cnst += " " + *$2;
571     delete $2;
572   }
573   | BOOL FALSETOK {                     // Boolean constants
574     $$.type = $1;
575     $$.cnst = new std::string(*$1.newTy);
576     *$$.cnst += " " + *$2;
577     delete $2;
578   }
579   | FPType FPVAL {                   // Float & Double constants
580     $$.type = $1;
581     $$.cnst = new std::string(*$1.newTy);
582     *$$.cnst += " " + *$2;
583     delete $2;
584   };
585
586
587 ConstExpr: CastOps '(' ConstVal TO Types ')' {
588     std::string source = *$3.cnst;
589     TypeInfo DstTy = $5;
590     ResolveType(DstTy);
591     if (*$1 == "cast") {
592       // Call getCastUpgrade to upgrade the old cast
593       $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
594     } else {
595       // Nothing to upgrade, just create the cast constant expr
596       $$ = new std::string(*$1);
597       *$$ += "( " + source + " to " + *$5.newTy + ")";
598     }
599     delete $1; $3.destroy(); delete $4; $5.destroy();
600   }
601   | GETELEMENTPTR '(' ConstVal IndexList ')' {
602     *$1 += "(" + *$3.cnst;
603     for (unsigned i = 0; i < $4->size(); ++i) {
604       ValueInfo& VI = (*$4)[i];
605       *$1 += ", " + *VI.val;
606       VI.destroy();
607     }
608     *$1 += ")";
609     $$ = $1;
610     $3.destroy();
611     delete $4;
612   }
613   | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
614     *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
615     $3.destroy(); $5.destroy(); $7.destroy();
616     $$ = $1;
617   }
618   | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
619     const char* op = getDivRemOpcode(*$1, $3.type); 
620     $$ = new std::string(op);
621     *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
622     delete $1; $3.destroy(); $5.destroy();
623   }
624   | LogicalOps '(' ConstVal ',' ConstVal ')' {
625     *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
626     $3.destroy(); $5.destroy();
627     $$ = $1;
628   }
629   | SetCondOps '(' ConstVal ',' ConstVal ')' {
630     *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
631     $3.destroy(); $5.destroy();
632     $$ = $1;
633   }
634   | ShiftOps '(' ConstVal ',' ConstVal ')' {
635     const char* shiftop = $1->c_str();
636     if (*$1 == "shr")
637       shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
638     $$ = new std::string(shiftop);
639     *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
640     delete $1; $3.destroy(); $5.destroy();
641   }
642   | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
643     *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
644     $3.destroy(); $5.destroy();
645     $$ = $1;
646   }
647   | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
648     *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
649     $3.destroy(); $5.destroy(); $7.destroy();
650     $$ = $1;
651   }
652   | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
653     *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
654     $3.destroy(); $5.destroy(); $7.destroy();
655     $$ = $1;
656   };
657
658
659 // ConstVector - A list of comma separated constants.
660
661 ConstVector 
662   : ConstVector ',' ConstVal {
663     *$1 += ", " + *$3.cnst;
664     $3.destroy();
665     $$ = $1;
666   }
667   | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
668   ;
669
670
671 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
672 GlobalType : GLOBAL | CONSTANT ;
673
674
675 //===----------------------------------------------------------------------===//
676 //                             Rules to match Modules
677 //===----------------------------------------------------------------------===//
678
679 // Module rule: Capture the result of parsing the whole file into a result
680 // variable...
681 //
682 Module : DefinitionList {
683 };
684
685 // DefinitionList - Top level definitions
686 //
687 DefinitionList : DefinitionList Function {
688     $$ = 0;
689   } 
690   | DefinitionList FunctionProto {
691     *O << *$2 << "\n";
692     delete $2;
693     $$ = 0;
694   }
695   | DefinitionList MODULE ASM_TOK AsmBlock {
696     *O << "module asm " << " " << *$4 << "\n";
697     $$ = 0;
698   }  
699   | DefinitionList IMPLEMENTATION {
700     *O << "implementation\n";
701     $$ = 0;
702   }
703   | ConstPool { $$ = 0; }
704
705 External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
706
707 // ConstPool - Constants with optional names assigned to them.
708 ConstPool : ConstPool OptAssign TYPE TypesV {
709     EnumeratedTypes.push_back($4);
710     if (!$2->empty()) {
711       NamedTypes[*$2].newTy = new std::string(*$4.newTy);
712       NamedTypes[*$2].oldTy = $4.oldTy;
713       NamedTypes[*$2].elemTy = $4.elemTy;
714       *O << *$2 << " = ";
715     }
716     *O << "type " << *$4.newTy << "\n";
717     delete $2; delete $3; $4.destroy();
718     $$ = 0;
719   }
720   | ConstPool FunctionProto {       // Function prototypes can be in const pool
721     *O << *$2 << "\n";
722     delete $2;
723     $$ = 0;
724   }
725   | ConstPool MODULE ASM_TOK AsmBlock {  // Asm blocks can be in the const pool
726     *O << *$2 << " " << *$3 << " " << *$4 << "\n";
727     delete $2; delete $3; delete $4; 
728     $$ = 0;
729   }
730   | ConstPool OptAssign OptLinkage GlobalType ConstVal  GlobalVarAttributes {
731     if (!$2->empty())
732       *O << *$2 << " = ";
733     *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
734     delete $2; delete $3; delete $4; $5.destroy(); delete $6; 
735     $$ = 0;
736   }
737   | ConstPool OptAssign External GlobalType Types  GlobalVarAttributes {
738     if (!$2->empty())
739       *O << *$2 << " = ";
740     *O <<  *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
741     delete $2; delete $3; delete $4; $5.destroy(); delete $6;
742     $$ = 0;
743   }
744   | ConstPool OptAssign DLLIMPORT GlobalType Types  GlobalVarAttributes {
745     if (!$2->empty())
746       *O << *$2 << " = ";
747     *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
748     delete $2; delete $3; delete $4; $5.destroy(); delete $6;
749     $$ = 0;
750   }
751   | ConstPool OptAssign EXTERN_WEAK GlobalType Types  GlobalVarAttributes {
752     if (!$2->empty())
753       *O << *$2 << " = ";
754     *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
755     delete $2; delete $3; delete $4; $5.destroy(); delete $6;
756     $$ = 0;
757   }
758   | ConstPool TARGET TargetDefinition { 
759     *O << *$2 << " " << *$3 << "\n";
760     delete $2; delete $3;
761     $$ = 0;
762   }
763   | ConstPool DEPLIBS '=' LibrariesDefinition {
764     *O << *$2 << " = " << *$4 << "\n";
765     delete $2; delete $4;
766     $$ = 0;
767   }
768   | /* empty: end of list */ { 
769     $$ = 0;
770   };
771
772
773 AsmBlock : STRINGCONSTANT ;
774
775 BigOrLittle : BIG | LITTLE 
776
777 TargetDefinition 
778   : ENDIAN '=' BigOrLittle {
779     *$1 += " = " + *$3;
780     delete $3;
781     $$ = $1;
782   }
783   | POINTERSIZE '=' EUINT64VAL {
784     *$1 += " = " + *$3;
785     if (*$3 == "64")
786       SizeOfPointer = 64;
787     delete $3;
788     $$ = $1;
789   }
790   | TRIPLE '=' STRINGCONSTANT {
791     *$1 += " = " + *$3;
792     delete $3;
793     $$ = $1;
794   }
795   | DATALAYOUT '=' STRINGCONSTANT {
796     *$1 += " = " + *$3;
797     delete $3;
798     $$ = $1;
799   };
800
801 LibrariesDefinition 
802   : '[' LibList ']' {
803     $2->insert(0, "[ ");
804     *$2 += " ]";
805     $$ = $2;
806   };
807
808 LibList 
809   : LibList ',' STRINGCONSTANT {
810     *$1 += ", " + *$3;
811     delete $3;
812     $$ = $1;
813   }
814   | STRINGCONSTANT 
815   | /* empty: end of list */ {
816     $$ = new std::string();
817   };
818
819 //===----------------------------------------------------------------------===//
820 //                       Rules to match Function Headers
821 //===----------------------------------------------------------------------===//
822
823 Name : VAR_ID | STRINGCONSTANT;
824 OptName : Name | /*empty*/ { $$ = new std::string(); };
825
826 ArgVal : Types OptName {
827   $$ = $1.newTy;
828   if (!$2->empty())
829     *$$ += " " + *$2;
830   delete $2;
831 };
832
833 ArgListH : ArgListH ',' ArgVal {
834     *$1 += ", " + *$3;
835     delete $3;
836   }
837   | ArgVal {
838     $$ = $1;
839   };
840
841 ArgList : ArgListH {
842     $$ = $1;
843   }
844   | ArgListH ',' DOTDOTDOT {
845     *$1 += ", ...";
846     $$ = $1;
847     delete $3;
848   }
849   | DOTDOTDOT {
850     $$ = $1;
851   }
852   | /* empty */ { $$ = new std::string(); };
853
854 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' 
855                   OptSection OptAlign {
856     if (!$1->empty()) {
857       *$1 += " ";
858     }
859     *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
860     if (!$7->empty()) {
861       *$1 += " " + *$7;
862     }
863     if (!$8->empty()) {
864       *$1 += " " + *$8;
865     }
866     $2.destroy();
867     delete $3;
868     delete $5;
869     delete $7;
870     delete $8;
871     $$ = $1;
872   };
873
874 BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
875   | '{' { $$ = new std::string ("{"); }
876
877 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
878   if (!$1->empty()) {
879     *O << *$1 << " ";
880   }
881   *O << *$2 << " " << *$3 << "\n";
882   delete $1; delete $2; delete $3;
883   $$ = 0;
884 };
885
886 END : ENDTOK { $$ = new std::string("}"); delete $1; }
887     | '}' { $$ = new std::string("}"); };
888
889 Function : FunctionHeader BasicBlockList END {
890   if ($2)
891     *O << *$2;
892   *O << '\n' << *$3 << "\n";
893   $$ = 0;
894 };
895
896 FnDeclareLinkage
897   : /*default*/ { $$ = new std::string(); }
898   | DLLIMPORT    
899   | EXTERN_WEAK 
900   ;
901   
902 FunctionProto 
903   : DECLARE FnDeclareLinkage FunctionHeaderH { 
904     if (!$2->empty())
905       *$1 += " " + *$2;
906     *$1 += " " + *$3;
907     delete $2;
908     delete $3;
909     $$ = $1;
910   };
911
912 //===----------------------------------------------------------------------===//
913 //                        Rules to match Basic Blocks
914 //===----------------------------------------------------------------------===//
915
916 OptSideEffect : /* empty */ { $$ = new std::string(); }
917   | SIDEEFFECT;
918
919 ConstValueRef 
920   : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
921   | ZEROINITIALIZER 
922   | '<' ConstVector '>' { 
923     $2->insert(0, "<");
924     *$2 += ">";
925     $$ = $2;
926   }
927   | ConstExpr 
928   | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
929     if (!$2->empty()) {
930       *$1 += " " + *$2;
931     }
932     *$1 += " " + *$3 + ", " + *$5;
933     delete $2; delete $3; delete $5;
934     $$ = $1;
935   };
936
937 SymbolicValueRef : IntVal | Name ;
938
939 // ValueRef - A reference to a definition... either constant or symbolic
940 ValueRef 
941   : SymbolicValueRef {
942     $$.val = $1;
943     $$.constant = false;
944     $$.type.newTy = 0;
945     $$.type.oldTy = UnresolvedTy;
946   }
947   | ConstValueRef {
948     $$.val = $1;
949     $$.constant = true;
950     $$.type.newTy = 0;
951     $$.type.oldTy = UnresolvedTy;
952   }
953   ;
954
955 // ResolvedVal - a <type> <value> pair.  This is used only in cases where the
956 // type immediately preceeds the value reference, and allows complex constant
957 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
958 ResolvedVal : Types ValueRef {
959     $$ = $2;
960     $$.type = $1;
961     $$.val->insert(0, *$1.newTy + " ");
962   };
963
964 BasicBlockList : BasicBlockList BasicBlock {
965     $$ = 0;
966   }
967   | BasicBlock { // Do not allow functions with 0 basic blocks   
968     $$ = 0;
969   };
970
971
972 // Basic blocks are terminated by branching instructions: 
973 // br, br/cc, switch, ret
974 //
975 BasicBlock : InstructionList BBTerminatorInst  {
976     $$ = 0;
977   };
978
979 InstructionList : InstructionList Inst {
980     *O << "    " << *$2 << "\n";
981     delete $2;
982     $$ = 0;
983   }
984   | /* empty */ {
985     $$ = 0;
986   }
987   | LABELSTR {
988     *O << *$1 << "\n";
989     delete $1;
990     $$ = 0;
991   };
992
993 Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
994
995 BBTerminatorInst : RET ResolvedVal {              // Return with a result...
996     *O << "    " << *$1 << " " << *$2.val << "\n";
997     delete $1; $2.destroy();
998     $$ = 0;
999   }
1000   | RET VOID {                                       // Return with no result...
1001     *O << "    " << *$1 << " " << *$2.newTy << "\n";
1002     delete $1; $2.destroy();
1003     $$ = 0;
1004   }
1005   | BR LABEL ValueRef {                         // Unconditional Branch...
1006     *O << "    " << *$1 << " " << *$2.newTy << " " << *$3.val << "\n";
1007     delete $1; $2.destroy(); $3.destroy();
1008     $$ = 0;
1009   }                                                  // Conditional Branch...
1010   | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
1011     *O << "    " << *$1 << " " << *$2.newTy << " " << *$3.val << ", " 
1012        << *$5.newTy << " " << *$6.val << ", " << *$8.newTy << " " 
1013        << *$9.val << "\n";
1014     delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); 
1015     $8.destroy(); $9.destroy();
1016     $$ = 0;
1017   }
1018   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
1019     *O << "    " << *$1 << " " << *$2.newTy << " " << *$3.val << ", " 
1020        << *$5.newTy << " " << *$6.val << " [" << *$8 << " ]\n";
1021     delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy(); 
1022     delete $8;
1023     $$ = 0;
1024   }
1025   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
1026     *O << "    " << *$1 << " " << *$2.newTy << " " << *$3.val << ", " 
1027        << *$5.newTy << " " << *$6.val << "[]\n";
1028     delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1029     $$ = 0;
1030   }
1031   | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
1032     TO LABEL ValueRef Unwind LABEL ValueRef {
1033     *O << "    ";
1034     if (!$1->empty())
1035       *O << *$1 << " = ";
1036     *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5.val << " (";
1037     for (unsigned i = 0; i < $7->size(); ++i) {
1038       ValueInfo& VI = (*$7)[i];
1039       *O << *VI.val;
1040       if (i+1 < $7->size())
1041         *O << ", ";
1042       VI.destroy();
1043     }
1044     *O << ") " << *$9 << " " << *$10.newTy << " " << *$11.val << " " 
1045        << *$12 << " " << *$13.newTy << " " << *$14.val << "\n";
1046     delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7; 
1047     delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy(); 
1048     $14.destroy(); 
1049     $$ = 0;
1050   }
1051   | Unwind {
1052     *O << "    " << *$1 << "\n";
1053     delete $1;
1054     $$ = 0;
1055   }
1056   | UNREACHABLE {
1057     *O << "    " << *$1 << "\n";
1058     delete $1;
1059     $$ = 0;
1060   };
1061
1062 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
1063     *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1064     $2.destroy(); delete $3; $5.destroy(); $6.destroy();
1065     $$ = $1;
1066   }
1067   | IntType ConstValueRef ',' LABEL ValueRef {
1068     $2->insert(0, *$1.newTy + " " );
1069     *$2 += ", " + *$4.newTy + " " + *$5.val;
1070     $1.destroy(); $4.destroy(); $5.destroy();
1071     $$ = $2;
1072   };
1073
1074 Inst 
1075   : OptAssign InstVal {
1076     if (!$1->empty())
1077       *$1 += " = ";
1078     *$1 += *$2;
1079     delete $2;
1080     $$ = $1; 
1081   };
1082
1083 PHIList 
1084   : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
1085     $3.val->insert(0, *$1.newTy + "[");
1086     *$3.val += "," + *$5.val + "]";
1087     $1.destroy(); $5.destroy();
1088     $$ = new std::string(*$3.val);
1089     $3.destroy();
1090   }
1091   | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1092     *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1093     $4.destroy(); $6.destroy();
1094     $$ = $1;
1095   };
1096
1097
1098 ValueRefList 
1099   : ResolvedVal { 
1100     $$ = new ValueList();
1101     $$->push_back($1);
1102   }
1103   | ValueRefList ',' ResolvedVal {
1104     $1->push_back($3);
1105     $$ = $1;
1106   };
1107
1108 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1109 ValueRefListE 
1110   : ValueRefList  { $$ = $1; }
1111   | /*empty*/ { $$ = new ValueList(); }
1112   ;
1113
1114 OptTailCall 
1115   : TAIL CALL {
1116     *$1 += " " + *$2;
1117     delete $2;
1118     $$ = $1;
1119   }
1120   | CALL 
1121   ;
1122
1123 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1124     const char* op = getDivRemOpcode(*$1, $2); 
1125     $$ = new std::string(op);
1126     *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1127     delete $1; $2.destroy(); $3.destroy(); $5.destroy();
1128   }
1129   | LogicalOps Types ValueRef ',' ValueRef {
1130     *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1131     $2.destroy(); $3.destroy(); $5.destroy();
1132     $$ = $1;
1133   }
1134   | SetCondOps Types ValueRef ',' ValueRef {
1135     *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1136     $2.destroy(); $3.destroy(); $5.destroy();
1137     $$ = $1;
1138   }
1139   | NOT ResolvedVal {
1140     *$1 += " " + *$2.val;
1141     $2.destroy();
1142     $$ = $1;
1143   }
1144   | ShiftOps ResolvedVal ',' ResolvedVal {
1145     const char* shiftop = $1->c_str();
1146     if (*$1 == "shr")
1147       shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1148     $$ = new std::string(shiftop);
1149     *$$ += " " + *$2.val + ", " + *$4.val;
1150     delete $1; $2.destroy(); $4.destroy();
1151   }
1152   | CastOps ResolvedVal TO Types {
1153     std::string source = *$2.val;
1154     TypeInfo SrcTy = $2.type;
1155     TypeInfo DstTy = $4;
1156     ResolveType(DstTy);
1157     $$ = new std::string();
1158     if (*$1 == "cast") {
1159       *$$ +=  getCastUpgrade(source, SrcTy, DstTy, false);
1160     } else {
1161       *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
1162     }
1163     delete $1; $2.destroy();
1164     delete $3; $4.destroy();
1165   }
1166   | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1167     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1168     $2.destroy(); $4.destroy(); $6.destroy();
1169     $$ = $1;
1170   }
1171   | VAARG ResolvedVal ',' Types {
1172     *$1 += " " + *$2.val + ", " + *$4.newTy;
1173     $2.destroy(); $4.destroy();
1174     $$ = $1;
1175   }
1176   | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1177     *$1 += " " + *$2.val + ", " + *$4.val;
1178     $2.destroy(); $4.destroy();
1179     $$ = $1;
1180   }
1181   | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1182     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1183     $2.destroy(); $4.destroy(); $6.destroy();
1184     $$ = $1;
1185   }
1186   | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1187     *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1188     $2.destroy(); $4.destroy(); $6.destroy();
1189     $$ = $1;
1190   }
1191   | PHI_TOK PHIList {
1192     *$1 += " " + *$2;
1193     delete $2;
1194     $$ = $1;
1195   }
1196   | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')'  {
1197     if (!$2->empty())
1198       *$1 += " " + *$2;
1199     if (!$1->empty())
1200       *$1 += " ";
1201     *$1 += *$3.newTy + " " + *$4.val + "(";
1202     for (unsigned i = 0; i < $6->size(); ++i) {
1203       ValueInfo& VI = (*$6)[i];
1204       *$1 += *VI.val;
1205       if (i+1 < $6->size())
1206         *$1 += ", ";
1207       VI.destroy();
1208     }
1209     *$1 += ")";
1210     delete $2; $3.destroy(); $4.destroy(); delete $6;
1211     $$ = $1;
1212   }
1213   | MemoryInst ;
1214
1215
1216 // IndexList - List of indices for GEP based instructions...
1217 IndexList 
1218   : ',' ValueRefList { $$ = $2; }
1219   | /* empty */ {  $$ = new ValueList(); }
1220   ;
1221
1222 OptVolatile 
1223   : VOLATILE 
1224   | /* empty */ { $$ = new std::string(); }
1225   ;
1226
1227 MemoryInst : MALLOC Types OptCAlign {
1228     *$1 += " " + *$2.newTy;
1229     if (!$3->empty())
1230       *$1 += " " + *$3;
1231     $2.destroy(); delete $3;
1232     $$ = $1;
1233   }
1234   | MALLOC Types ',' UINT ValueRef OptCAlign {
1235     *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
1236     if (!$6->empty())
1237       *$1 += " " + *$6;
1238     $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
1239     $$ = $1;
1240   }
1241   | ALLOCA Types OptCAlign {
1242     *$1 += " " + *$2.newTy;
1243     if (!$3->empty())
1244       *$1 += " " + *$3;
1245     $2.destroy(); delete $3;
1246     $$ = $1;
1247   }
1248   | ALLOCA Types ',' UINT ValueRef OptCAlign {
1249     *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
1250     if (!$6->empty())
1251       *$1 += " " + *$6;
1252     $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
1253     $$ = $1;
1254   }
1255   | FREE ResolvedVal {
1256     *$1 += " " + *$2.val;
1257     $2.destroy();
1258     $$ = $1;
1259   }
1260   | OptVolatile LOAD Types ValueRef {
1261     if (!$1->empty())
1262       *$1 += " ";
1263     *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1264     delete $2; $3.destroy(); $4.destroy();
1265     $$ = $1;
1266   }
1267   | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1268     if (!$1->empty())
1269       *$1 += " ";
1270     *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1271     delete $2; $3.destroy(); $5.destroy(); $6.destroy();
1272     $$ = $1;
1273   }
1274   | GETELEMENTPTR Types ValueRef IndexList {
1275     // Upgrade the indices
1276     for (unsigned i = 0; i < $4->size(); ++i) {
1277       ValueInfo& VI = (*$4)[i];
1278       if (VI.type.isUnsigned() && !VI.isConstant() && 
1279           VI.type.getBitWidth() < 64) {
1280         std::string* old = VI.val;
1281         *O << "    %gep_upgrade" << unique << " = zext " << *old 
1282            << " to ulong\n";
1283         VI.val = new std::string("ulong %gep_upgrade" + llvm::utostr(unique++));
1284         VI.type.oldTy = ULongTy;
1285         delete old;
1286       }
1287     }
1288     *$1 += " " + *$2.newTy + " " + *$3.val;
1289     for (unsigned i = 0; i < $4->size(); ++i) {
1290       ValueInfo& VI = (*$4)[i];
1291       *$1 += ", " + *VI.val;
1292       VI.destroy();
1293     }
1294     $2.destroy(); $3.destroy(); delete $4;
1295     $$ = $1;
1296   };
1297
1298 %%
1299
1300 int yyerror(const char *ErrorMsg) {
1301   std::string where 
1302     = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1303                   + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1304   std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1305   if (yychar == YYEMPTY || yychar == 0)
1306     errMsg += "end-of-file.";
1307   else
1308     errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1309   std::cerr << errMsg << '\n';
1310   exit(1);
1311 }