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