blob: fedff0ee80e1d70d1726dea23eccb22b3c79dd1b [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 Spencer229e9362006-12-02 22:14:11 +000025#define UPGRADE_SETCOND_OPS 1
Reid Spencere7c3c602006-11-30 06:36:44 +000026
27int yylex(); // declaration" of xxx warnings.
28int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000029extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000030
31static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000032static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000033std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000034unsigned SizeOfPointer = 32;
Reid Spencerf459d392006-12-02 16:19:52 +000035static uint64_t unique = 1;
Reid Spencer96839be2006-11-30 16:50:26 +000036
Reid Spencera50d5962006-12-02 04:11:07 +000037typedef std::vector<TypeInfo> TypeVector;
38static TypeVector EnumeratedTypes;
39typedef std::map<std::string,TypeInfo> TypeMap;
40static TypeMap NamedTypes;
41
Reid Spencerf8483652006-12-02 15:16:01 +000042void destroy(ValueList* VL) {
43 while (!VL->empty()) {
44 ValueInfo& VI = VL->back();
45 VI.destroy();
46 VL->pop_back();
47 }
48 delete VL;
49}
50
Reid Spencer96839be2006-11-30 16:50:26 +000051void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencere77e35e2006-12-01 20:26:20 +000052 std::ostream &out, bool debug)
Reid Spencere7c3c602006-11-30 06:36:44 +000053{
54 Upgradelineno = 1;
55 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000056 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000057 yydebug = debug;
Reid Spencere7c3c602006-11-30 06:36:44 +000058 O = &out;
59
60 if (yyparse()) {
61 std::cerr << "Parse failed.\n";
62 exit(1);
63 }
64}
65
Reid Spencera50d5962006-12-02 04:11:07 +000066static void ResolveType(TypeInfo& Ty) {
67 if (Ty.oldTy == UnresolvedTy) {
68 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
Reid Spencer78720742006-12-02 20:21:22 +000069 if (I != NamedTypes.end()) {
Reid Spencera50d5962006-12-02 04:11:07 +000070 Ty.oldTy = I->second.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000071 Ty.elemTy = I->second.elemTy;
72 } else {
Reid Spencera50d5962006-12-02 04:11:07 +000073 std::string msg("Can't resolve type: ");
74 msg += *Ty.newTy;
75 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000076 }
Reid Spencera50d5962006-12-02 04:11:07 +000077 } else if (Ty.oldTy == NumericTy) {
78 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
79 if (ref < EnumeratedTypes.size()) {
80 Ty.oldTy = EnumeratedTypes[ref].oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000081 Ty.elemTy = EnumeratedTypes[ref].elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +000082 } else {
83 std::string msg("Can't resolve type: ");
84 msg += *Ty.newTy;
85 yyerror(msg.c_str());
86 }
Reid Spencer280d8012006-12-01 23:40:53 +000087 }
Reid Spencera50d5962006-12-02 04:11:07 +000088 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000089}
90
Reid Spencera50d5962006-12-02 04:11:07 +000091static const char* getCastOpcode(
92 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
93{
Reid Spencere77e35e2006-12-01 20:26:20 +000094 unsigned SrcBits = SrcTy.getBitWidth();
95 unsigned DstBits = DstTy.getBitWidth();
96 const char* opcode = "bitcast";
97 // Run through the possibilities ...
98 if (DstTy.isIntegral()) { // Casting to integral
99 if (SrcTy.isIntegral()) { // Casting from integral
100 if (DstBits < SrcBits)
101 opcode = "trunc";
102 else if (DstBits > SrcBits) { // its an extension
103 if (SrcTy.isSigned())
104 opcode ="sext"; // signed -> SEXT
105 else
106 opcode = "zext"; // unsigned -> ZEXT
107 } else {
108 opcode = "bitcast"; // Same size, No-op cast
109 }
110 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
111 if (DstTy.isSigned())
112 opcode = "fptosi"; // FP -> sint
113 else
114 opcode = "fptoui"; // FP -> uint
115 } else if (SrcTy.isPacked()) {
116 assert(DstBits == SrcTy.getBitWidth() &&
117 "Casting packed to integer of different width");
118 opcode = "bitcast"; // same size, no-op cast
119 } else {
120 assert(SrcTy.isPointer() &&
121 "Casting from a value that is not first-class type");
122 opcode = "ptrtoint"; // ptr -> int
123 }
124 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
125 if (SrcTy.isIntegral()) { // Casting from integral
126 if (SrcTy.isSigned())
127 opcode = "sitofp"; // sint -> FP
128 else
129 opcode = "uitofp"; // uint -> FP
130 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
131 if (DstBits < SrcBits) {
132 opcode = "fptrunc"; // FP -> smaller FP
133 } else if (DstBits > SrcBits) {
134 opcode = "fpext"; // FP -> larger FP
135 } else {
136 opcode ="bitcast"; // same size, no-op cast
137 }
138 } else if (SrcTy.isPacked()) {
139 assert(DstBits == SrcTy.getBitWidth() &&
140 "Casting packed to floating point of different width");
141 opcode = "bitcast"; // same size, no-op cast
142 } else {
143 assert(0 && "Casting pointer or non-first class to float");
144 }
145 } else if (DstTy.isPacked()) {
146 if (SrcTy.isPacked()) {
147 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
148 "Casting packed to packed of different widths");
149 opcode = "bitcast"; // packed -> packed
150 } else if (DstTy.getBitWidth() == SrcBits) {
151 opcode = "bitcast"; // float/int -> packed
152 } else {
153 assert(!"Illegal cast to packed (wrong type or size)");
154 }
155 } else if (DstTy.isPointer()) {
156 if (SrcTy.isPointer()) {
157 opcode = "bitcast"; // ptr -> ptr
158 } else if (SrcTy.isIntegral()) {
159 opcode = "inttoptr"; // int -> ptr
160 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000161 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000162 }
163 } else {
164 assert(!"Casting to type that is not first-class");
165 }
166 return opcode;
167}
168
Reid Spencera50d5962006-12-02 04:11:07 +0000169static std::string getCastUpgrade(
170 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
171{
172 std::string Result;
173 std::string Source = Src;
174 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
175 // fp -> ptr cast is no longer supported but we must upgrade this
176 // by doing a double cast: fp -> int -> ptr
177 if (isConst)
178 Source = "ulong fptoui(" + Source + " to ulong)";
179 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000180 *O << " %cast_upgrade" << unique << " = fptoui " << Source
181 << " to ulong\n";
182 Source = "ulong %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000183 }
184 // Update the SrcTy for the getCastOpcode call below
185 SrcTy.destroy();
186 SrcTy.newTy = new std::string("ulong");
187 SrcTy.oldTy = ULongTy;
188 } else if (DstTy.oldTy == BoolTy) {
189 // cast ptr %x to bool was previously defined as setne ptr %x, null
190 // The ptrtoint semantic is to truncate, not compare so we must retain
191 // the original intent by replace the cast with a setne
192 const char* comparator = SrcTy.isPointer() ? ", null" :
193 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
194 if (isConst)
195 Result = "setne (" + Source + comparator + ")";
196 else
197 Result = "setne " + Source + comparator;
198 return Result; // skip cast processing below
199 }
200 ResolveType(SrcTy);
201 ResolveType(DstTy);
202 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
203 if (isConst)
204 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
205 else
206 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
207 return Result;
208}
209
Reid Spencer78720742006-12-02 20:21:22 +0000210const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
211 const char* op = opcode.c_str();
212 TypeInfo Ty = TI;
213 ResolveType(Ty);
214 if (Ty.isPacked())
215 Ty.oldTy = Ty.getElementType();
216 if (opcode == "div")
217 if (Ty.isFloatingPoint())
218 op = "fdiv";
219 else if (Ty.isUnsigned())
220 op = "udiv";
221 else if (Ty.isSigned())
222 op = "sdiv";
223 else
224 yyerror("Invalid type for div instruction");
225 else if (opcode == "rem")
226 if (Ty.isFloatingPoint())
227 op = "frem";
228 else if (Ty.isUnsigned())
229 op = "urem";
230 else if (Ty.isSigned())
231 op = "srem";
232 else
233 yyerror("Invalid type for rem instruction");
234 return op;
235}
Reid Spencer229e9362006-12-02 22:14:11 +0000236
237std::string
238getCompareOp(const std::string& setcc, const TypeInfo& TI) {
239 assert(setcc.length() == 5);
240 char cc1 = setcc[3];
241 char cc2 = setcc[4];
242 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
243 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
244 std::string result("xcmp xxx");
245 result[6] = cc1;
246 result[7] = cc2;
247 if (TI.isFloatingPoint()) {
248 result[0] = 'f';
249 result[5] = 'o'; // FIXME: Always map to ordered comparison ?
250 } else if (TI.isIntegral() || TI.isPointer()) {
251 result[0] = 'i';
252 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
253 result.erase(5,1);
254 else if (TI.isSigned())
255 result[5] = 's';
256 else if (TI.isUnsigned() || TI.isPointer())
257 result[5] = 'u';
258 else
259 yyerror("Invalid integral type for setcc");
260 }
261 return result;
262}
263
Reid Spencere7c3c602006-11-30 06:36:44 +0000264%}
265
Reid Spencere77e35e2006-12-01 20:26:20 +0000266%file-prefix="UpgradeParser"
267
268%union {
269 std::string* String;
270 TypeInfo Type;
271 ValueInfo Value;
272 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000273 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000274}
275
Reid Spencerf2d55322006-12-01 21:52:30 +0000276%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000277%token <Type> FLOAT DOUBLE LABEL
278%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000279%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000280%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
281%token <String> IMPLEMENTATION BEGINTOK ENDTOK
282%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
283%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
284%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
285%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000286%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000287%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
288%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
289%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
290%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000291%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
292%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000293%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000294%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
295%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000296%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000297%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000298%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000299%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
300%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000301
302%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
303%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
304%type <String> ArgTypeListI ConstExpr DefinitionList
305%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
306%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
307%type <String> Function FunctionProto BasicBlock TypeListI
308%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
Reid Spencer78720742006-12-02 20:21:22 +0000309%type <String> OptTailCall InstVal OptVolatile Unwind
Reid Spencere77e35e2006-12-01 20:26:20 +0000310%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
311%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000312%type <String> Name ConstValueRef ConstVector External
Reid Spencer229e9362006-12-02 22:14:11 +0000313%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps CompareOps
314%type <String> Predicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000315
Reid Spencerf8483652006-12-02 15:16:01 +0000316%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000317
318%type <Type> IntType SIntType UIntType FPType TypesV Types
319%type <Type> PrimType UpRTypesV UpRTypes
320
Reid Spencerf2d55322006-12-01 21:52:30 +0000321%type <String> IntVal EInt64Val
322%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000323
Reid Spencerf459d392006-12-02 16:19:52 +0000324%type <Value> ValueRef ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000325
326%start Module
327
328%%
329
330// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000331IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000332EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000333
334// Operations that are notably excluded from this list include:
335// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000336ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
337 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000338LogicalOps : AND | OR | XOR;
339SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer229e9362006-12-02 22:14:11 +0000340CompareOps : ICMP | FCMP;
341Predicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE
342 | OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE ;
Reid Spencerf7bde222006-12-01 22:26:37 +0000343ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000344CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
345 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
346 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000347
348// These are some types that allow classification if we only want a particular
349// thing... for example, only a signed, unsigned, or integral type.
350SIntType : LONG | INT | SHORT | SBYTE;
351UIntType : ULONG | UINT | USHORT | UBYTE;
352IntType : SIntType | UIntType;
353FPType : FLOAT | DOUBLE;
354
355// OptAssign - Value producing statements have an optional assignment component
356OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000357 $$ = $1;
358 }
359 | /*empty*/ {
360 $$ = new std::string("");
361 };
362
363OptLinkage
364 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
365 | EXTERN_WEAK
366 | /*empty*/ { $$ = new std::string(""); } ;
367
368OptCallingConv
369 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000370 | X86_FASTCALLCC_TOK
371 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000372 *$1 += *$2;
373 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000374 $$ = $1;
375 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000376 | /*empty*/ { $$ = new std::string(""); } ;
377
378// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
379// a comma before it.
380OptAlign
381 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000382 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencere7c3c602006-11-30 06:36:44 +0000383 ;
384OptCAlign
385 : /*empty*/ { $$ = new std::string(); }
386 | ',' ALIGN EUINT64VAL {
387 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000388 *$2 += " " + *$3;
389 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000390 $$ = $2;
391 };
392
393SectionString
394 : SECTION STRINGCONSTANT {
395 *$1 += " " + *$2;
396 delete $2;
397 $$ = $1;
398 };
399
400OptSection : /*empty*/ { $$ = new std::string(); }
401 | SectionString;
402
403GlobalVarAttributes
404 : /* empty */ { $$ = new std::string(); }
405 | ',' GlobalVarAttribute GlobalVarAttributes {
406 $2->insert(0, ", ");
407 if (!$3->empty())
408 *$2 += " " + *$3;
409 delete $3;
410 $$ = $2;
411 };
412
413GlobalVarAttribute
414 : SectionString
415 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000416 *$1 += " " + *$2;
417 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000418 $$ = $1;
419 };
420
421//===----------------------------------------------------------------------===//
422// Types includes all predefined types... except void, because it can only be
423// used in specific contexts (function returning void for example). To have
424// access to it, a user must explicitly use TypesV.
425//
426
427// TypesV includes all of 'Types', but it also includes the void type.
428TypesV : Types | VOID ;
429UpRTypesV : UpRTypes | VOID ;
430Types : UpRTypes ;
431
432// Derived types are added later...
433//
434PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000435PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000436UpRTypes
437 : OPAQUE {
438 $$.newTy = $1;
439 $$.oldTy = OpaqueTy;
440 }
441 | SymbolicValueRef {
442 $$.newTy = $1;
443 $$.oldTy = UnresolvedTy;
444 }
Reid Spencer78720742006-12-02 20:21:22 +0000445 | PrimType {
446 $$ = $1;
447 }
448 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000449 $2->insert(0, "\\");
450 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000451 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000452 }
453 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000454 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000455 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000456 $$.newTy = $1.newTy;
457 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000458 }
459 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000460 $2->insert(0,"[ ");
461 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000462 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000463 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000464 $$.oldTy = ArrayTy;
Reid Spencer78720742006-12-02 20:21:22 +0000465 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000466 }
467 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000468 $2->insert(0,"< ");
469 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000470 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000471 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000472 $$.oldTy = PackedTy;
Reid Spencer78720742006-12-02 20:21:22 +0000473 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000474 }
475 | '{' TypeListI '}' { // Structure type?
476 $2->insert(0, "{ ");
477 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000478 $$.newTy = $2;
479 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000480 }
481 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000482 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000483 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000484 }
485 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000486 *$1.newTy += '*';
Reid Spencer78720742006-12-02 20:21:22 +0000487 $$.elemTy = $1.oldTy;
Reid Spencere77e35e2006-12-01 20:26:20 +0000488 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000489 $$ = $1;
490 };
491
492// TypeList - Used for struct declarations and as a basis for function type
493// declaration type lists
494//
Reid Spencere77e35e2006-12-01 20:26:20 +0000495TypeListI
496 : UpRTypes {
497 $$ = $1.newTy;
498 }
499 | TypeListI ',' UpRTypes {
500 *$1 += ", " + *$3.newTy;
501 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000502 $$ = $1;
503 };
504
505// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000506ArgTypeListI
507 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000508 | TypeListI ',' DOTDOTDOT {
509 *$1 += ", ...";
510 delete $3;
511 $$ = $1;
512 }
513 | DOTDOTDOT {
514 $$ = $1;
515 }
516 | /*empty*/ {
517 $$ = new std::string();
518 };
519
520// ConstVal - The various declarations that go into the constant pool. This
521// production is used ONLY to represent constants that show up AFTER a 'const',
522// 'constant' or 'global' token at global scope. Constants that can be inlined
523// into other expressions (such as integers and constexprs) are handled by the
524// ResolvedVal, ValueRef and ConstValueRef productions.
525//
526ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000527 $$.type = $1;
528 $$.cnst = new std::string(*$1.newTy);
529 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000530 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000531 }
532 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000533 $$.type = $1;
534 $$.cnst = new std::string(*$1.newTy);
535 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000536 }
537 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000538 $$.type = $1;
539 $$.cnst = new std::string(*$1.newTy);
540 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000541 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000542 }
543 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000544 $$.type = $1;
545 $$.cnst = new std::string(*$1.newTy);
546 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000547 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000548 }
549 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000550 $$.type = $1;
551 $$.cnst = new std::string(*$1.newTy);
552 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000553 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000554 }
555 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000556 $$.type = $1;
557 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000558 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000559 }
560 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000561 $$.type = $1;
562 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000563 *$$.cnst += " " + *$2;
564 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000565 }
566 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000567 $$.type = $1;
568 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000569 *$$.cnst += " " + *$2;
570 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000571 }
572 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000573 $$.type = $1;
574 $$.cnst = new std::string(*$1.newTy);
575 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000576 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000577 }
578 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000579 $$.type = $1;
580 $$.cnst = new std::string(*$1.newTy);
581 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000582 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000583 }
584 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000585 $$.type = $1;
586 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000587 *$$.cnst += " " + *$2;
588 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000589 }
590 | SIntType EInt64Val { // integral constants
591 $$.type = $1;
592 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000593 *$$.cnst += " " + *$2;
594 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000595 }
596 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000597 $$.type = $1;
598 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000599 *$$.cnst += " " + *$2;
600 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000601 }
602 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000603 $$.type = $1;
604 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000605 *$$.cnst += " " + *$2;
606 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000607 }
608 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000609 $$.type = $1;
610 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000611 *$$.cnst += " " + *$2;
612 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000613 }
614 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000615 $$.type = $1;
616 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000617 *$$.cnst += " " + *$2;
618 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000619 };
620
621
Reid Spencerfcb5df82006-12-01 22:34:43 +0000622ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000623 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000624 TypeInfo DstTy = $5;
625 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000626 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000627 // Call getCastUpgrade to upgrade the old cast
628 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
629 } else {
630 // Nothing to upgrade, just create the cast constant expr
631 $$ = new std::string(*$1);
632 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000633 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000634 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000635 }
636 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000637 *$1 += "(" + *$3.cnst;
638 for (unsigned i = 0; i < $4->size(); ++i) {
639 ValueInfo& VI = (*$4)[i];
640 *$1 += ", " + *VI.val;
641 VI.destroy();
642 }
643 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000644 $$ = $1;
645 $3.destroy();
646 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000647 }
648 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000649 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
650 $3.destroy(); $5.destroy(); $7.destroy();
651 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000652 }
653 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000654 const char* op = getDivRemOpcode(*$1, $3.type);
655 $$ = new std::string(op);
656 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
657 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000658 }
659 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000660 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
661 $3.destroy(); $5.destroy();
662 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000663 }
664 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000665#if UPGRADE_SETCOND_OPS
666 *$1 = getCompareOp(*$1, $3.type);
667#endif
Reid Spencere77e35e2006-12-01 20:26:20 +0000668 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
669 $3.destroy(); $5.destroy();
670 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000671 }
Reid Spencer229e9362006-12-02 22:14:11 +0000672 | CompareOps Predicates '(' ConstVal ',' ConstVal ')' {
673 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
674 delete $2; $4.destroy(); $6.destroy();
675 $$ = $1;
676 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000677 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000678 const char* shiftop = $1->c_str();
679 if (*$1 == "shr")
680 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
681 $$ = new std::string(shiftop);
682 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
683 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000684 }
685 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000686 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
687 $3.destroy(); $5.destroy();
688 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000689 }
690 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000691 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
692 $3.destroy(); $5.destroy(); $7.destroy();
693 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000694 }
695 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000696 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
697 $3.destroy(); $5.destroy(); $7.destroy();
698 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000699 };
700
701
702// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000703
704ConstVector
705 : ConstVector ',' ConstVal {
706 *$1 += ", " + *$3.cnst;
707 $3.destroy();
708 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000709 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000710 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
711 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000712
713
714// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000715GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000716
717
718//===----------------------------------------------------------------------===//
719// Rules to match Modules
720//===----------------------------------------------------------------------===//
721
722// Module rule: Capture the result of parsing the whole file into a result
723// variable...
724//
725Module : DefinitionList {
726};
727
728// DefinitionList - Top level definitions
729//
730DefinitionList : DefinitionList Function {
731 $$ = 0;
732 }
733 | DefinitionList FunctionProto {
734 *O << *$2 << "\n";
735 delete $2;
736 $$ = 0;
737 }
738 | DefinitionList MODULE ASM_TOK AsmBlock {
739 *O << "module asm " << " " << *$4 << "\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000740 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000741 }
742 | DefinitionList IMPLEMENTATION {
743 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000744 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000745 }
Reid Spencera50d5962006-12-02 04:11:07 +0000746 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000747
Reid Spencer78720742006-12-02 20:21:22 +0000748External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
749
Reid Spencere7c3c602006-11-30 06:36:44 +0000750// ConstPool - Constants with optional names assigned to them.
751ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000752 EnumeratedTypes.push_back($4);
753 if (!$2->empty()) {
754 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
755 NamedTypes[*$2].oldTy = $4.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +0000756 NamedTypes[*$2].elemTy = $4.elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +0000757 *O << *$2 << " = ";
758 }
759 *O << "type " << *$4.newTy << "\n";
760 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000761 $$ = 0;
762 }
763 | ConstPool FunctionProto { // Function prototypes can be in const pool
764 *O << *$2 << "\n";
765 delete $2;
766 $$ = 0;
767 }
768 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
769 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
770 delete $2; delete $3; delete $4;
771 $$ = 0;
772 }
773 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000774 if (!$2->empty())
775 *O << *$2 << " = ";
776 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000777 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000778 $$ = 0;
779 }
Reid Spencer78720742006-12-02 20:21:22 +0000780 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000781 if (!$2->empty())
782 *O << *$2 << " = ";
783 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000784 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000785 $$ = 0;
786 }
787 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000788 if (!$2->empty())
789 *O << *$2 << " = ";
790 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000791 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000792 $$ = 0;
793 }
794 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000795 if (!$2->empty())
796 *O << *$2 << " = ";
797 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000798 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000799 $$ = 0;
800 }
801 | ConstPool TARGET TargetDefinition {
802 *O << *$2 << " " << *$3 << "\n";
803 delete $2; delete $3;
804 $$ = 0;
805 }
806 | ConstPool DEPLIBS '=' LibrariesDefinition {
807 *O << *$2 << " = " << *$4 << "\n";
808 delete $2; delete $4;
809 $$ = 0;
810 }
811 | /* empty: end of list */ {
812 $$ = 0;
813 };
814
815
816AsmBlock : STRINGCONSTANT ;
817
818BigOrLittle : BIG | LITTLE
819
820TargetDefinition
821 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000822 *$1 += " = " + *$3;
823 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000824 $$ = $1;
825 }
826 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000827 *$1 += " = " + *$3;
828 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000829 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000830 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000831 $$ = $1;
832 }
833 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000834 *$1 += " = " + *$3;
835 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000836 $$ = $1;
837 }
838 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000839 *$1 += " = " + *$3;
840 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000841 $$ = $1;
842 };
843
844LibrariesDefinition
845 : '[' LibList ']' {
846 $2->insert(0, "[ ");
847 *$2 += " ]";
848 $$ = $2;
849 };
850
851LibList
852 : LibList ',' STRINGCONSTANT {
853 *$1 += ", " + *$3;
854 delete $3;
855 $$ = $1;
856 }
857 | STRINGCONSTANT
858 | /* empty: end of list */ {
859 $$ = new std::string();
860 };
861
862//===----------------------------------------------------------------------===//
863// Rules to match Function Headers
864//===----------------------------------------------------------------------===//
865
866Name : VAR_ID | STRINGCONSTANT;
867OptName : Name | /*empty*/ { $$ = new std::string(); };
868
869ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000870 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000871 if (!$2->empty())
872 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000873 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000874};
875
876ArgListH : ArgListH ',' ArgVal {
877 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000878 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000879 }
880 | ArgVal {
881 $$ = $1;
882 };
883
884ArgList : ArgListH {
885 $$ = $1;
886 }
887 | ArgListH ',' DOTDOTDOT {
888 *$1 += ", ...";
889 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000890 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000891 }
892 | DOTDOTDOT {
893 $$ = $1;
894 }
Reid Spencerd154b572006-12-01 20:36:40 +0000895 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000896
897FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
898 OptSection OptAlign {
899 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000900 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000901 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000902 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000903 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000904 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000905 }
906 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000907 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000908 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000909 $2.destroy();
910 delete $3;
911 delete $5;
912 delete $7;
913 delete $8;
914 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000915 };
916
Reid Spencer78720742006-12-02 20:21:22 +0000917BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
918 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000919
920FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
921 if (!$1->empty()) {
922 *O << *$1 << " ";
923 }
924 *O << *$2 << " " << *$3 << "\n";
925 delete $1; delete $2; delete $3;
926 $$ = 0;
927};
928
Reid Spencer78720742006-12-02 20:21:22 +0000929END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000930 | '}' { $$ = new std::string("}"); };
931
932Function : FunctionHeader BasicBlockList END {
933 if ($2)
934 *O << *$2;
935 *O << '\n' << *$3 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000936 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000937};
938
Reid Spencere77e35e2006-12-01 20:26:20 +0000939FnDeclareLinkage
940 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000941 | DLLIMPORT
942 | EXTERN_WEAK
943 ;
944
945FunctionProto
946 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000947 if (!$2->empty())
948 *$1 += " " + *$2;
949 *$1 += " " + *$3;
950 delete $2;
951 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000952 $$ = $1;
953 };
954
955//===----------------------------------------------------------------------===//
956// Rules to match Basic Blocks
957//===----------------------------------------------------------------------===//
958
Reid Spencerd154b572006-12-01 20:36:40 +0000959OptSideEffect : /* empty */ { $$ = new std::string(); }
960 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000961
Reid Spencere77e35e2006-12-01 20:26:20 +0000962ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000963 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
964 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +0000965 | '<' ConstVector '>' {
966 $2->insert(0, "<");
967 *$2 += ">";
968 $$ = $2;
969 }
970 | ConstExpr
971 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
972 if (!$2->empty()) {
973 *$1 += " " + *$2;
974 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000975 *$1 += " " + *$3 + ", " + *$5;
976 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +0000977 $$ = $1;
978 };
979
Reid Spencerf2d55322006-12-01 21:52:30 +0000980SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000981
982// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +0000983ValueRef
984 : SymbolicValueRef {
985 $$.val = $1;
986 $$.constant = false;
987 $$.type.newTy = 0;
988 $$.type.oldTy = UnresolvedTy;
989 }
990 | ConstValueRef {
991 $$.val = $1;
992 $$.constant = true;
993 $$.type.newTy = 0;
994 $$.type.oldTy = UnresolvedTy;
995 }
996 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000997
998// ResolvedVal - a <type> <value> pair. This is used only in cases where the
999// type immediately preceeds the value reference, and allows complex constant
1000// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1001ResolvedVal : Types ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001002 $$ = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +00001003 $$.type = $1;
Reid Spencerf459d392006-12-02 16:19:52 +00001004 $$.val->insert(0, *$1.newTy + " ");
Reid Spencere7c3c602006-11-30 06:36:44 +00001005 };
1006
1007BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001008 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001009 }
1010 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001011 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001012 };
1013
1014
1015// Basic blocks are terminated by branching instructions:
1016// br, br/cc, switch, ret
1017//
Reid Spencer16244f42006-12-01 21:10:07 +00001018BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001019 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001020 };
1021
1022InstructionList : InstructionList Inst {
1023 *O << " " << *$2 << "\n";
1024 delete $2;
1025 $$ = 0;
1026 }
1027 | /* empty */ {
1028 $$ = 0;
1029 }
1030 | LABELSTR {
1031 *O << *$1 << "\n";
1032 delete $1;
1033 $$ = 0;
1034 };
1035
Reid Spencer78720742006-12-02 20:21:22 +00001036Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1037
Reid Spencere7c3c602006-11-30 06:36:44 +00001038BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencere77e35e2006-12-01 20:26:20 +00001039 *O << " " << *$1 << " " << *$2.val << "\n";
1040 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001041 $$ = 0;
1042 }
1043 | RET VOID { // Return with no result...
Reid Spencere77e35e2006-12-01 20:26:20 +00001044 *O << " " << *$1 << " " << *$2.newTy << "\n";
1045 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001046 $$ = 0;
1047 }
1048 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencerf459d392006-12-02 16:19:52 +00001049 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << "\n";
1050 delete $1; $2.destroy(); $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001051 $$ = 0;
1052 } // Conditional Branch...
1053 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001054 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1055 << *$5.newTy << " " << *$6.val << ", " << *$8.newTy << " "
1056 << *$9.val << "\n";
1057 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1058 $8.destroy(); $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001059 $$ = 0;
1060 }
1061 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001062 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1063 << *$5.newTy << " " << *$6.val << " [" << *$8 << " ]\n";
1064 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1065 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001066 $$ = 0;
1067 }
1068 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001069 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1070 << *$5.newTy << " " << *$6.val << "[]\n";
1071 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001072 $$ = 0;
1073 }
Reid Spencer16244f42006-12-01 21:10:07 +00001074 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001075 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001076 *O << " ";
1077 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +00001078 *O << *$1 << " = ";
Reid Spencerf459d392006-12-02 16:19:52 +00001079 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001080 for (unsigned i = 0; i < $7->size(); ++i) {
1081 ValueInfo& VI = (*$7)[i];
1082 *O << *VI.val;
1083 if (i+1 < $7->size())
1084 *O << ", ";
1085 VI.destroy();
1086 }
Reid Spencerf459d392006-12-02 16:19:52 +00001087 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11.val << " "
1088 << *$12 << " " << *$13.newTy << " " << *$14.val << "\n";
1089 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1090 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1091 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001092 $$ = 0;
1093 }
Reid Spencer78720742006-12-02 20:21:22 +00001094 | Unwind {
Reid Spencere7c3c602006-11-30 06:36:44 +00001095 *O << " " << *$1 << "\n";
1096 delete $1;
1097 $$ = 0;
1098 }
1099 | UNREACHABLE {
1100 *O << " " << *$1 << "\n";
1101 delete $1;
1102 $$ = 0;
1103 };
1104
1105JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001106 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1107 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001108 $$ = $1;
1109 }
1110 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001111 $2->insert(0, *$1.newTy + " " );
Reid Spencerf459d392006-12-02 16:19:52 +00001112 *$2 += ", " + *$4.newTy + " " + *$5.val;
1113 $1.destroy(); $4.destroy(); $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001114 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001115 };
1116
1117Inst
1118 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001119 if (!$1->empty())
1120 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001121 *$1 += *$2;
1122 delete $2;
1123 $$ = $1;
1124 };
1125
1126PHIList
1127 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencerf459d392006-12-02 16:19:52 +00001128 $3.val->insert(0, *$1.newTy + "[");
1129 *$3.val += "," + *$5.val + "]";
1130 $1.destroy(); $5.destroy();
1131 $$ = new std::string(*$3.val);
1132 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001133 }
1134 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001135 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1136 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001137 $$ = $1;
1138 };
1139
1140
1141ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001142 : ResolvedVal {
1143 $$ = new ValueList();
1144 $$->push_back($1);
1145 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001146 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001147 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001148 $$ = $1;
1149 };
1150
1151// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1152ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001153 : ValueRefList { $$ = $1; }
1154 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001155 ;
1156
1157OptTailCall
1158 : TAIL CALL {
1159 *$1 += " " + *$2;
1160 delete $2;
1161 $$ = $1;
1162 }
1163 | CALL
1164 ;
1165
1166InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001167 const char* op = getDivRemOpcode(*$1, $2);
1168 $$ = new std::string(op);
1169 *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1170 delete $1; $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001171 }
1172 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001173 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1174 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001175 $$ = $1;
1176 }
1177 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer229e9362006-12-02 22:14:11 +00001178#if UPGRADE_SETCOND_OPS
1179 *$1 = getCompareOp(*$1, $2);
1180#endif
Reid Spencerf459d392006-12-02 16:19:52 +00001181 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1182 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001183 $$ = $1;
1184 }
Reid Spencer229e9362006-12-02 22:14:11 +00001185 | CompareOps Predicates Types ValueRef ',' ValueRef ')' {
1186 *$1 += " " + *$2 + " " + *$4.val + "," + *$6.val + ")";
1187 delete $2; $4.destroy(); $6.destroy();
1188 $$ = $1;
1189 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001190 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001191 *$1 += " " + *$2.val;
1192 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001193 $$ = $1;
1194 }
1195 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001196 const char* shiftop = $1->c_str();
1197 if (*$1 == "shr")
1198 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1199 $$ = new std::string(shiftop);
1200 *$$ += " " + *$2.val + ", " + *$4.val;
1201 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001202 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001203 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001204 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001205 TypeInfo SrcTy = $2.type;
1206 TypeInfo DstTy = $4;
1207 ResolveType(DstTy);
1208 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001209 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001210 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1211 } else {
1212 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001213 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001214 delete $1; $2.destroy();
1215 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001216 }
1217 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001218 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1219 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001220 $$ = $1;
1221 }
1222 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001223 *$1 += " " + *$2.val + ", " + *$4.newTy;
1224 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001225 $$ = $1;
1226 }
1227 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001228 *$1 += " " + *$2.val + ", " + *$4.val;
1229 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001230 $$ = $1;
1231 }
1232 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001233 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1234 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001235 $$ = $1;
1236 }
1237 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001238 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1239 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001240 $$ = $1;
1241 }
1242 | PHI_TOK PHIList {
1243 *$1 += " " + *$2;
1244 delete $2;
1245 $$ = $1;
1246 }
1247 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1248 if (!$2->empty())
1249 *$1 += " " + *$2;
1250 if (!$1->empty())
1251 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001252 *$1 += *$3.newTy + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001253 for (unsigned i = 0; i < $6->size(); ++i) {
1254 ValueInfo& VI = (*$6)[i];
1255 *$1 += *VI.val;
1256 if (i+1 < $6->size())
1257 *$1 += ", ";
1258 VI.destroy();
1259 }
1260 *$1 += ")";
Reid Spencerf459d392006-12-02 16:19:52 +00001261 delete $2; $3.destroy(); $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001262 $$ = $1;
1263 }
1264 | MemoryInst ;
1265
1266
1267// IndexList - List of indices for GEP based instructions...
1268IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001269 : ',' ValueRefList { $$ = $2; }
1270 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001271 ;
1272
1273OptVolatile
1274 : VOLATILE
1275 | /* empty */ { $$ = new std::string(); }
1276 ;
1277
1278MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001279 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001280 if (!$3->empty())
1281 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001282 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001283 $$ = $1;
1284 }
1285 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001286 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001287 if (!$6->empty())
1288 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001289 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001290 $$ = $1;
1291 }
1292 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001293 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001294 if (!$3->empty())
1295 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001296 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001297 $$ = $1;
1298 }
1299 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001300 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001301 if (!$6->empty())
1302 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001303 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001304 $$ = $1;
1305 }
1306 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001307 *$1 += " " + *$2.val;
1308 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001309 $$ = $1;
1310 }
1311 | OptVolatile LOAD Types ValueRef {
1312 if (!$1->empty())
1313 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001314 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1315 delete $2; $3.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001316 $$ = $1;
1317 }
1318 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1319 if (!$1->empty())
1320 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001321 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1322 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001323 $$ = $1;
1324 }
1325 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf459d392006-12-02 16:19:52 +00001326 // Upgrade the indices
1327 for (unsigned i = 0; i < $4->size(); ++i) {
1328 ValueInfo& VI = (*$4)[i];
1329 if (VI.type.isUnsigned() && !VI.isConstant() &&
1330 VI.type.getBitWidth() < 64) {
1331 std::string* old = VI.val;
1332 *O << " %gep_upgrade" << unique << " = zext " << *old
1333 << " to ulong\n";
1334 VI.val = new std::string("ulong %gep_upgrade" + llvm::utostr(unique++));
1335 VI.type.oldTy = ULongTy;
1336 delete old;
1337 }
1338 }
1339 *$1 += " " + *$2.newTy + " " + *$3.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001340 for (unsigned i = 0; i < $4->size(); ++i) {
1341 ValueInfo& VI = (*$4)[i];
1342 *$1 += ", " + *VI.val;
1343 VI.destroy();
1344 }
Reid Spencerf459d392006-12-02 16:19:52 +00001345 $2.destroy(); $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001346 $$ = $1;
1347 };
1348
1349%%
1350
1351int yyerror(const char *ErrorMsg) {
1352 std::string where
1353 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1354 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1355 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1356 if (yychar == YYEMPTY || yychar == 0)
1357 errMsg += "end-of-file.";
1358 else
1359 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1360 std::cerr << errMsg << '\n';
1361 exit(1);
1362}