1 //===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file implements the bison parser for LLVM 1.9 assembly language.
12 //===----------------------------------------------------------------------===//
15 #include "ParserInternals.h"
16 #include <llvm/ADT/StringExtras.h>
22 #define YYERROR_VERBOSE 1
23 #define YYINCLUDED_STDLIB_H
26 int yylex(); // declaration" of xxx warnings.
30 static std::string CurFilename;
31 static std::ostream *O = 0;
32 std::istream* LexInput = 0;
33 unsigned SizeOfPointer = 32;
35 void UpgradeAssembly(const std::string &infile, std::istream& in,
36 std::ostream &out, bool debug)
45 std::cerr << "Parse failed.\n";
50 const char* getCastOpcode(TypeInfo& SrcTy, TypeInfo&DstTy) {
51 unsigned SrcBits = SrcTy.getBitWidth();
52 unsigned DstBits = DstTy.getBitWidth();
53 const char* opcode = "bitcast";
54 // Run through the possibilities ...
55 if (DstTy.isIntegral()) { // Casting to integral
56 if (SrcTy.isIntegral()) { // Casting from integral
57 if (DstBits < SrcBits)
59 else if (DstBits > SrcBits) { // its an extension
61 opcode ="sext"; // signed -> SEXT
63 opcode = "zext"; // unsigned -> ZEXT
65 opcode = "bitcast"; // Same size, No-op cast
67 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
69 opcode = "fptosi"; // FP -> sint
71 opcode = "fptoui"; // FP -> uint
72 } else if (SrcTy.isPacked()) {
73 assert(DstBits == SrcTy.getBitWidth() &&
74 "Casting packed to integer of different width");
75 opcode = "bitcast"; // same size, no-op cast
77 assert(SrcTy.isPointer() &&
78 "Casting from a value that is not first-class type");
79 opcode = "ptrtoint"; // ptr -> int
81 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
82 if (SrcTy.isIntegral()) { // Casting from integral
84 opcode = "sitofp"; // sint -> FP
86 opcode = "uitofp"; // uint -> FP
87 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
88 if (DstBits < SrcBits) {
89 opcode = "fptrunc"; // FP -> smaller FP
90 } else if (DstBits > SrcBits) {
91 opcode = "fpext"; // FP -> larger FP
93 opcode ="bitcast"; // same size, no-op cast
95 } else if (SrcTy.isPacked()) {
96 assert(DstBits == SrcTy.getBitWidth() &&
97 "Casting packed to floating point of different width");
98 opcode = "bitcast"; // same size, no-op cast
100 assert(0 && "Casting pointer or non-first class to float");
102 } else if (DstTy.isPacked()) {
103 if (SrcTy.isPacked()) {
104 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
105 "Casting packed to packed of different widths");
106 opcode = "bitcast"; // packed -> packed
107 } else if (DstTy.getBitWidth() == SrcBits) {
108 opcode = "bitcast"; // float/int -> packed
110 assert(!"Illegal cast to packed (wrong type or size)");
112 } else if (DstTy.isPointer()) {
113 if (SrcTy.isPointer()) {
114 opcode = "bitcast"; // ptr -> ptr
115 } else if (SrcTy.isIntegral()) {
116 opcode = "inttoptr"; // int -> ptr
118 assert(!"Casting pointer to other than pointer or int");
121 assert(!"Casting to type that is not first-class");
128 %file-prefix="UpgradeParser"
137 %token <Const> ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL TRUETOK FALSETOK
138 %token <Const> NULL_TOK UNDEF ZEROINITIALIZER
140 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
141 %token <Type> FLOAT DOUBLE LABEL OPAQUE
143 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
144 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
145 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
146 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
147 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
148 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
149 %token <String> ALIGN
150 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
151 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
152 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
153 %token <String> DATALAYOUT
154 %token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
155 %token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
156 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
157 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
158 %token <String> PHI_TOK SELECT SHL LSHR ASHR VAARG
159 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
162 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
163 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
164 %type <String> ArgTypeListI ConstExpr DefinitionList
165 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
166 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
167 %type <String> Function FunctionProto BasicBlock TypeListI
168 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
169 %type <String> ValueRefList OptTailCall InstVal IndexList OptVolatile
170 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
171 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
172 %type <String> Name ValueRef ValueRefListE
173 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps ConstValueRef
175 %type <String> ConstVector
177 %type <Type> IntType SIntType UIntType FPType TypesV Types
178 %type <Type> PrimType UpRTypesV UpRTypes
180 %type <Const> IntVal EInt64Val ConstVal
182 %type <Value> ResolvedVal
188 // Handle constant integer size restriction and conversion...
189 IntVal : SINTVAL | UINTVAL
190 EInt64Val : ESINT64VAL | EUINT64VAL;
192 // Operations that are notably excluded from this list include:
193 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
194 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
195 LogicalOps : AND | OR | XOR;
196 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
197 ShiftOps : SHL | LSHR | ASHR;
199 // These are some types that allow classification if we only want a particular
200 // thing... for example, only a signed, unsigned, or integral type.
201 SIntType : LONG | INT | SHORT | SBYTE;
202 UIntType : ULONG | UINT | USHORT | UBYTE;
203 IntType : SIntType | UIntType;
204 FPType : FLOAT | DOUBLE;
206 // OptAssign - Value producing statements have an optional assignment component
207 OptAssign : Name '=' {
212 $$ = new std::string("");
216 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
218 | /*empty*/ { $$ = new std::string(""); } ;
221 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
222 | X86_FASTCALLCC_TOK | CC_TOK EUINT64VAL
223 | /*empty*/ { $$ = new std::string(""); } ;
225 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
226 // a comma before it.
228 : /*empty*/ { $$ = new std::string(); }
229 | ALIGN EUINT64VAL { *$1 += " " + *$2.cnst; delete $2.cnst; $$ = $1; };
232 : /*empty*/ { $$ = new std::string(); }
233 | ',' ALIGN EUINT64VAL {
235 *$2 += " " + *$3.cnst;
241 : SECTION STRINGCONSTANT {
247 OptSection : /*empty*/ { $$ = new std::string(); }
251 : /* empty */ { $$ = new std::string(); }
252 | ',' GlobalVarAttribute GlobalVarAttributes {
263 *$1 += " " + *$2.cnst;
268 //===----------------------------------------------------------------------===//
269 // Types includes all predefined types... except void, because it can only be
270 // used in specific contexts (function returning void for example). To have
271 // access to it, a user must explicitly use TypesV.
274 // TypesV includes all of 'Types', but it also includes the void type.
275 TypesV : Types | VOID ;
276 UpRTypesV : UpRTypes | VOID ;
279 // Derived types are added later...
281 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
282 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
283 UpRTypes : OPAQUE | PrimType
285 $$.newTy = $1; $$.oldTy = OpaqueTy;
288 // Include derived types in the Types production.
290 UpRTypes : '\\' EUINT64VAL { // Type UpReference
291 $2.cnst->insert(0, "\\");
295 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
296 *$1.newTy += "( " + *$3 + " )";
299 $$.oldTy = FunctionTy;
301 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
302 $2.cnst->insert(0,"[ ");
303 *$2.cnst += " x " + *$4.newTy + " ]";
308 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
309 $2.cnst->insert(0,"< ");
310 *$2.cnst += " x " + *$4.newTy + " >";
315 | '{' TypeListI '}' { // Structure type?
321 | '{' '}' { // Empty structure type?
322 $$.newTy = new std::string("{ }");
325 | UpRTypes '*' { // Pointer type?
327 $1.oldTy = PointerTy;
331 // TypeList - Used for struct declarations and as a basis for function type
332 // declaration type lists
338 | TypeListI ',' UpRTypes {
339 *$1 += ", " + *$3.newTy;
344 // ArgTypeList - List of types for a function type declaration...
347 | TypeListI ',' DOTDOTDOT {
356 $$ = new std::string();
359 // ConstVal - The various declarations that go into the constant pool. This
360 // production is used ONLY to represent constants that show up AFTER a 'const',
361 // 'constant' or 'global' token at global scope. Constants that can be inlined
362 // into other expressions (such as integers and constexprs) are handled by the
363 // ResolvedVal, ValueRef and ConstValueRef productions.
365 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
367 $$.cnst = new std::string(*$1.newTy);
368 *$$.cnst += " [ " + *$3 + " ]";
373 $$.cnst = new std::string(*$1.newTy);
376 | Types 'c' STRINGCONSTANT {
378 $$.cnst = new std::string(*$1.newTy);
379 *$$.cnst += " c" + *$3;
382 | Types '<' ConstVector '>' { // Nonempty unsized arr
384 $$.cnst = new std::string(*$1.newTy);
385 *$$.cnst += " < " + *$3 + " >";
388 | Types '{' ConstVector '}' {
390 $$.cnst = new std::string(*$1.newTy);
391 *$$.cnst += " { " + *$3 + " }";
396 $$.cnst = new std::string(*$1.newTy);
401 $$.cnst = new std::string(*$1.newTy);
402 *$$.cnst += " " + *$2.cnst;
407 $$.cnst = new std::string(*$1.newTy);
408 *$$.cnst += " " + *$2.cnst;
411 | Types SymbolicValueRef {
413 $$.cnst = new std::string(*$1.newTy);
414 *$$.cnst += " " + *$2;
419 $$.cnst = new std::string(*$1.newTy);
420 *$$.cnst += " " + *$2;
423 | Types ZEROINITIALIZER {
425 $$.cnst = new std::string(*$1.newTy);
426 *$$.cnst += " " + *$2.cnst;
429 | SIntType EInt64Val { // integral constants
431 $$.cnst = new std::string(*$1.newTy);
432 *$$.cnst += " " + *$2.cnst;
435 | UIntType EUINT64VAL { // integral constants
437 $$.cnst = new std::string(*$1.newTy);
438 *$$.cnst += " " + *$2.cnst;
441 | BOOL TRUETOK { // Boolean constants
443 $$.cnst = new std::string(*$1.newTy);
444 *$$.cnst += " " + *$2.cnst;
447 | BOOL FALSETOK { // Boolean constants
449 $$.cnst = new std::string(*$1.newTy);
450 *$$.cnst += " " + *$2.cnst;
453 | FPType FPVAL { // Float & Double constants
455 $$.cnst = new std::string(*$1.newTy);
456 *$$.cnst += " " + *$2.cnst;
461 ConstExpr: CAST '(' ConstVal TO Types ')' {
462 // We must infer the cast opcode from the types of the operands.
463 const char *opcode = getCastOpcode($3.type, $5);
464 $$ = new std::string(opcode);
465 *$$ += "(" + *$3.cnst + " " + *$4 + " " + *$5.newTy + ")";
466 delete $1; $3.destroy(); delete $4; $5.destroy();
468 | GETELEMENTPTR '(' ConstVal IndexList ')' {
469 *$1 += "(" + *$3.cnst + " " + *$4 + ")";
474 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
475 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
476 $3.destroy(); $5.destroy(); $7.destroy();
479 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
480 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
481 $3.destroy(); $5.destroy();
484 | LogicalOps '(' ConstVal ',' ConstVal ')' {
485 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
486 $3.destroy(); $5.destroy();
489 | SetCondOps '(' ConstVal ',' ConstVal ')' {
490 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
491 $3.destroy(); $5.destroy();
494 | ShiftOps '(' ConstVal ',' ConstVal ')' {
495 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
496 $3.destroy(); $5.destroy();
499 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
500 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
501 $3.destroy(); $5.destroy();
504 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
505 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
506 $3.destroy(); $5.destroy(); $7.destroy();
509 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
510 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
511 $3.destroy(); $5.destroy(); $7.destroy();
516 // ConstVector - A list of comma separated constants.
519 : ConstVector ',' ConstVal {
520 *$1 += ", " + *$3.cnst;
524 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
528 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
529 GlobalType : GLOBAL | CONSTANT ;
532 //===----------------------------------------------------------------------===//
533 // Rules to match Modules
534 //===----------------------------------------------------------------------===//
536 // Module rule: Capture the result of parsing the whole file into a result
539 Module : DefinitionList {
542 // DefinitionList - Top level definitions
544 DefinitionList : DefinitionList Function {
547 | DefinitionList FunctionProto {
552 | DefinitionList MODULE ASM_TOK AsmBlock {
553 *O << "module asm " << " " << *$4 << "\n";
556 | DefinitionList IMPLEMENTATION {
557 *O << "implementation\n";
562 // ConstPool - Constants with optional names assigned to them.
563 ConstPool : ConstPool OptAssign TYPE TypesV {
564 *O << *$2 << " " << *$3 << " " << *$4.newTy << "\n";
565 // delete $2; delete $3; $4.destroy();
568 | ConstPool FunctionProto { // Function prototypes can be in const pool
573 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
574 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
575 delete $2; delete $3; delete $4;
578 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
579 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.cnst << " "
581 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
584 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
585 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
586 << " " << *$6 << "\n";
587 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
590 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
591 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
592 << " " << *$6 << "\n";
593 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
596 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
597 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
598 << " " << *$6 << "\n";
599 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
602 | ConstPool TARGET TargetDefinition {
603 *O << *$2 << " " << *$3 << "\n";
604 delete $2; delete $3;
607 | ConstPool DEPLIBS '=' LibrariesDefinition {
608 *O << *$2 << " = " << *$4 << "\n";
609 delete $2; delete $4;
612 | /* empty: end of list */ {
617 AsmBlock : STRINGCONSTANT ;
619 BigOrLittle : BIG | LITTLE
622 : ENDIAN '=' BigOrLittle {
627 | POINTERSIZE '=' EUINT64VAL {
628 *$1 += " = " + *$3.cnst;
629 if (*$3.cnst == "64")
634 | TRIPLE '=' STRINGCONSTANT {
639 | DATALAYOUT '=' STRINGCONSTANT {
653 : LibList ',' STRINGCONSTANT {
659 | /* empty: end of list */ {
660 $$ = new std::string();
663 //===----------------------------------------------------------------------===//
664 // Rules to match Function Headers
665 //===----------------------------------------------------------------------===//
667 Name : VAR_ID | STRINGCONSTANT;
668 OptName : Name | /*empty*/ { $$ = new std::string(); };
670 ArgVal : Types OptName {
677 ArgListH : ArgListH ',' ArgVal {
688 | ArgListH ',' DOTDOTDOT {
696 | /* empty */ { $$ = new std::string(); };
698 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
699 OptSection OptAlign {
703 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
719 $$ = new std::string("begin");
722 $$ = new std::string ("{");
725 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
729 *O << *$2 << " " << *$3 << "\n";
730 delete $1; delete $2; delete $3;
734 END : ENDTOK { $$ = new std::string("end"); }
735 | '}' { $$ = new std::string("}"); };
737 Function : FunctionHeader BasicBlockList END {
740 *O << '\n' << *$3 << "\n";
745 : /*default*/ { $$ = new std::string(); }
751 : DECLARE FnDeclareLinkage FunctionHeaderH {
760 //===----------------------------------------------------------------------===//
761 // Rules to match Basic Blocks
762 //===----------------------------------------------------------------------===//
764 OptSideEffect : /* empty */ { $$ = new std::string(); }
768 : ESINT64VAL { $$ = $1.cnst; }
769 | EUINT64VAL { $$ = $1.cnst; }
770 | FPVAL { $$ = $1.cnst; }
771 | TRUETOK { $$ = $1.cnst; }
772 | FALSETOK { $$ = $1.cnst; }
773 | NULL_TOK { $$ = $1.cnst; }
774 | UNDEF { $$ = $1.cnst; }
775 | ZEROINITIALIZER { $$ = $1.cnst; }
776 | '<' ConstVector '>' {
782 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
786 *$1 += " " + *$3 + ", " + *$5;
787 delete $2; delete $3; delete $5;
791 SymbolicValueRef : IntVal { $$ = $1.cnst; } | Name ;
793 // ValueRef - A reference to a definition... either constant or symbolic
794 ValueRef : SymbolicValueRef | ConstValueRef;
797 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
798 // type immediately preceeds the value reference, and allows complex constant
799 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
800 ResolvedVal : Types ValueRef {
802 $$.val = new std::string(*$1.newTy + " ");
807 BasicBlockList : BasicBlockList BasicBlock {
809 | BasicBlock { // Do not allow functions with 0 basic blocks
813 // Basic blocks are terminated by branching instructions:
814 // br, br/cc, switch, ret
816 BasicBlock : InstructionList OptAssign BBTerminatorInst {
820 InstructionList : InstructionList Inst {
821 *O << " " << *$2 << "\n";
834 BBTerminatorInst : RET ResolvedVal { // Return with a result...
835 *O << " " << *$1 << " " << *$2.val << "\n";
836 delete $1; $2.destroy();
839 | RET VOID { // Return with no result...
840 *O << " " << *$1 << " " << *$2.newTy << "\n";
841 delete $1; $2.destroy();
844 | BR LABEL ValueRef { // Unconditional Branch...
845 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
846 delete $1; $2.destroy(); delete $3;
848 } // Conditional Branch...
849 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
850 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
851 << *$5.newTy << " " << *$6 << ", " << *$8.newTy << " " << *$9 << "\n";
852 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
853 $8.destroy(); delete $9;
856 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
857 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
858 << " " << *$6 << " [" << *$8 << " ]\n";
859 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
862 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
863 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
864 << *$5.newTy << " " << *$6 << "[]\n";
865 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
868 | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
869 TO LABEL ValueRef UNWIND LABEL ValueRef {
870 *O << " " << *$1 << " " << *$2 << " " << *$3.newTy << " " << *$4 << " ("
871 << *$6 << ") " << *$8 << " " << *$9.newTy << " " << *$10 << " "
872 << *$11 << " " << *$12.newTy << " " << *$13 << "\n";
873 delete $1; delete $2; $3.destroy(); delete $4; delete $6; delete $8;
874 $9.destroy(); delete $10; delete $11; $12.destroy(); delete $13;
878 *O << " " << *$1 << "\n";
883 *O << " " << *$1 << "\n";
888 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
889 *$1 += *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
890 $2.destroy(); delete $3; $5.destroy(); delete $6;
893 | IntType ConstValueRef ',' LABEL ValueRef {
894 $2->insert(0, *$1.newTy + " " );
895 *$2 += ", " + *$4.newTy + " " + *$5;
896 $1.destroy(); $4.destroy(); delete $5;
901 : OptAssign InstVal {
908 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
909 $3->insert(0, *$1.newTy + "[");
910 *$3 += "," + *$5 + "]";
911 $1.destroy(); delete $5;
914 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
915 *$1 += ", [" + *$4 + "," + *$6 + "]";
916 delete $4; delete $6;
922 : ResolvedVal { $$ = new std::string(*$1.val); $1.destroy(); }
923 | ValueRefList ',' ResolvedVal {
924 *$1 += ", " + *$3.val;
929 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
932 | /*empty*/ { $$ = new std::string(); }
944 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
945 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
946 $2.destroy(); delete $3; delete $5;
949 | LogicalOps Types ValueRef ',' ValueRef {
950 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
951 $2.destroy(); delete $3; delete $5;
954 | SetCondOps Types ValueRef ',' ValueRef {
955 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
956 $2.destroy(); delete $3; delete $5;
960 *$1 += " " + *$2.val;
964 | ShiftOps ResolvedVal ',' ResolvedVal {
965 *$1 += " " + *$2.val + ", " + *$4.val;
966 $2.destroy(); $4.destroy();
969 | CAST ResolvedVal TO Types {
970 const char *opcode = getCastOpcode($2.type, $4);
971 $$ = new std::string(opcode);
972 *$$ += *$2.val + " " + *$3 + " " + *$4.newTy;
973 delete $1; $2.destroy();
974 delete $3; $4.destroy();
976 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
977 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
978 $2.destroy(); $4.destroy(); $6.destroy();
981 | VAARG ResolvedVal ',' Types {
982 *$1 += " " + *$2.val + ", " + *$4.newTy;
983 $2.destroy(); $4.destroy();
986 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
987 *$1 += " " + *$2.val + ", " + *$4.val;
988 $2.destroy(); $4.destroy();
991 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
992 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
993 $2.destroy(); $4.destroy(); $6.destroy();
996 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
997 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
998 $2.destroy(); $4.destroy(); $6.destroy();
1006 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1011 *$1 += *$3.newTy + " " + *$4 + "(" + *$6 + ")";
1012 delete $2; $3.destroy(); delete $4; delete $6;
1018 // IndexList - List of indices for GEP based instructions...
1020 : ',' ValueRefList {
1021 $2->insert(0, ", ");
1024 | /* empty */ { $$ = new std::string(); }
1029 | /* empty */ { $$ = new std::string(); }
1032 MemoryInst : MALLOC Types OptCAlign {
1033 *$1 += " " + *$2.newTy;
1036 $2.destroy(); delete $3;
1039 | MALLOC Types ',' UINT ValueRef OptCAlign {
1040 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1043 $2.destroy(); $4.destroy(); delete $5; delete $6;
1046 | ALLOCA Types OptCAlign {
1047 *$1 += " " + *$2.newTy;
1050 $2.destroy(); delete $3;
1053 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1054 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1057 $2.destroy(); $4.destroy(); delete $5; delete $6;
1060 | FREE ResolvedVal {
1061 *$1 += " " + *$2.val;
1065 | OptVolatile LOAD Types ValueRef {
1068 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1069 delete $2; $3.destroy(); delete $4;
1072 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1075 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1076 delete $2; $3.destroy(); $5.destroy(); delete $6;
1079 | GETELEMENTPTR Types ValueRef IndexList {
1080 *$1 += *$2.newTy + " " + *$3 + " " + *$4;
1081 $2.destroy(); delete $3; delete $4;
1087 int yyerror(const char *ErrorMsg) {
1089 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1090 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1091 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1092 if (yychar == YYEMPTY || yychar == 0)
1093 errMsg += "end-of-file.";
1095 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1096 std::cerr << errMsg << '\n';