blob: f8f9bd3e38f2110ec87797f7b3559f38b07952c8 [file] [log] [blame]
Reid Spencer96839be2006-11-30 16:50:26 +00001//===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
Reid Spencere7c3c602006-11-30 06:36:44 +00002//
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//
Reid Spencer96839be2006-11-30 16:50:26 +000010// This file implements the bison parser for LLVM 1.9 assembly language.
Reid Spencere7c3c602006-11-30 06:36:44 +000011//
12//===----------------------------------------------------------------------===//
13
14%{
Reid Spencere7c3c602006-11-30 06:36:44 +000015#include "ParserInternals.h"
16#include <llvm/ADT/StringExtras.h>
Reid Spencere7c3c602006-11-30 06:36:44 +000017#include <algorithm>
Reid Spencera50d5962006-12-02 04:11:07 +000018#include <map>
Reid Spencere7c3c602006-11-30 06:36:44 +000019#include <utility>
20#include <iostream>
21
Reid Spencere77e35e2006-12-01 20:26:20 +000022#define YYERROR_VERBOSE 1
Reid Spencer96839be2006-11-30 16:50:26 +000023#define YYINCLUDED_STDLIB_H
Reid Spencere77e35e2006-12-01 20:26:20 +000024#define YYDEBUG 1
Reid Spencere7c3c602006-11-30 06:36:44 +000025
26int yylex(); // declaration" of xxx warnings.
27int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000028extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000029
30static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000031static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000032std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000033unsigned SizeOfPointer = 32;
Reid Spencer96839be2006-11-30 16:50:26 +000034
Reid Spencera50d5962006-12-02 04:11:07 +000035typedef std::vector<TypeInfo> TypeVector;
36static TypeVector EnumeratedTypes;
37typedef std::map<std::string,TypeInfo> TypeMap;
38static TypeMap NamedTypes;
39
Reid Spencerf8483652006-12-02 15:16:01 +000040void destroy(ValueList* VL) {
41 while (!VL->empty()) {
42 ValueInfo& VI = VL->back();
43 VI.destroy();
44 VL->pop_back();
45 }
46 delete VL;
47}
48
Reid Spencer96839be2006-11-30 16:50:26 +000049void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencere77e35e2006-12-01 20:26:20 +000050 std::ostream &out, bool debug)
Reid Spencere7c3c602006-11-30 06:36:44 +000051{
52 Upgradelineno = 1;
53 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000054 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000055 yydebug = debug;
Reid Spencere7c3c602006-11-30 06:36:44 +000056 O = &out;
57
58 if (yyparse()) {
59 std::cerr << "Parse failed.\n";
60 exit(1);
61 }
62}
63
Reid Spencera50d5962006-12-02 04:11:07 +000064static 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;
Reid Spencer280d8012006-12-01 23:40:53 +000069 else {
Reid Spencera50d5962006-12-02 04:11:07 +000070 std::string msg("Can't resolve type: ");
71 msg += *Ty.newTy;
72 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000073 }
Reid Spencera50d5962006-12-02 04:11:07 +000074 } else if (Ty.oldTy == NumericTy) {
75 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
76 if (ref < EnumeratedTypes.size()) {
77 Ty.oldTy = EnumeratedTypes[ref].oldTy;
78 } else {
79 std::string msg("Can't resolve type: ");
80 msg += *Ty.newTy;
81 yyerror(msg.c_str());
82 }
Reid Spencer280d8012006-12-01 23:40:53 +000083 }
Reid Spencera50d5962006-12-02 04:11:07 +000084 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000085}
86
Reid Spencera50d5962006-12-02 04:11:07 +000087static const char* getCastOpcode(
88 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
89{
Reid Spencere77e35e2006-12-01 20:26:20 +000090 unsigned SrcBits = SrcTy.getBitWidth();
91 unsigned DstBits = DstTy.getBitWidth();
92 const char* opcode = "bitcast";
93 // Run through the possibilities ...
94 if (DstTy.isIntegral()) { // Casting to integral
95 if (SrcTy.isIntegral()) { // Casting from integral
96 if (DstBits < SrcBits)
97 opcode = "trunc";
98 else if (DstBits > SrcBits) { // its an extension
99 if (SrcTy.isSigned())
100 opcode ="sext"; // signed -> SEXT
101 else
102 opcode = "zext"; // unsigned -> ZEXT
103 } else {
104 opcode = "bitcast"; // Same size, No-op cast
105 }
106 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
107 if (DstTy.isSigned())
108 opcode = "fptosi"; // FP -> sint
109 else
110 opcode = "fptoui"; // FP -> uint
111 } else if (SrcTy.isPacked()) {
112 assert(DstBits == SrcTy.getBitWidth() &&
113 "Casting packed to integer of different width");
114 opcode = "bitcast"; // same size, no-op cast
115 } else {
116 assert(SrcTy.isPointer() &&
117 "Casting from a value that is not first-class type");
118 opcode = "ptrtoint"; // ptr -> int
119 }
120 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
121 if (SrcTy.isIntegral()) { // Casting from integral
122 if (SrcTy.isSigned())
123 opcode = "sitofp"; // sint -> FP
124 else
125 opcode = "uitofp"; // uint -> FP
126 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
127 if (DstBits < SrcBits) {
128 opcode = "fptrunc"; // FP -> smaller FP
129 } else if (DstBits > SrcBits) {
130 opcode = "fpext"; // FP -> larger FP
131 } else {
132 opcode ="bitcast"; // same size, no-op cast
133 }
134 } else if (SrcTy.isPacked()) {
135 assert(DstBits == SrcTy.getBitWidth() &&
136 "Casting packed to floating point of different width");
137 opcode = "bitcast"; // same size, no-op cast
138 } else {
139 assert(0 && "Casting pointer or non-first class to float");
140 }
141 } else if (DstTy.isPacked()) {
142 if (SrcTy.isPacked()) {
143 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
144 "Casting packed to packed of different widths");
145 opcode = "bitcast"; // packed -> packed
146 } else if (DstTy.getBitWidth() == SrcBits) {
147 opcode = "bitcast"; // float/int -> packed
148 } else {
149 assert(!"Illegal cast to packed (wrong type or size)");
150 }
151 } else if (DstTy.isPointer()) {
152 if (SrcTy.isPointer()) {
153 opcode = "bitcast"; // ptr -> ptr
154 } else if (SrcTy.isIntegral()) {
155 opcode = "inttoptr"; // int -> ptr
156 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000157 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000158 }
159 } else {
160 assert(!"Casting to type that is not first-class");
161 }
162 return opcode;
163}
164
Reid Spencera50d5962006-12-02 04:11:07 +0000165static std::string getCastUpgrade(
166 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
167{
168 std::string Result;
169 std::string Source = Src;
170 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
171 // fp -> ptr cast is no longer supported but we must upgrade this
172 // by doing a double cast: fp -> int -> ptr
173 if (isConst)
174 Source = "ulong fptoui(" + Source + " to ulong)";
175 else {
176 *O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
177 Source = "ulong %cast_upgrade";
178 }
179 // Update the SrcTy for the getCastOpcode call below
180 SrcTy.destroy();
181 SrcTy.newTy = new std::string("ulong");
182 SrcTy.oldTy = ULongTy;
183 } else if (DstTy.oldTy == BoolTy) {
184 // cast ptr %x to bool was previously defined as setne ptr %x, null
185 // The ptrtoint semantic is to truncate, not compare so we must retain
186 // the original intent by replace the cast with a setne
187 const char* comparator = SrcTy.isPointer() ? ", null" :
188 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
189 if (isConst)
190 Result = "setne (" + Source + comparator + ")";
191 else
192 Result = "setne " + Source + comparator;
193 return Result; // skip cast processing below
194 }
195 ResolveType(SrcTy);
196 ResolveType(DstTy);
197 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
198 if (isConst)
199 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
200 else
201 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
202 return Result;
203}
204
Reid Spencere7c3c602006-11-30 06:36:44 +0000205%}
206
Reid Spencere77e35e2006-12-01 20:26:20 +0000207%file-prefix="UpgradeParser"
208
209%union {
210 std::string* String;
211 TypeInfo Type;
212 ValueInfo Value;
213 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000214 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000215}
216
Reid Spencerf2d55322006-12-01 21:52:30 +0000217%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000218%token <Type> FLOAT DOUBLE LABEL
219%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000220%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000221%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
Reid Spencerf7bde222006-12-01 22:26:37 +0000236%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000237%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000238%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
239%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000240
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
Reid Spencerf8483652006-12-02 15:16:01 +0000248%type <String> OptTailCall InstVal OptVolatile
Reid Spencere77e35e2006-12-01 20:26:20 +0000249%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
250%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencerf8483652006-12-02 15:16:01 +0000251%type <String> Name ValueRef ConstValueRef ConstVector
Reid Spencerfcb5df82006-12-01 22:34:43 +0000252%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
Reid Spencere77e35e2006-12-01 20:26:20 +0000253
Reid Spencerf8483652006-12-02 15:16:01 +0000254%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000255
256%type <Type> IntType SIntType UIntType FPType TypesV Types
257%type <Type> PrimType UpRTypesV UpRTypes
258
Reid Spencerf2d55322006-12-01 21:52:30 +0000259%type <String> IntVal EInt64Val
260%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000261
262%type <Value> ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000263
264%start Module
265
266%%
267
268// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000269IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000270EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000271
272// Operations that are notably excluded from this list include:
273// RET, BR, & SWITCH because they end basic blocks and are treated specially.
274ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
275LogicalOps : AND | OR | XOR;
276SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencerf7bde222006-12-01 22:26:37 +0000277ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000278CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
279 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
280 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000281
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.
284SIntType : LONG | INT | SHORT | SBYTE;
285UIntType : ULONG | UINT | USHORT | UBYTE;
286IntType : SIntType | UIntType;
287FPType : FLOAT | DOUBLE;
288
289// OptAssign - Value producing statements have an optional assignment component
290OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000291 $$ = $1;
292 }
293 | /*empty*/ {
294 $$ = new std::string("");
295 };
296
297OptLinkage
298 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
299 | EXTERN_WEAK
300 | /*empty*/ { $$ = new std::string(""); } ;
301
302OptCallingConv
303 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000304 | X86_FASTCALLCC_TOK
305 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000306 *$1 += *$2;
307 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000308 $$ = $1;
309 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000310 | /*empty*/ { $$ = new std::string(""); } ;
311
312// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
313// a comma before it.
314OptAlign
315 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000316 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencere7c3c602006-11-30 06:36:44 +0000317 ;
318OptCAlign
319 : /*empty*/ { $$ = new std::string(); }
320 | ',' ALIGN EUINT64VAL {
321 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000322 *$2 += " " + *$3;
323 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000324 $$ = $2;
325 };
326
327SectionString
328 : SECTION STRINGCONSTANT {
329 *$1 += " " + *$2;
330 delete $2;
331 $$ = $1;
332 };
333
334OptSection : /*empty*/ { $$ = new std::string(); }
335 | SectionString;
336
337GlobalVarAttributes
338 : /* empty */ { $$ = new std::string(); }
339 | ',' GlobalVarAttribute GlobalVarAttributes {
340 $2->insert(0, ", ");
341 if (!$3->empty())
342 *$2 += " " + *$3;
343 delete $3;
344 $$ = $2;
345 };
346
347GlobalVarAttribute
348 : SectionString
349 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000350 *$1 += " " + *$2;
351 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000352 $$ = $1;
353 };
354
355//===----------------------------------------------------------------------===//
356// Types includes all predefined types... except void, because it can only be
357// used in specific contexts (function returning void for example). To have
358// access to it, a user must explicitly use TypesV.
359//
360
361// TypesV includes all of 'Types', but it also includes the void type.
362TypesV : Types | VOID ;
363UpRTypesV : UpRTypes | VOID ;
364Types : UpRTypes ;
365
366// Derived types are added later...
367//
368PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000369PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000370UpRTypes
371 : OPAQUE {
372 $$.newTy = $1;
373 $$.oldTy = OpaqueTy;
374 }
375 | SymbolicValueRef {
376 $$.newTy = $1;
377 $$.oldTy = UnresolvedTy;
378 }
379 | PrimType
380 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000381
382// Include derived types in the Types production.
383//
384UpRTypes : '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000385 $2->insert(0, "\\");
386 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000387 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000388 }
389 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000390 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000391 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000392 $$.newTy = $1.newTy;
393 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000394 }
395 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000396 $2->insert(0,"[ ");
397 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000398 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000399 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000400 $$.oldTy = ArrayTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000401 }
402 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000403 $2->insert(0,"< ");
404 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000405 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000406 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000407 $$.oldTy = PackedTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000408 }
409 | '{' TypeListI '}' { // Structure type?
410 $2->insert(0, "{ ");
411 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000412 $$.newTy = $2;
413 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000414 }
415 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000416 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000417 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000418 }
419 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000420 *$1.newTy += '*';
421 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000422 $$ = $1;
423 };
424
425// TypeList - Used for struct declarations and as a basis for function type
426// declaration type lists
427//
Reid Spencere77e35e2006-12-01 20:26:20 +0000428TypeListI
429 : UpRTypes {
430 $$ = $1.newTy;
431 }
432 | TypeListI ',' UpRTypes {
433 *$1 += ", " + *$3.newTy;
434 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000435 $$ = $1;
436 };
437
438// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000439ArgTypeListI
440 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000441 | TypeListI ',' DOTDOTDOT {
442 *$1 += ", ...";
443 delete $3;
444 $$ = $1;
445 }
446 | DOTDOTDOT {
447 $$ = $1;
448 }
449 | /*empty*/ {
450 $$ = new std::string();
451 };
452
453// ConstVal - The various declarations that go into the constant pool. This
454// production is used ONLY to represent constants that show up AFTER a 'const',
455// 'constant' or 'global' token at global scope. Constants that can be inlined
456// into other expressions (such as integers and constexprs) are handled by the
457// ResolvedVal, ValueRef and ConstValueRef productions.
458//
459ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000460 $$.type = $1;
461 $$.cnst = new std::string(*$1.newTy);
462 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000463 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000464 }
465 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000466 $$.type = $1;
467 $$.cnst = new std::string(*$1.newTy);
468 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000469 }
470 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000471 $$.type = $1;
472 $$.cnst = new std::string(*$1.newTy);
473 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000474 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000475 }
476 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000477 $$.type = $1;
478 $$.cnst = new std::string(*$1.newTy);
479 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000480 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000481 }
482 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000483 $$.type = $1;
484 $$.cnst = new std::string(*$1.newTy);
485 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000486 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000487 }
488 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000489 $$.type = $1;
490 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000491 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000492 }
493 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000494 $$.type = $1;
495 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000496 *$$.cnst += " " + *$2;
497 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000498 }
499 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000500 $$.type = $1;
501 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000502 *$$.cnst += " " + *$2;
503 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000504 }
505 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000506 $$.type = $1;
507 $$.cnst = new std::string(*$1.newTy);
508 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000509 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000510 }
511 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000512 $$.type = $1;
513 $$.cnst = new std::string(*$1.newTy);
514 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000515 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000516 }
517 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000518 $$.type = $1;
519 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000520 *$$.cnst += " " + *$2;
521 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000522 }
523 | SIntType EInt64Val { // integral constants
524 $$.type = $1;
525 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000526 *$$.cnst += " " + *$2;
527 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000528 }
529 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000530 $$.type = $1;
531 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000532 *$$.cnst += " " + *$2;
533 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000534 }
535 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000536 $$.type = $1;
537 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000538 *$$.cnst += " " + *$2;
539 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000540 }
541 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000542 $$.type = $1;
543 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000544 *$$.cnst += " " + *$2;
545 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000546 }
547 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000548 $$.type = $1;
549 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000550 *$$.cnst += " " + *$2;
551 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000552 };
553
554
Reid Spencerfcb5df82006-12-01 22:34:43 +0000555ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000556 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000557 TypeInfo DstTy = $5;
558 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000559 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000560 // Call getCastUpgrade to upgrade the old cast
561 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
562 } else {
563 // Nothing to upgrade, just create the cast constant expr
564 $$ = new std::string(*$1);
565 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000566 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000567 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000568 }
569 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000570 *$1 += "(" + *$3.cnst;
571 for (unsigned i = 0; i < $4->size(); ++i) {
572 ValueInfo& VI = (*$4)[i];
573 *$1 += ", " + *VI.val;
574 VI.destroy();
575 }
576 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000577 $$ = $1;
578 $3.destroy();
579 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000580 }
581 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000582 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
583 $3.destroy(); $5.destroy(); $7.destroy();
584 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000585 }
586 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000587 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
588 $3.destroy(); $5.destroy();
589 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000590 }
591 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000592 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
593 $3.destroy(); $5.destroy();
594 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000595 }
596 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000597 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
598 $3.destroy(); $5.destroy();
599 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000600 }
601 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000602 const char* shiftop = $1->c_str();
603 if (*$1 == "shr")
604 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
605 $$ = new std::string(shiftop);
606 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
607 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000608 }
609 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000610 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
611 $3.destroy(); $5.destroy();
612 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000613 }
614 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000615 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
616 $3.destroy(); $5.destroy(); $7.destroy();
617 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000618 }
619 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000620 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
621 $3.destroy(); $5.destroy(); $7.destroy();
622 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000623 };
624
625
626// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000627
628ConstVector
629 : ConstVector ',' ConstVal {
630 *$1 += ", " + *$3.cnst;
631 $3.destroy();
632 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000633 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000634 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
635 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000636
637
638// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000639GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000640
641
642//===----------------------------------------------------------------------===//
643// Rules to match Modules
644//===----------------------------------------------------------------------===//
645
646// Module rule: Capture the result of parsing the whole file into a result
647// variable...
648//
649Module : DefinitionList {
650};
651
652// DefinitionList - Top level definitions
653//
654DefinitionList : DefinitionList Function {
655 $$ = 0;
656 }
657 | DefinitionList FunctionProto {
658 *O << *$2 << "\n";
659 delete $2;
660 $$ = 0;
661 }
662 | DefinitionList MODULE ASM_TOK AsmBlock {
663 *O << "module asm " << " " << *$4 << "\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000664 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000665 }
666 | DefinitionList IMPLEMENTATION {
667 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000668 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000669 }
Reid Spencera50d5962006-12-02 04:11:07 +0000670 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000671
672// ConstPool - Constants with optional names assigned to them.
673ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000674 EnumeratedTypes.push_back($4);
675 if (!$2->empty()) {
676 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
677 NamedTypes[*$2].oldTy = $4.oldTy;
678 *O << *$2 << " = ";
679 }
680 *O << "type " << *$4.newTy << "\n";
681 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000682 $$ = 0;
683 }
684 | ConstPool FunctionProto { // Function prototypes can be in const pool
685 *O << *$2 << "\n";
686 delete $2;
687 $$ = 0;
688 }
689 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
690 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
691 delete $2; delete $3; delete $4;
692 $$ = 0;
693 }
694 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000695 if (!$2->empty())
696 *O << *$2 << " = ";
697 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000698 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000699 $$ = 0;
700 }
701 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000702 if (!$2->empty())
703 *O << *$2 << " = ";
704 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000705 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000706 $$ = 0;
707 }
708 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000709 if (!$2->empty())
710 *O << *$2 << " = ";
711 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000712 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000713 $$ = 0;
714 }
715 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000716 if (!$2->empty())
717 *O << *$2 << " = ";
718 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000719 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000720 $$ = 0;
721 }
722 | ConstPool TARGET TargetDefinition {
723 *O << *$2 << " " << *$3 << "\n";
724 delete $2; delete $3;
725 $$ = 0;
726 }
727 | ConstPool DEPLIBS '=' LibrariesDefinition {
728 *O << *$2 << " = " << *$4 << "\n";
729 delete $2; delete $4;
730 $$ = 0;
731 }
732 | /* empty: end of list */ {
733 $$ = 0;
734 };
735
736
737AsmBlock : STRINGCONSTANT ;
738
739BigOrLittle : BIG | LITTLE
740
741TargetDefinition
742 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000743 *$1 += " = " + *$3;
744 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000745 $$ = $1;
746 }
747 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000748 *$1 += " = " + *$3;
749 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000750 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000751 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000752 $$ = $1;
753 }
754 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000755 *$1 += " = " + *$3;
756 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000757 $$ = $1;
758 }
759 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000760 *$1 += " = " + *$3;
761 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000762 $$ = $1;
763 };
764
765LibrariesDefinition
766 : '[' LibList ']' {
767 $2->insert(0, "[ ");
768 *$2 += " ]";
769 $$ = $2;
770 };
771
772LibList
773 : LibList ',' STRINGCONSTANT {
774 *$1 += ", " + *$3;
775 delete $3;
776 $$ = $1;
777 }
778 | STRINGCONSTANT
779 | /* empty: end of list */ {
780 $$ = new std::string();
781 };
782
783//===----------------------------------------------------------------------===//
784// Rules to match Function Headers
785//===----------------------------------------------------------------------===//
786
787Name : VAR_ID | STRINGCONSTANT;
788OptName : Name | /*empty*/ { $$ = new std::string(); };
789
790ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000791 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000792 if (!$2->empty())
793 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000794 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000795};
796
797ArgListH : ArgListH ',' ArgVal {
798 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000799 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000800 }
801 | ArgVal {
802 $$ = $1;
803 };
804
805ArgList : ArgListH {
806 $$ = $1;
807 }
808 | ArgListH ',' DOTDOTDOT {
809 *$1 += ", ...";
810 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000811 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000812 }
813 | DOTDOTDOT {
814 $$ = $1;
815 }
Reid Spencerd154b572006-12-01 20:36:40 +0000816 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000817
818FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
819 OptSection OptAlign {
820 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000821 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000822 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000823 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000824 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000825 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000826 }
827 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000828 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000829 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000830 $2.destroy();
831 delete $3;
832 delete $5;
833 delete $7;
834 delete $8;
835 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000836 };
837
838BEGIN : BEGINTOK {
839 $$ = new std::string("begin");
840 }
841 | '{' {
842 $$ = new std::string ("{");
843 }
844
845FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
846 if (!$1->empty()) {
847 *O << *$1 << " ";
848 }
849 *O << *$2 << " " << *$3 << "\n";
850 delete $1; delete $2; delete $3;
851 $$ = 0;
852};
853
854END : ENDTOK { $$ = new std::string("end"); }
855 | '}' { $$ = new std::string("}"); };
856
857Function : FunctionHeader BasicBlockList END {
858 if ($2)
859 *O << *$2;
860 *O << '\n' << *$3 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000861 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000862};
863
Reid Spencere77e35e2006-12-01 20:26:20 +0000864FnDeclareLinkage
865 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000866 | DLLIMPORT
867 | EXTERN_WEAK
868 ;
869
870FunctionProto
871 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000872 if (!$2->empty())
873 *$1 += " " + *$2;
874 *$1 += " " + *$3;
875 delete $2;
876 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000877 $$ = $1;
878 };
879
880//===----------------------------------------------------------------------===//
881// Rules to match Basic Blocks
882//===----------------------------------------------------------------------===//
883
Reid Spencerd154b572006-12-01 20:36:40 +0000884OptSideEffect : /* empty */ { $$ = new std::string(); }
885 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000886
Reid Spencere77e35e2006-12-01 20:26:20 +0000887ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000888 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
889 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +0000890 | '<' ConstVector '>' {
891 $2->insert(0, "<");
892 *$2 += ">";
893 $$ = $2;
894 }
895 | ConstExpr
896 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
897 if (!$2->empty()) {
898 *$1 += " " + *$2;
899 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000900 *$1 += " " + *$3 + ", " + *$5;
901 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +0000902 $$ = $1;
903 };
904
Reid Spencerf2d55322006-12-01 21:52:30 +0000905SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000906
907// ValueRef - A reference to a definition... either constant or symbolic
908ValueRef : SymbolicValueRef | ConstValueRef;
909
910
911// ResolvedVal - a <type> <value> pair. This is used only in cases where the
912// type immediately preceeds the value reference, and allows complex constant
913// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
914ResolvedVal : Types ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000915 $$.type = $1;
916 $$.val = new std::string(*$1.newTy + " ");
917 *$$.val += *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000918 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000919 };
920
921BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +0000922 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000923 }
924 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +0000925 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000926 };
927
928
929// Basic blocks are terminated by branching instructions:
930// br, br/cc, switch, ret
931//
Reid Spencer16244f42006-12-01 21:10:07 +0000932BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +0000933 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000934 };
935
936InstructionList : InstructionList Inst {
937 *O << " " << *$2 << "\n";
938 delete $2;
939 $$ = 0;
940 }
941 | /* empty */ {
942 $$ = 0;
943 }
944 | LABELSTR {
945 *O << *$1 << "\n";
946 delete $1;
947 $$ = 0;
948 };
949
950BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000951 *O << " " << *$1 << " " << *$2.val << "\n";
952 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000953 $$ = 0;
954 }
955 | RET VOID { // Return with no result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000956 *O << " " << *$1 << " " << *$2.newTy << "\n";
957 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000958 $$ = 0;
959 }
960 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencere77e35e2006-12-01 20:26:20 +0000961 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
962 delete $1; $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000963 $$ = 0;
964 } // Conditional Branch...
965 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000966 *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;
Reid Spencere7c3c602006-11-30 06:36:44 +0000970 $$ = 0;
971 }
972 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000973 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
974 << " " << *$6 << " [" << *$8 << " ]\n";
975 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000976 $$ = 0;
977 }
978 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000979 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
980 << *$5.newTy << " " << *$6 << "[]\n";
981 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000982 $$ = 0;
983 }
Reid Spencer16244f42006-12-01 21:10:07 +0000984 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencere7c3c602006-11-30 06:36:44 +0000985 TO LABEL ValueRef UNWIND LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +0000986 *O << " ";
987 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +0000988 *O << *$1 << " = ";
Reid Spencerf8483652006-12-02 15:16:01 +0000989 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " (";
990 for (unsigned i = 0; i < $7->size(); ++i) {
991 ValueInfo& VI = (*$7)[i];
992 *O << *VI.val;
993 if (i+1 < $7->size())
994 *O << ", ";
995 VI.destroy();
996 }
997 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
Reid Spencer16244f42006-12-01 21:10:07 +0000998 << *$12 << " " << *$13.newTy << " " << *$14 << "\n";
999 delete $1; delete $2; delete $3; $4.destroy(); delete $5; delete $7;
1000 delete $9; $10.destroy(); delete $11; delete $12; $13.destroy();
1001 delete $14;
Reid Spencere7c3c602006-11-30 06:36:44 +00001002 $$ = 0;
1003 }
1004 | UNWIND {
1005 *O << " " << *$1 << "\n";
1006 delete $1;
1007 $$ = 0;
1008 }
1009 | UNREACHABLE {
1010 *O << " " << *$1 << "\n";
1011 delete $1;
1012 $$ = 0;
1013 };
1014
1015JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001016 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +00001017 $2.destroy(); delete $3; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001018 $$ = $1;
1019 }
1020 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001021 $2->insert(0, *$1.newTy + " " );
1022 *$2 += ", " + *$4.newTy + " " + *$5;
1023 $1.destroy(); $4.destroy(); delete $5;
1024 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001025 };
1026
1027Inst
1028 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001029 if (!$1->empty())
1030 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001031 *$1 += *$2;
1032 delete $2;
1033 $$ = $1;
1034 };
1035
1036PHIList
1037 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencere77e35e2006-12-01 20:26:20 +00001038 $3->insert(0, *$1.newTy + "[");
1039 *$3 += "," + *$5 + "]";
1040 $1.destroy(); delete $5;
1041 $$ = $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001042 }
1043 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1044 *$1 += ", [" + *$4 + "," + *$6 + "]";
1045 delete $4; delete $6;
1046 $$ = $1;
1047 };
1048
1049
1050ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001051 : ResolvedVal {
1052 $$ = new ValueList();
1053 $$->push_back($1);
1054 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001055 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001056 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001057 $$ = $1;
1058 };
1059
1060// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1061ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001062 : ValueRefList { $$ = $1; }
1063 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001064 ;
1065
1066OptTailCall
1067 : TAIL CALL {
1068 *$1 += " " + *$2;
1069 delete $2;
1070 $$ = $1;
1071 }
1072 | CALL
1073 ;
1074
1075InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001076 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1077 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001078 $$ = $1;
1079 }
1080 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001081 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1082 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001083 $$ = $1;
1084 }
1085 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001086 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1087 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001088 $$ = $1;
1089 }
1090 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001091 *$1 += " " + *$2.val;
1092 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001093 $$ = $1;
1094 }
1095 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001096 const char* shiftop = $1->c_str();
1097 if (*$1 == "shr")
1098 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1099 $$ = new std::string(shiftop);
1100 *$$ += " " + *$2.val + ", " + *$4.val;
1101 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001102 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001103 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001104 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001105 TypeInfo SrcTy = $2.type;
1106 TypeInfo DstTy = $4;
1107 ResolveType(DstTy);
1108 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001109 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001110 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1111 } else {
1112 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001113 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001114 delete $1; $2.destroy();
1115 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001116 }
1117 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001118 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1119 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001120 $$ = $1;
1121 }
1122 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001123 *$1 += " " + *$2.val + ", " + *$4.newTy;
1124 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001125 $$ = $1;
1126 }
1127 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001128 *$1 += " " + *$2.val + ", " + *$4.val;
1129 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001130 $$ = $1;
1131 }
1132 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001133 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1134 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001135 $$ = $1;
1136 }
1137 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001138 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1139 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001140 $$ = $1;
1141 }
1142 | PHI_TOK PHIList {
1143 *$1 += " " + *$2;
1144 delete $2;
1145 $$ = $1;
1146 }
1147 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1148 if (!$2->empty())
1149 *$1 += " " + *$2;
1150 if (!$1->empty())
1151 *$1 += " ";
Reid Spencerf8483652006-12-02 15:16:01 +00001152 *$1 += *$3.newTy + " " + *$4 + "(";
1153 for (unsigned i = 0; i < $6->size(); ++i) {
1154 ValueInfo& VI = (*$6)[i];
1155 *$1 += *VI.val;
1156 if (i+1 < $6->size())
1157 *$1 += ", ";
1158 VI.destroy();
1159 }
1160 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +00001161 delete $2; $3.destroy(); delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001162 $$ = $1;
1163 }
1164 | MemoryInst ;
1165
1166
1167// IndexList - List of indices for GEP based instructions...
1168IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001169 : ',' ValueRefList { $$ = $2; }
1170 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001171 ;
1172
1173OptVolatile
1174 : VOLATILE
1175 | /* empty */ { $$ = new std::string(); }
1176 ;
1177
1178MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001179 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001180 if (!$3->empty())
1181 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001182 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001183 $$ = $1;
1184 }
1185 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001186 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001187 if (!$6->empty())
1188 *$1 += " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +00001189 $2.destroy(); $4.destroy(); delete $5; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001190 $$ = $1;
1191 }
1192 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001193 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001194 if (!$3->empty())
1195 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001196 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001197 $$ = $1;
1198 }
1199 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001200 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001201 if (!$6->empty())
1202 *$1 += " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +00001203 $2.destroy(); $4.destroy(); delete $5; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001204 $$ = $1;
1205 }
1206 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001207 *$1 += " " + *$2.val;
1208 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001209 $$ = $1;
1210 }
1211 | OptVolatile LOAD Types ValueRef {
1212 if (!$1->empty())
1213 *$1 += " ";
Reid Spencere77e35e2006-12-01 20:26:20 +00001214 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1215 delete $2; $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001216 $$ = $1;
1217 }
1218 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1219 if (!$1->empty())
1220 *$1 += " ";
Reid Spencere77e35e2006-12-01 20:26:20 +00001221 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1222 delete $2; $3.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001223 $$ = $1;
1224 }
1225 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf8483652006-12-02 15:16:01 +00001226 *$1 += " " + *$2.newTy + " " + *$3;
1227 for (unsigned i = 0; i < $4->size(); ++i) {
1228 ValueInfo& VI = (*$4)[i];
1229 *$1 += ", " + *VI.val;
1230 VI.destroy();
1231 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001232 $2.destroy(); delete $3; delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001233 $$ = $1;
1234 };
1235
1236%%
1237
1238int yyerror(const char *ErrorMsg) {
1239 std::string where
1240 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1241 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1242 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1243 if (yychar == YYEMPTY || yychar == 0)
1244 errMsg += "end-of-file.";
1245 else
1246 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1247 std::cerr << errMsg << '\n';
1248 exit(1);
1249}