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