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