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