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 typedef std::vector<TypeInfo> TypeVector;
36 static TypeVector EnumeratedTypes;
37 typedef std::map<std::string,TypeInfo> TypeMap;
38 static TypeMap NamedTypes;
40 void destroy(ValueList* VL) {
41 while (!VL->empty()) {
42 ValueInfo& VI = VL->back();
49 void UpgradeAssembly(const std::string &infile, std::istream& in,
50 std::ostream &out, bool debug)
59 std::cerr << "Parse failed.\n";
64 static void ResolveType(TypeInfo& Ty) {
65 if (Ty.oldTy == UnresolvedTy) {
66 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
67 if (I != NamedTypes.end())
68 Ty.oldTy = I->second.oldTy;
70 std::string msg("Can't resolve type: ");
74 } else if (Ty.oldTy == NumericTy) {
75 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
76 if (ref < EnumeratedTypes.size()) {
77 Ty.oldTy = EnumeratedTypes[ref].oldTy;
79 std::string msg("Can't resolve type: ");
84 // otherwise its already resolved.
87 static const char* getCastOpcode(
88 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
90 unsigned SrcBits = SrcTy.getBitWidth();
91 unsigned DstBits = DstTy.getBitWidth();
92 const char* opcode = "bitcast";
93 // Run through the possibilities ...
94 if (DstTy.isIntegral()) { // Casting to integral
95 if (SrcTy.isIntegral()) { // Casting from integral
96 if (DstBits < SrcBits)
98 else if (DstBits > SrcBits) { // its an extension
100 opcode ="sext"; // signed -> SEXT
102 opcode = "zext"; // unsigned -> ZEXT
104 opcode = "bitcast"; // Same size, No-op cast
106 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
107 if (DstTy.isSigned())
108 opcode = "fptosi"; // FP -> sint
110 opcode = "fptoui"; // FP -> uint
111 } else if (SrcTy.isPacked()) {
112 assert(DstBits == SrcTy.getBitWidth() &&
113 "Casting packed to integer of different width");
114 opcode = "bitcast"; // same size, no-op cast
116 assert(SrcTy.isPointer() &&
117 "Casting from a value that is not first-class type");
118 opcode = "ptrtoint"; // ptr -> int
120 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
121 if (SrcTy.isIntegral()) { // Casting from integral
122 if (SrcTy.isSigned())
123 opcode = "sitofp"; // sint -> FP
125 opcode = "uitofp"; // uint -> FP
126 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
127 if (DstBits < SrcBits) {
128 opcode = "fptrunc"; // FP -> smaller FP
129 } else if (DstBits > SrcBits) {
130 opcode = "fpext"; // FP -> larger FP
132 opcode ="bitcast"; // same size, no-op cast
134 } else if (SrcTy.isPacked()) {
135 assert(DstBits == SrcTy.getBitWidth() &&
136 "Casting packed to floating point of different width");
137 opcode = "bitcast"; // same size, no-op cast
139 assert(0 && "Casting pointer or non-first class to float");
141 } else if (DstTy.isPacked()) {
142 if (SrcTy.isPacked()) {
143 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
144 "Casting packed to packed of different widths");
145 opcode = "bitcast"; // packed -> packed
146 } else if (DstTy.getBitWidth() == SrcBits) {
147 opcode = "bitcast"; // float/int -> packed
149 assert(!"Illegal cast to packed (wrong type or size)");
151 } else if (DstTy.isPointer()) {
152 if (SrcTy.isPointer()) {
153 opcode = "bitcast"; // ptr -> ptr
154 } else if (SrcTy.isIntegral()) {
155 opcode = "inttoptr"; // int -> ptr
157 assert(!"Casting invalid type to pointer");
160 assert(!"Casting to type that is not first-class");
165 static std::string getCastUpgrade(
166 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
169 std::string Source = Src;
170 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
171 // fp -> ptr cast is no longer supported but we must upgrade this
172 // by doing a double cast: fp -> int -> ptr
174 Source = "ulong fptoui(" + Source + " to ulong)";
176 *O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
177 Source = "ulong %cast_upgrade";
179 // Update the SrcTy for the getCastOpcode call below
181 SrcTy.newTy = new std::string("ulong");
182 SrcTy.oldTy = ULongTy;
183 } else if (DstTy.oldTy == BoolTy) {
184 // cast ptr %x to bool was previously defined as setne ptr %x, null
185 // The ptrtoint semantic is to truncate, not compare so we must retain
186 // the original intent by replace the cast with a setne
187 const char* comparator = SrcTy.isPointer() ? ", null" :
188 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
190 Result = "setne (" + Source + comparator + ")";
192 Result = "setne " + Source + comparator;
193 return Result; // skip cast processing below
197 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
199 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
201 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
207 %file-prefix="UpgradeParser"
217 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
218 %token <Type> FLOAT DOUBLE LABEL
219 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
220 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
221 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
222 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
223 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
224 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
225 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
226 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
227 %token <String> ALIGN
228 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
229 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
230 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
231 %token <String> DATALAYOUT
232 %token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
233 %token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
234 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
235 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
236 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
237 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
238 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
239 %token <String> PTRTOINT INTTOPTR BITCAST
241 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
242 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
243 %type <String> ArgTypeListI ConstExpr DefinitionList
244 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
245 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
246 %type <String> Function FunctionProto BasicBlock TypeListI
247 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
248 %type <String> OptTailCall InstVal OptVolatile
249 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
250 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
251 %type <String> Name ValueRef ConstValueRef ConstVector
252 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
254 %type <ValList> ValueRefList ValueRefListE IndexList
256 %type <Type> IntType SIntType UIntType FPType TypesV Types
257 %type <Type> PrimType UpRTypesV UpRTypes
259 %type <String> IntVal EInt64Val
260 %type <Const> ConstVal
262 %type <Value> ResolvedVal
268 // Handle constant integer size restriction and conversion...
269 IntVal : SINTVAL | UINTVAL ;
270 EInt64Val : ESINT64VAL | EUINT64VAL;
272 // Operations that are notably excluded from this list include:
273 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
274 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
275 LogicalOps : AND | OR | XOR;
276 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
277 ShiftOps : SHL | SHR | ASHR | LSHR;
278 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
279 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
282 // These are some types that allow classification if we only want a particular
283 // thing... for example, only a signed, unsigned, or integral type.
284 SIntType : LONG | INT | SHORT | SBYTE;
285 UIntType : ULONG | UINT | USHORT | UBYTE;
286 IntType : SIntType | UIntType;
287 FPType : FLOAT | DOUBLE;
289 // OptAssign - Value producing statements have an optional assignment component
290 OptAssign : Name '=' {
294 $$ = new std::string("");
298 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
300 | /*empty*/ { $$ = new std::string(""); } ;
303 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
305 | CC_TOK EUINT64VAL {
310 | /*empty*/ { $$ = new std::string(""); } ;
312 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
313 // a comma before it.
315 : /*empty*/ { $$ = new std::string(); }
316 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
319 : /*empty*/ { $$ = new std::string(); }
320 | ',' ALIGN EUINT64VAL {
328 : SECTION STRINGCONSTANT {
334 OptSection : /*empty*/ { $$ = new std::string(); }
338 : /* empty */ { $$ = new std::string(); }
339 | ',' GlobalVarAttribute GlobalVarAttributes {
355 //===----------------------------------------------------------------------===//
356 // Types includes all predefined types... except void, because it can only be
357 // used in specific contexts (function returning void for example). To have
358 // access to it, a user must explicitly use TypesV.
361 // TypesV includes all of 'Types', but it also includes the void type.
362 TypesV : Types | VOID ;
363 UpRTypesV : UpRTypes | VOID ;
366 // Derived types are added later...
368 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
369 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
377 $$.oldTy = UnresolvedTy;
382 // Include derived types in the Types production.
384 UpRTypes : '\\' EUINT64VAL { // Type UpReference
387 $$.oldTy = NumericTy;
389 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
390 *$1.newTy += "( " + *$3 + " )";
393 $$.oldTy = FunctionTy;
395 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
397 *$2 += " x " + *$4.newTy + " ]";
402 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
404 *$2 += " x " + *$4.newTy + " >";
409 | '{' TypeListI '}' { // Structure type?
415 | '{' '}' { // Empty structure type?
416 $$.newTy = new std::string("{}");
419 | UpRTypes '*' { // Pointer type?
421 $1.oldTy = PointerTy;
425 // TypeList - Used for struct declarations and as a basis for function type
426 // declaration type lists
432 | TypeListI ',' UpRTypes {
433 *$1 += ", " + *$3.newTy;
438 // ArgTypeList - List of types for a function type declaration...
441 | TypeListI ',' DOTDOTDOT {
450 $$ = new std::string();
453 // ConstVal - The various declarations that go into the constant pool. This
454 // production is used ONLY to represent constants that show up AFTER a 'const',
455 // 'constant' or 'global' token at global scope. Constants that can be inlined
456 // into other expressions (such as integers and constexprs) are handled by the
457 // ResolvedVal, ValueRef and ConstValueRef productions.
459 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
461 $$.cnst = new std::string(*$1.newTy);
462 *$$.cnst += " [ " + *$3 + " ]";
467 $$.cnst = new std::string(*$1.newTy);
470 | Types 'c' STRINGCONSTANT {
472 $$.cnst = new std::string(*$1.newTy);
473 *$$.cnst += " c" + *$3;
476 | Types '<' ConstVector '>' { // Nonempty unsized arr
478 $$.cnst = new std::string(*$1.newTy);
479 *$$.cnst += " < " + *$3 + " >";
482 | Types '{' ConstVector '}' {
484 $$.cnst = new std::string(*$1.newTy);
485 *$$.cnst += " { " + *$3 + " }";
490 $$.cnst = new std::string(*$1.newTy);
495 $$.cnst = new std::string(*$1.newTy);
496 *$$.cnst += " " + *$2;
501 $$.cnst = new std::string(*$1.newTy);
502 *$$.cnst += " " + *$2;
505 | Types SymbolicValueRef {
507 $$.cnst = new std::string(*$1.newTy);
508 *$$.cnst += " " + *$2;
513 $$.cnst = new std::string(*$1.newTy);
514 *$$.cnst += " " + *$2;
517 | Types ZEROINITIALIZER {
519 $$.cnst = new std::string(*$1.newTy);
520 *$$.cnst += " " + *$2;
523 | SIntType EInt64Val { // integral constants
525 $$.cnst = new std::string(*$1.newTy);
526 *$$.cnst += " " + *$2;
529 | UIntType EUINT64VAL { // integral constants
531 $$.cnst = new std::string(*$1.newTy);
532 *$$.cnst += " " + *$2;
535 | BOOL TRUETOK { // Boolean constants
537 $$.cnst = new std::string(*$1.newTy);
538 *$$.cnst += " " + *$2;
541 | BOOL FALSETOK { // Boolean constants
543 $$.cnst = new std::string(*$1.newTy);
544 *$$.cnst += " " + *$2;
547 | FPType FPVAL { // Float & Double constants
549 $$.cnst = new std::string(*$1.newTy);
550 *$$.cnst += " " + *$2;
555 ConstExpr: CastOps '(' ConstVal TO Types ')' {
556 std::string source = *$3.cnst;
560 // Call getCastUpgrade to upgrade the old cast
561 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
563 // Nothing to upgrade, just create the cast constant expr
564 $$ = new std::string(*$1);
565 *$$ += "( " + source + " to " + *$5.newTy + ")";
567 delete $1; $3.destroy(); delete $4; $5.destroy();
569 | GETELEMENTPTR '(' ConstVal IndexList ')' {
570 *$1 += "(" + *$3.cnst;
571 for (unsigned i = 0; i < $4->size(); ++i) {
572 ValueInfo& VI = (*$4)[i];
573 *$1 += ", " + *VI.val;
581 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
582 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
583 $3.destroy(); $5.destroy(); $7.destroy();
586 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
587 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
588 $3.destroy(); $5.destroy();
591 | LogicalOps '(' ConstVal ',' ConstVal ')' {
592 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
593 $3.destroy(); $5.destroy();
596 | SetCondOps '(' ConstVal ',' ConstVal ')' {
597 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
598 $3.destroy(); $5.destroy();
601 | ShiftOps '(' ConstVal ',' ConstVal ')' {
602 const char* shiftop = $1->c_str();
604 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
605 $$ = new std::string(shiftop);
606 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
607 delete $1; $3.destroy(); $5.destroy();
609 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
610 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
611 $3.destroy(); $5.destroy();
614 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
615 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
616 $3.destroy(); $5.destroy(); $7.destroy();
619 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
620 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
621 $3.destroy(); $5.destroy(); $7.destroy();
626 // ConstVector - A list of comma separated constants.
629 : ConstVector ',' ConstVal {
630 *$1 += ", " + *$3.cnst;
634 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
638 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
639 GlobalType : GLOBAL | CONSTANT ;
642 //===----------------------------------------------------------------------===//
643 // Rules to match Modules
644 //===----------------------------------------------------------------------===//
646 // Module rule: Capture the result of parsing the whole file into a result
649 Module : DefinitionList {
652 // DefinitionList - Top level definitions
654 DefinitionList : DefinitionList Function {
657 | DefinitionList FunctionProto {
662 | DefinitionList MODULE ASM_TOK AsmBlock {
663 *O << "module asm " << " " << *$4 << "\n";
666 | DefinitionList IMPLEMENTATION {
667 *O << "implementation\n";
670 | ConstPool { $$ = 0; }
672 // ConstPool - Constants with optional names assigned to them.
673 ConstPool : ConstPool OptAssign TYPE TypesV {
674 EnumeratedTypes.push_back($4);
676 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
677 NamedTypes[*$2].oldTy = $4.oldTy;
680 *O << "type " << *$4.newTy << "\n";
681 delete $2; delete $3; $4.destroy();
684 | ConstPool FunctionProto { // Function prototypes can be in const pool
689 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
690 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
691 delete $2; delete $3; delete $4;
694 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
697 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
698 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
701 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
704 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
705 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
708 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
711 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
712 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
715 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
718 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
719 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
722 | ConstPool TARGET TargetDefinition {
723 *O << *$2 << " " << *$3 << "\n";
724 delete $2; delete $3;
727 | ConstPool DEPLIBS '=' LibrariesDefinition {
728 *O << *$2 << " = " << *$4 << "\n";
729 delete $2; delete $4;
732 | /* empty: end of list */ {
737 AsmBlock : STRINGCONSTANT ;
739 BigOrLittle : BIG | LITTLE
742 : ENDIAN '=' BigOrLittle {
747 | POINTERSIZE '=' EUINT64VAL {
754 | TRIPLE '=' STRINGCONSTANT {
759 | DATALAYOUT '=' STRINGCONSTANT {
773 : LibList ',' STRINGCONSTANT {
779 | /* empty: end of list */ {
780 $$ = new std::string();
783 //===----------------------------------------------------------------------===//
784 // Rules to match Function Headers
785 //===----------------------------------------------------------------------===//
787 Name : VAR_ID | STRINGCONSTANT;
788 OptName : Name | /*empty*/ { $$ = new std::string(); };
790 ArgVal : Types OptName {
797 ArgListH : ArgListH ',' ArgVal {
808 | ArgListH ',' DOTDOTDOT {
816 | /* empty */ { $$ = new std::string(); };
818 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
819 OptSection OptAlign {
823 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
839 $$ = new std::string("begin");
842 $$ = new std::string ("{");
845 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
849 *O << *$2 << " " << *$3 << "\n";
850 delete $1; delete $2; delete $3;
854 END : ENDTOK { $$ = new std::string("end"); }
855 | '}' { $$ = new std::string("}"); };
857 Function : FunctionHeader BasicBlockList END {
860 *O << '\n' << *$3 << "\n";
865 : /*default*/ { $$ = new std::string(); }
871 : DECLARE FnDeclareLinkage FunctionHeaderH {
880 //===----------------------------------------------------------------------===//
881 // Rules to match Basic Blocks
882 //===----------------------------------------------------------------------===//
884 OptSideEffect : /* empty */ { $$ = new std::string(); }
888 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
890 | '<' ConstVector '>' {
896 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
900 *$1 += " " + *$3 + ", " + *$5;
901 delete $2; delete $3; delete $5;
905 SymbolicValueRef : IntVal | Name ;
907 // ValueRef - A reference to a definition... either constant or symbolic
908 ValueRef : SymbolicValueRef | ConstValueRef;
911 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
912 // type immediately preceeds the value reference, and allows complex constant
913 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
914 ResolvedVal : Types ValueRef {
916 $$.val = new std::string(*$1.newTy + " ");
921 BasicBlockList : BasicBlockList BasicBlock {
924 | BasicBlock { // Do not allow functions with 0 basic blocks
929 // Basic blocks are terminated by branching instructions:
930 // br, br/cc, switch, ret
932 BasicBlock : InstructionList BBTerminatorInst {
936 InstructionList : InstructionList Inst {
937 *O << " " << *$2 << "\n";
950 BBTerminatorInst : RET ResolvedVal { // Return with a result...
951 *O << " " << *$1 << " " << *$2.val << "\n";
952 delete $1; $2.destroy();
955 | RET VOID { // Return with no result...
956 *O << " " << *$1 << " " << *$2.newTy << "\n";
957 delete $1; $2.destroy();
960 | BR LABEL ValueRef { // Unconditional Branch...
961 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
962 delete $1; $2.destroy(); delete $3;
964 } // Conditional Branch...
965 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
966 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
967 << *$5.newTy << " " << *$6 << ", " << *$8.newTy << " " << *$9 << "\n";
968 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
969 $8.destroy(); delete $9;
972 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
973 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
974 << " " << *$6 << " [" << *$8 << " ]\n";
975 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
978 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
979 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
980 << *$5.newTy << " " << *$6 << "[]\n";
981 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
984 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
985 TO LABEL ValueRef UNWIND LABEL ValueRef {
989 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " (";
990 for (unsigned i = 0; i < $7->size(); ++i) {
991 ValueInfo& VI = (*$7)[i];
993 if (i+1 < $7->size())
997 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
998 << *$12 << " " << *$13.newTy << " " << *$14 << "\n";
999 delete $1; delete $2; delete $3; $4.destroy(); delete $5; delete $7;
1000 delete $9; $10.destroy(); delete $11; delete $12; $13.destroy();
1005 *O << " " << *$1 << "\n";
1010 *O << " " << *$1 << "\n";
1015 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
1016 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
1017 $2.destroy(); delete $3; $5.destroy(); delete $6;
1020 | IntType ConstValueRef ',' LABEL ValueRef {
1021 $2->insert(0, *$1.newTy + " " );
1022 *$2 += ", " + *$4.newTy + " " + *$5;
1023 $1.destroy(); $4.destroy(); delete $5;
1028 : OptAssign InstVal {
1037 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
1038 $3->insert(0, *$1.newTy + "[");
1039 *$3 += "," + *$5 + "]";
1040 $1.destroy(); delete $5;
1043 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1044 *$1 += ", [" + *$4 + "," + *$6 + "]";
1045 delete $4; delete $6;
1052 $$ = new ValueList();
1055 | ValueRefList ',' ResolvedVal {
1060 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1062 : ValueRefList { $$ = $1; }
1063 | /*empty*/ { $$ = new ValueList(); }
1075 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1076 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1077 $2.destroy(); delete $3; delete $5;
1080 | LogicalOps Types ValueRef ',' ValueRef {
1081 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1082 $2.destroy(); delete $3; delete $5;
1085 | SetCondOps Types ValueRef ',' ValueRef {
1086 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1087 $2.destroy(); delete $3; delete $5;
1091 *$1 += " " + *$2.val;
1095 | ShiftOps ResolvedVal ',' ResolvedVal {
1096 const char* shiftop = $1->c_str();
1098 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1099 $$ = new std::string(shiftop);
1100 *$$ += " " + *$2.val + ", " + *$4.val;
1101 delete $1; $2.destroy(); $4.destroy();
1103 | CastOps ResolvedVal TO Types {
1104 std::string source = *$2.val;
1105 TypeInfo SrcTy = $2.type;
1106 TypeInfo DstTy = $4;
1108 $$ = new std::string();
1109 if (*$1 == "cast") {
1110 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1112 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
1114 delete $1; $2.destroy();
1115 delete $3; $4.destroy();
1117 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1118 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1119 $2.destroy(); $4.destroy(); $6.destroy();
1122 | VAARG ResolvedVal ',' Types {
1123 *$1 += " " + *$2.val + ", " + *$4.newTy;
1124 $2.destroy(); $4.destroy();
1127 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1128 *$1 += " " + *$2.val + ", " + *$4.val;
1129 $2.destroy(); $4.destroy();
1132 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1133 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1134 $2.destroy(); $4.destroy(); $6.destroy();
1137 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1138 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1139 $2.destroy(); $4.destroy(); $6.destroy();
1147 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1152 *$1 += *$3.newTy + " " + *$4 + "(";
1153 for (unsigned i = 0; i < $6->size(); ++i) {
1154 ValueInfo& VI = (*$6)[i];
1156 if (i+1 < $6->size())
1161 delete $2; $3.destroy(); delete $4; delete $6;
1167 // IndexList - List of indices for GEP based instructions...
1169 : ',' ValueRefList { $$ = $2; }
1170 | /* empty */ { $$ = new ValueList(); }
1175 | /* empty */ { $$ = new std::string(); }
1178 MemoryInst : MALLOC Types OptCAlign {
1179 *$1 += " " + *$2.newTy;
1182 $2.destroy(); delete $3;
1185 | MALLOC Types ',' UINT ValueRef OptCAlign {
1186 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1189 $2.destroy(); $4.destroy(); delete $5; delete $6;
1192 | ALLOCA Types OptCAlign {
1193 *$1 += " " + *$2.newTy;
1196 $2.destroy(); delete $3;
1199 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1200 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1203 $2.destroy(); $4.destroy(); delete $5; delete $6;
1206 | FREE ResolvedVal {
1207 *$1 += " " + *$2.val;
1211 | OptVolatile LOAD Types ValueRef {
1214 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1215 delete $2; $3.destroy(); delete $4;
1218 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1221 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1222 delete $2; $3.destroy(); $5.destroy(); delete $6;
1225 | GETELEMENTPTR Types ValueRef IndexList {
1226 *$1 += " " + *$2.newTy + " " + *$3;
1227 for (unsigned i = 0; i < $4->size(); ++i) {
1228 ValueInfo& VI = (*$4)[i];
1229 *$1 += ", " + *VI.val;
1232 $2.destroy(); delete $3; delete $4;
1238 int yyerror(const char *ErrorMsg) {
1240 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1241 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1242 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1243 if (yychar == YYEMPTY || yychar == 0)
1244 errMsg += "end-of-file.";
1246 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1247 std::cerr << errMsg << '\n';