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