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