blob: 761bda1cdfc89c0cedf947de78e7b48456b986fa [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>
Reid Spencerbec0b592006-12-03 03:16:48 +000021#include <cassert>
Reid Spencere7c3c602006-11-30 06:36:44 +000022
Reid Spencere77e35e2006-12-01 20:26:20 +000023#define YYERROR_VERBOSE 1
Reid Spencer96839be2006-11-30 16:50:26 +000024#define YYINCLUDED_STDLIB_H
Reid Spencere77e35e2006-12-01 20:26:20 +000025#define YYDEBUG 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 Spencer71d2ec92006-12-31 06:02:26 +000037// This bool controls whether attributes are ever added to function declarations
38// definitions and calls.
39static bool AddAttributes = false;
40
Reid Spencerf5626a32007-01-01 01:20:41 +000041// This bool is used to communicate between the InstVal and Inst rules about
42// whether or not a cast should be deleted. When the flag is set, InstVal has
43// determined that the cast is a candidate. However, it can only be deleted if
44// the value being casted is the same value name as the instruction. The Inst
45// rule makes that comparison if the flag is set and comments out the
46// instruction if they match.
47static bool deleteUselessCastFlag = false;
48static std::string* deleteUselessCastName = 0;
49
Reid Spencera50d5962006-12-02 04:11:07 +000050typedef std::vector<TypeInfo> TypeVector;
51static TypeVector EnumeratedTypes;
52typedef std::map<std::string,TypeInfo> TypeMap;
53static TypeMap NamedTypes;
Reid Spencerf12ee422006-12-05 19:21:25 +000054static TypeMap Globals;
Reid Spencera50d5962006-12-02 04:11:07 +000055
Reid Spencerf8483652006-12-02 15:16:01 +000056void destroy(ValueList* VL) {
57 while (!VL->empty()) {
58 ValueInfo& VI = VL->back();
59 VI.destroy();
60 VL->pop_back();
61 }
62 delete VL;
63}
64
Reid Spencer96839be2006-11-30 16:50:26 +000065void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencer71d2ec92006-12-31 06:02:26 +000066 std::ostream &out, bool debug, bool addAttrs)
Reid Spencere7c3c602006-11-30 06:36:44 +000067{
68 Upgradelineno = 1;
69 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000070 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000071 yydebug = debug;
Reid Spencer71d2ec92006-12-31 06:02:26 +000072 AddAttributes = addAttrs;
Reid Spencere7c3c602006-11-30 06:36:44 +000073 O = &out;
74
75 if (yyparse()) {
76 std::cerr << "Parse failed.\n";
77 exit(1);
78 }
79}
80
Reid Spencera50d5962006-12-02 04:11:07 +000081static void ResolveType(TypeInfo& Ty) {
82 if (Ty.oldTy == UnresolvedTy) {
83 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
Reid Spencer78720742006-12-02 20:21:22 +000084 if (I != NamedTypes.end()) {
Reid Spencera50d5962006-12-02 04:11:07 +000085 Ty.oldTy = I->second.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000086 Ty.elemTy = I->second.elemTy;
87 } else {
Reid Spencera50d5962006-12-02 04:11:07 +000088 std::string msg("Can't resolve type: ");
89 msg += *Ty.newTy;
90 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000091 }
Reid Spencera50d5962006-12-02 04:11:07 +000092 } else if (Ty.oldTy == NumericTy) {
93 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
94 if (ref < EnumeratedTypes.size()) {
95 Ty.oldTy = EnumeratedTypes[ref].oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000096 Ty.elemTy = EnumeratedTypes[ref].elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +000097 } else {
98 std::string msg("Can't resolve type: ");
99 msg += *Ty.newTy;
100 yyerror(msg.c_str());
101 }
Reid Spencer280d8012006-12-01 23:40:53 +0000102 }
Reid Spencera50d5962006-12-02 04:11:07 +0000103 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +0000104}
105
Reid Spencera50d5962006-12-02 04:11:07 +0000106static const char* getCastOpcode(
107 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
108{
Reid Spencere77e35e2006-12-01 20:26:20 +0000109 unsigned SrcBits = SrcTy.getBitWidth();
110 unsigned DstBits = DstTy.getBitWidth();
111 const char* opcode = "bitcast";
112 // Run through the possibilities ...
113 if (DstTy.isIntegral()) { // Casting to integral
114 if (SrcTy.isIntegral()) { // Casting from integral
115 if (DstBits < SrcBits)
116 opcode = "trunc";
117 else if (DstBits > SrcBits) { // its an extension
118 if (SrcTy.isSigned())
119 opcode ="sext"; // signed -> SEXT
120 else
121 opcode = "zext"; // unsigned -> ZEXT
122 } else {
123 opcode = "bitcast"; // Same size, No-op cast
124 }
125 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
126 if (DstTy.isSigned())
127 opcode = "fptosi"; // FP -> sint
128 else
129 opcode = "fptoui"; // FP -> uint
130 } else if (SrcTy.isPacked()) {
131 assert(DstBits == SrcTy.getBitWidth() &&
132 "Casting packed to integer of different width");
133 opcode = "bitcast"; // same size, no-op cast
134 } else {
135 assert(SrcTy.isPointer() &&
136 "Casting from a value that is not first-class type");
137 opcode = "ptrtoint"; // ptr -> int
138 }
139 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
140 if (SrcTy.isIntegral()) { // Casting from integral
141 if (SrcTy.isSigned())
142 opcode = "sitofp"; // sint -> FP
143 else
144 opcode = "uitofp"; // uint -> FP
145 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
146 if (DstBits < SrcBits) {
147 opcode = "fptrunc"; // FP -> smaller FP
148 } else if (DstBits > SrcBits) {
149 opcode = "fpext"; // FP -> larger FP
150 } else {
151 opcode ="bitcast"; // same size, no-op cast
152 }
153 } else if (SrcTy.isPacked()) {
154 assert(DstBits == SrcTy.getBitWidth() &&
155 "Casting packed to floating point of different width");
156 opcode = "bitcast"; // same size, no-op cast
157 } else {
158 assert(0 && "Casting pointer or non-first class to float");
159 }
160 } else if (DstTy.isPacked()) {
161 if (SrcTy.isPacked()) {
162 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
163 "Casting packed to packed of different widths");
164 opcode = "bitcast"; // packed -> packed
165 } else if (DstTy.getBitWidth() == SrcBits) {
166 opcode = "bitcast"; // float/int -> packed
167 } else {
168 assert(!"Illegal cast to packed (wrong type or size)");
169 }
170 } else if (DstTy.isPointer()) {
171 if (SrcTy.isPointer()) {
172 opcode = "bitcast"; // ptr -> ptr
173 } else if (SrcTy.isIntegral()) {
174 opcode = "inttoptr"; // int -> ptr
175 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000176 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000177 }
178 } else {
179 assert(!"Casting to type that is not first-class");
180 }
181 return opcode;
182}
183
Reid Spencera50d5962006-12-02 04:11:07 +0000184static std::string getCastUpgrade(
185 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
186{
187 std::string Result;
188 std::string Source = Src;
189 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
190 // fp -> ptr cast is no longer supported but we must upgrade this
191 // by doing a double cast: fp -> int -> ptr
192 if (isConst)
Reid Spencer71d2ec92006-12-31 06:02:26 +0000193 Source = "i64 fptoui(" + Source + " to i64)";
Reid Spencera50d5962006-12-02 04:11:07 +0000194 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000195 *O << " %cast_upgrade" << unique << " = fptoui " << Source
Reid Spencer71d2ec92006-12-31 06:02:26 +0000196 << " to i64\n";
197 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000198 }
199 // Update the SrcTy for the getCastOpcode call below
200 SrcTy.destroy();
Reid Spencer71d2ec92006-12-31 06:02:26 +0000201 SrcTy.newTy = new std::string("i64");
Reid Spencera50d5962006-12-02 04:11:07 +0000202 SrcTy.oldTy = ULongTy;
Reid Spencer5fe27e72006-12-09 19:41:25 +0000203 } else if (DstTy.oldTy == BoolTy && SrcTy.oldTy != BoolTy) {
Reid Spencera50d5962006-12-02 04:11:07 +0000204 // cast ptr %x to bool was previously defined as setne ptr %x, null
205 // The ptrtoint semantic is to truncate, not compare so we must retain
206 // the original intent by replace the cast with a setne
207 const char* comparator = SrcTy.isPointer() ? ", null" :
208 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
Reid Spencere4d87aa2006-12-23 06:05:41 +0000209 const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne ";
Reid Spencer187ccf82006-12-09 16:57:22 +0000210 if (isConst) {
211 Result = "(" + Source + comparator + ")";
212 Result = compareOp + Result;
213 } else
214 Result = compareOp + Source + comparator;
Reid Spencera50d5962006-12-02 04:11:07 +0000215 return Result; // skip cast processing below
216 }
217 ResolveType(SrcTy);
218 ResolveType(DstTy);
219 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
220 if (isConst)
221 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
222 else
223 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
224 return Result;
225}
226
Reid Spencer78720742006-12-02 20:21:22 +0000227const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
228 const char* op = opcode.c_str();
229 TypeInfo Ty = TI;
230 ResolveType(Ty);
231 if (Ty.isPacked())
232 Ty.oldTy = Ty.getElementType();
233 if (opcode == "div")
234 if (Ty.isFloatingPoint())
235 op = "fdiv";
236 else if (Ty.isUnsigned())
237 op = "udiv";
238 else if (Ty.isSigned())
239 op = "sdiv";
240 else
241 yyerror("Invalid type for div instruction");
242 else if (opcode == "rem")
243 if (Ty.isFloatingPoint())
244 op = "frem";
245 else if (Ty.isUnsigned())
246 op = "urem";
247 else if (Ty.isSigned())
248 op = "srem";
249 else
250 yyerror("Invalid type for rem instruction");
251 return op;
252}
Reid Spencer229e9362006-12-02 22:14:11 +0000253
254std::string
255getCompareOp(const std::string& setcc, const TypeInfo& TI) {
256 assert(setcc.length() == 5);
257 char cc1 = setcc[3];
258 char cc2 = setcc[4];
259 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
260 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
261 std::string result("xcmp xxx");
262 result[6] = cc1;
263 result[7] = cc2;
264 if (TI.isFloatingPoint()) {
265 result[0] = 'f';
Reid Spencere4d87aa2006-12-23 06:05:41 +0000266 result[5] = 'o';
Reid Spencerf0cf1322006-12-07 04:23:03 +0000267 if (cc1 == 'n')
268 result[5] = 'u'; // NE maps to unordered
269 else
270 result[5] = 'o'; // everything else maps to ordered
Reid Spencer229e9362006-12-02 22:14:11 +0000271 } else if (TI.isIntegral() || TI.isPointer()) {
272 result[0] = 'i';
273 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
274 result.erase(5,1);
275 else if (TI.isSigned())
276 result[5] = 's';
Reid Spencer3e5ab8c2006-12-06 06:25:46 +0000277 else if (TI.isUnsigned() || TI.isPointer() || TI.isBool())
Reid Spencer229e9362006-12-02 22:14:11 +0000278 result[5] = 'u';
279 else
280 yyerror("Invalid integral type for setcc");
281 }
282 return result;
283}
284
Reid Spencere7c3c602006-11-30 06:36:44 +0000285%}
286
Reid Spencerf0cf1322006-12-07 04:23:03 +0000287// %file-prefix="UpgradeParser"
Reid Spencere77e35e2006-12-01 20:26:20 +0000288
289%union {
290 std::string* String;
291 TypeInfo Type;
292 ValueInfo Value;
293 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000294 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000295}
296
Reid Spencerf2d55322006-12-01 21:52:30 +0000297%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000298%token <Type> FLOAT DOUBLE LABEL
299%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000300%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000301%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
302%token <String> IMPLEMENTATION BEGINTOK ENDTOK
Reid Spencer71d2ec92006-12-31 06:02:26 +0000303%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
Reid Spencere77e35e2006-12-01 20:26:20 +0000304%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
305%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
306%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000307%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000308%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
309%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
310%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
311%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000312%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
313%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000314%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000315%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
316%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000317%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000318%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000319%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000320%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
321%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000322
323%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
324%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
325%type <String> ArgTypeListI ConstExpr DefinitionList
326%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
327%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
328%type <String> Function FunctionProto BasicBlock TypeListI
329%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
Reid Spencer78720742006-12-02 20:21:22 +0000330%type <String> OptTailCall InstVal OptVolatile Unwind
Reid Spencere77e35e2006-12-01 20:26:20 +0000331%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
332%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000333%type <String> Name ConstValueRef ConstVector External
Reid Spencer57f28f92006-12-03 07:10:26 +0000334%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
335%type <String> IPredicates FPredicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000336
Reid Spencerf8483652006-12-02 15:16:01 +0000337%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000338
339%type <Type> IntType SIntType UIntType FPType TypesV Types
340%type <Type> PrimType UpRTypesV UpRTypes
341
Reid Spencerf2d55322006-12-01 21:52:30 +0000342%type <String> IntVal EInt64Val
343%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000344
Reid Spencerf459d392006-12-02 16:19:52 +0000345%type <Value> ValueRef ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000346
347%start Module
348
349%%
350
351// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000352IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000353EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000354
355// Operations that are notably excluded from this list include:
356// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000357ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
358 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000359LogicalOps : AND | OR | XOR;
360SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer57f28f92006-12-03 07:10:26 +0000361IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
362FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
363 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
Reid Spencerf7bde222006-12-01 22:26:37 +0000364ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000365CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
366 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
367 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000368
369// These are some types that allow classification if we only want a particular
370// thing... for example, only a signed, unsigned, or integral type.
371SIntType : LONG | INT | SHORT | SBYTE;
372UIntType : ULONG | UINT | USHORT | UBYTE;
373IntType : SIntType | UIntType;
374FPType : FLOAT | DOUBLE;
375
376// OptAssign - Value producing statements have an optional assignment component
377OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000378 $$ = $1;
379 }
380 | /*empty*/ {
381 $$ = new std::string("");
382 };
383
384OptLinkage
385 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
386 | EXTERN_WEAK
387 | /*empty*/ { $$ = new std::string(""); } ;
388
389OptCallingConv
390 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000391 | X86_FASTCALLCC_TOK
392 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000393 *$1 += *$2;
394 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000395 $$ = $1;
396 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000397 | /*empty*/ { $$ = new std::string(""); } ;
398
399// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
400// a comma before it.
401OptAlign
402 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000403 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencerf0cf1322006-12-07 04:23:03 +0000404
Reid Spencere7c3c602006-11-30 06:36:44 +0000405OptCAlign
406 : /*empty*/ { $$ = new std::string(); }
407 | ',' ALIGN EUINT64VAL {
408 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000409 *$2 += " " + *$3;
410 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000411 $$ = $2;
412 };
413
414SectionString
415 : SECTION STRINGCONSTANT {
416 *$1 += " " + *$2;
417 delete $2;
418 $$ = $1;
419 };
420
421OptSection : /*empty*/ { $$ = new std::string(); }
422 | SectionString;
423
424GlobalVarAttributes
425 : /* empty */ { $$ = new std::string(); }
426 | ',' GlobalVarAttribute GlobalVarAttributes {
427 $2->insert(0, ", ");
428 if (!$3->empty())
429 *$2 += " " + *$3;
430 delete $3;
431 $$ = $2;
432 };
433
434GlobalVarAttribute
435 : SectionString
436 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000437 *$1 += " " + *$2;
438 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000439 $$ = $1;
440 };
441
442//===----------------------------------------------------------------------===//
443// Types includes all predefined types... except void, because it can only be
444// used in specific contexts (function returning void for example). To have
445// access to it, a user must explicitly use TypesV.
446//
447
448// TypesV includes all of 'Types', but it also includes the void type.
449TypesV : Types | VOID ;
450UpRTypesV : UpRTypes | VOID ;
451Types : UpRTypes ;
452
453// Derived types are added later...
454//
455PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000456PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000457UpRTypes
458 : OPAQUE {
459 $$.newTy = $1;
460 $$.oldTy = OpaqueTy;
461 }
462 | SymbolicValueRef {
463 $$.newTy = $1;
464 $$.oldTy = UnresolvedTy;
465 }
Reid Spencer78720742006-12-02 20:21:22 +0000466 | PrimType {
467 $$ = $1;
468 }
469 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000470 $2->insert(0, "\\");
471 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000472 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000473 }
474 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000475 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000476 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000477 $$.newTy = $1.newTy;
478 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000479 }
480 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000481 $2->insert(0,"[ ");
482 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000483 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000484 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000485 $$.oldTy = ArrayTy;
Reid Spencer78720742006-12-02 20:21:22 +0000486 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000487 }
488 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000489 $2->insert(0,"< ");
490 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000491 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000492 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000493 $$.oldTy = PackedTy;
Reid Spencer78720742006-12-02 20:21:22 +0000494 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000495 }
496 | '{' TypeListI '}' { // Structure type?
497 $2->insert(0, "{ ");
498 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000499 $$.newTy = $2;
500 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000501 }
502 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000503 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000504 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000505 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000506 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
507 $3->insert(0, "<{ ");
508 *$3 += " }>";
509 $$.newTy = $3;
510 $$.oldTy = StructTy;
511 }
512 | '<' '{' '}' '>' { // Empty packed structure type?
513 $$.newTy = new std::string("<{}>");
514 $$.oldTy = StructTy;
515 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000516 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000517 *$1.newTy += '*';
Reid Spencer78720742006-12-02 20:21:22 +0000518 $$.elemTy = $1.oldTy;
Reid Spencere77e35e2006-12-01 20:26:20 +0000519 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000520 $$ = $1;
521 };
522
523// TypeList - Used for struct declarations and as a basis for function type
524// declaration type lists
525//
Reid Spencere77e35e2006-12-01 20:26:20 +0000526TypeListI
527 : UpRTypes {
528 $$ = $1.newTy;
529 }
530 | TypeListI ',' UpRTypes {
531 *$1 += ", " + *$3.newTy;
532 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000533 $$ = $1;
534 };
535
536// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000537ArgTypeListI
538 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000539 | TypeListI ',' DOTDOTDOT {
540 *$1 += ", ...";
541 delete $3;
542 $$ = $1;
543 }
544 | DOTDOTDOT {
545 $$ = $1;
546 }
547 | /*empty*/ {
548 $$ = new std::string();
549 };
550
551// ConstVal - The various declarations that go into the constant pool. This
552// production is used ONLY to represent constants that show up AFTER a 'const',
553// 'constant' or 'global' token at global scope. Constants that can be inlined
554// into other expressions (such as integers and constexprs) are handled by the
555// ResolvedVal, ValueRef and ConstValueRef productions.
556//
557ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000558 $$.type = $1;
559 $$.cnst = new std::string(*$1.newTy);
560 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000561 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000562 }
563 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000564 $$.type = $1;
565 $$.cnst = new std::string(*$1.newTy);
566 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000567 }
568 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000569 $$.type = $1;
570 $$.cnst = new std::string(*$1.newTy);
571 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000572 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000573 }
574 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000575 $$.type = $1;
576 $$.cnst = new std::string(*$1.newTy);
577 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000578 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000579 }
580 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000581 $$.type = $1;
582 $$.cnst = new std::string(*$1.newTy);
583 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000584 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000585 }
586 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000587 $$.type = $1;
588 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000589 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000590 }
591 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000592 $$.type = $1;
593 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000594 *$$.cnst += " " + *$2;
595 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000596 }
597 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000598 $$.type = $1;
599 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000600 *$$.cnst += " " + *$2;
601 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000602 }
603 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000604 $$.type = $1;
605 $$.cnst = new std::string(*$1.newTy);
606 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000607 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000608 }
609 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000610 $$.type = $1;
611 $$.cnst = new std::string(*$1.newTy);
612 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000613 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000614 }
615 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000616 $$.type = $1;
617 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000618 *$$.cnst += " " + *$2;
619 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000620 }
621 | SIntType EInt64Val { // integral constants
622 $$.type = $1;
623 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000624 *$$.cnst += " " + *$2;
625 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000626 }
627 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000628 $$.type = $1;
629 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000630 *$$.cnst += " " + *$2;
631 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000632 }
633 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000634 $$.type = $1;
635 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000636 *$$.cnst += " " + *$2;
637 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000638 }
639 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000640 $$.type = $1;
641 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000642 *$$.cnst += " " + *$2;
643 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000644 }
645 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000646 $$.type = $1;
647 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000648 *$$.cnst += " " + *$2;
649 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000650 };
651
652
Reid Spencerfcb5df82006-12-01 22:34:43 +0000653ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000654 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000655 TypeInfo DstTy = $5;
656 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000657 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000658 // Call getCastUpgrade to upgrade the old cast
659 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
660 } else {
661 // Nothing to upgrade, just create the cast constant expr
662 $$ = new std::string(*$1);
663 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000664 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000665 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000666 }
667 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000668 *$1 += "(" + *$3.cnst;
669 for (unsigned i = 0; i < $4->size(); ++i) {
670 ValueInfo& VI = (*$4)[i];
671 *$1 += ", " + *VI.val;
672 VI.destroy();
673 }
674 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000675 $$ = $1;
676 $3.destroy();
677 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000678 }
679 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000680 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
681 $3.destroy(); $5.destroy(); $7.destroy();
682 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000683 }
684 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000685 const char* op = getDivRemOpcode(*$1, $3.type);
686 $$ = new std::string(op);
687 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
688 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000689 }
690 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000691 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
692 $3.destroy(); $5.destroy();
693 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000694 }
695 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000696 *$1 = getCompareOp(*$1, $3.type);
Reid Spencere77e35e2006-12-01 20:26:20 +0000697 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
698 $3.destroy(); $5.destroy();
699 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000700 }
Reid Spencer57f28f92006-12-03 07:10:26 +0000701 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
702 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
703 delete $2; $4.destroy(); $6.destroy();
704 $$ = $1;
705 }
706 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000707 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
708 delete $2; $4.destroy(); $6.destroy();
709 $$ = $1;
710 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000711 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000712 const char* shiftop = $1->c_str();
713 if (*$1 == "shr")
714 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
715 $$ = new std::string(shiftop);
716 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
717 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000718 }
719 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000720 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
721 $3.destroy(); $5.destroy();
722 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000723 }
724 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000725 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
726 $3.destroy(); $5.destroy(); $7.destroy();
727 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000728 }
729 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000730 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
731 $3.destroy(); $5.destroy(); $7.destroy();
732 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000733 };
734
735
736// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000737
738ConstVector
739 : ConstVector ',' ConstVal {
740 *$1 += ", " + *$3.cnst;
741 $3.destroy();
742 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000743 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000744 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
745 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000746
747
748// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000749GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000750
751
752//===----------------------------------------------------------------------===//
753// Rules to match Modules
754//===----------------------------------------------------------------------===//
755
756// Module rule: Capture the result of parsing the whole file into a result
757// variable...
758//
759Module : DefinitionList {
760};
761
762// DefinitionList - Top level definitions
763//
764DefinitionList : DefinitionList Function {
765 $$ = 0;
766 }
767 | DefinitionList FunctionProto {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000768 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000769 delete $2;
770 $$ = 0;
771 }
772 | DefinitionList MODULE ASM_TOK AsmBlock {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000773 *O << "module asm " << ' ' << *$4 << '\n';
Reid Spencerd154b572006-12-01 20:36:40 +0000774 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000775 }
776 | DefinitionList IMPLEMENTATION {
777 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000778 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000779 }
Reid Spencera50d5962006-12-02 04:11:07 +0000780 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000781
Reid Spencer78720742006-12-02 20:21:22 +0000782External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
783
Reid Spencere7c3c602006-11-30 06:36:44 +0000784// ConstPool - Constants with optional names assigned to them.
785ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000786 EnumeratedTypes.push_back($4);
787 if (!$2->empty()) {
788 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
789 NamedTypes[*$2].oldTy = $4.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +0000790 NamedTypes[*$2].elemTy = $4.elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +0000791 *O << *$2 << " = ";
792 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000793 *O << "type " << *$4.newTy << '\n';
Reid Spencera50d5962006-12-02 04:11:07 +0000794 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000795 $$ = 0;
796 }
797 | ConstPool FunctionProto { // Function prototypes can be in const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000798 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000799 delete $2;
800 $$ = 0;
801 }
802 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000803 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000804 delete $2; delete $3; delete $4;
805 $$ = 0;
806 }
807 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000808 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000809 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000810 Globals[*$2] = $5.type.clone();
811 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000812 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000813 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000814 $$ = 0;
815 }
Reid Spencer78720742006-12-02 20:21:22 +0000816 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000817 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000818 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000819 Globals[*$2] = $5.clone();
820 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000821 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000822 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000823 $$ = 0;
824 }
825 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000826 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000827 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000828 Globals[*$2] = $5.clone();
829 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000830 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000831 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000832 $$ = 0;
833 }
834 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000835 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000836 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000837 Globals[*$2] = $5.clone();
838 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000839 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000840 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000841 $$ = 0;
842 }
843 | ConstPool TARGET TargetDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000844 *O << *$2 << ' ' << *$3 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000845 delete $2; delete $3;
846 $$ = 0;
847 }
848 | ConstPool DEPLIBS '=' LibrariesDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000849 *O << *$2 << " = " << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000850 delete $2; delete $4;
851 $$ = 0;
852 }
853 | /* empty: end of list */ {
854 $$ = 0;
855 };
856
857
858AsmBlock : STRINGCONSTANT ;
859
860BigOrLittle : BIG | LITTLE
861
862TargetDefinition
863 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000864 *$1 += " = " + *$3;
865 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000866 $$ = $1;
867 }
868 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000869 *$1 += " = " + *$3;
870 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000871 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000872 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000873 $$ = $1;
874 }
875 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000876 *$1 += " = " + *$3;
877 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000878 $$ = $1;
879 }
880 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000881 *$1 += " = " + *$3;
882 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000883 $$ = $1;
884 };
885
886LibrariesDefinition
887 : '[' LibList ']' {
888 $2->insert(0, "[ ");
889 *$2 += " ]";
890 $$ = $2;
891 };
892
893LibList
894 : LibList ',' STRINGCONSTANT {
895 *$1 += ", " + *$3;
896 delete $3;
897 $$ = $1;
898 }
899 | STRINGCONSTANT
900 | /* empty: end of list */ {
901 $$ = new std::string();
902 };
903
904//===----------------------------------------------------------------------===//
905// Rules to match Function Headers
906//===----------------------------------------------------------------------===//
907
908Name : VAR_ID | STRINGCONSTANT;
909OptName : Name | /*empty*/ { $$ = new std::string(); };
910
911ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000912 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000913 if (!$2->empty())
914 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000915 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000916};
917
918ArgListH : ArgListH ',' ArgVal {
919 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000920 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000921 }
922 | ArgVal {
923 $$ = $1;
924 };
925
926ArgList : ArgListH {
927 $$ = $1;
928 }
929 | ArgListH ',' DOTDOTDOT {
930 *$1 += ", ...";
931 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000932 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000933 }
934 | DOTDOTDOT {
935 $$ = $1;
936 }
Reid Spencerd154b572006-12-01 20:36:40 +0000937 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000938
Reid Spencer71d2ec92006-12-31 06:02:26 +0000939FunctionHeaderH
940 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
Reid Spencere7c3c602006-11-30 06:36:44 +0000941 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000942 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000943 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000944 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000945 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000946 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000947 }
948 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000949 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000950 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000951 $2.destroy();
952 delete $3;
953 delete $5;
954 delete $7;
955 delete $8;
956 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000957 };
958
Reid Spencer78720742006-12-02 20:21:22 +0000959BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
960 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000961
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000962FunctionHeader
963 : OptLinkage FunctionHeaderH BEGIN {
964 *O << "define ";
965 if (!$1->empty()) {
966 *O << *$1 << ' ';
967 }
968 *O << *$2 << ' ' << *$3 << '\n';
969 delete $1; delete $2; delete $3;
970 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000971 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000972 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000973
Reid Spencer78720742006-12-02 20:21:22 +0000974END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000975 | '}' { $$ = new std::string("}"); };
976
977Function : FunctionHeader BasicBlockList END {
978 if ($2)
979 *O << *$2;
Reid Spencer71d2ec92006-12-31 06:02:26 +0000980 *O << *$3 << "\n\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000981 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000982};
983
Reid Spencere77e35e2006-12-01 20:26:20 +0000984FnDeclareLinkage
985 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000986 | DLLIMPORT
987 | EXTERN_WEAK
988 ;
989
990FunctionProto
991 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000992 if (!$2->empty())
993 *$1 += " " + *$2;
994 *$1 += " " + *$3;
995 delete $2;
996 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000997 $$ = $1;
998 };
999
1000//===----------------------------------------------------------------------===//
1001// Rules to match Basic Blocks
1002//===----------------------------------------------------------------------===//
1003
Reid Spencerd154b572006-12-01 20:36:40 +00001004OptSideEffect : /* empty */ { $$ = new std::string(); }
1005 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +00001006
Reid Spencere77e35e2006-12-01 20:26:20 +00001007ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +00001008 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1009 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +00001010 | '<' ConstVector '>' {
1011 $2->insert(0, "<");
1012 *$2 += ">";
1013 $$ = $2;
1014 }
1015 | ConstExpr
1016 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1017 if (!$2->empty()) {
1018 *$1 += " " + *$2;
1019 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001020 *$1 += " " + *$3 + ", " + *$5;
1021 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001022 $$ = $1;
1023 };
1024
Reid Spencerf2d55322006-12-01 21:52:30 +00001025SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001026
1027// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +00001028ValueRef
1029 : SymbolicValueRef {
1030 $$.val = $1;
1031 $$.constant = false;
1032 $$.type.newTy = 0;
1033 $$.type.oldTy = UnresolvedTy;
1034 }
1035 | ConstValueRef {
1036 $$.val = $1;
1037 $$.constant = true;
1038 $$.type.newTy = 0;
1039 $$.type.oldTy = UnresolvedTy;
1040 }
1041 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001042
1043// ResolvedVal - a <type> <value> pair. This is used only in cases where the
1044// type immediately preceeds the value reference, and allows complex constant
1045// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1046ResolvedVal : Types ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001047 $$ = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +00001048 $$.type = $1;
Reid Spencerf459d392006-12-02 16:19:52 +00001049 $$.val->insert(0, *$1.newTy + " ");
Reid Spencere7c3c602006-11-30 06:36:44 +00001050 };
1051
1052BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001053 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001054 }
1055 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001056 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001057 };
1058
1059
1060// Basic blocks are terminated by branching instructions:
1061// br, br/cc, switch, ret
1062//
Reid Spencer16244f42006-12-01 21:10:07 +00001063BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001064 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001065 };
1066
1067InstructionList : InstructionList Inst {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001068 *O << " " << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001069 delete $2;
1070 $$ = 0;
1071 }
1072 | /* empty */ {
1073 $$ = 0;
1074 }
1075 | LABELSTR {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001076 *O << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001077 delete $1;
1078 $$ = 0;
1079 };
1080
Reid Spencer78720742006-12-02 20:21:22 +00001081Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1082
Reid Spencere7c3c602006-11-30 06:36:44 +00001083BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001084 *O << " " << *$1 << ' ' << *$2.val << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001085 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001086 $$ = 0;
1087 }
1088 | RET VOID { // Return with no result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001089 *O << " " << *$1 << ' ' << *$2.newTy << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001090 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001091 $$ = 0;
1092 }
1093 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001094 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001095 delete $1; $2.destroy(); $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001096 $$ = 0;
1097 } // Conditional Branch...
1098 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001099 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1100 << *$5.newTy << ' ' << *$6.val << ", " << *$8.newTy << ' '
1101 << *$9.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001102 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1103 $8.destroy(); $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001104 $$ = 0;
1105 }
1106 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001107 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1108 << *$5.newTy << ' ' << *$6.val << " [" << *$8 << " ]\n";
Reid Spencerf459d392006-12-02 16:19:52 +00001109 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1110 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001111 $$ = 0;
1112 }
1113 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001114 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1115 << *$5.newTy << ' ' << *$6.val << "[]\n";
Reid Spencerf459d392006-12-02 16:19:52 +00001116 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001117 $$ = 0;
1118 }
Reid Spencer16244f42006-12-01 21:10:07 +00001119 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001120 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001121 *O << " ";
1122 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +00001123 *O << *$1 << " = ";
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001124 *O << *$2 << ' ' << *$3 << ' ' << *$4.newTy << ' ' << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001125 for (unsigned i = 0; i < $7->size(); ++i) {
1126 ValueInfo& VI = (*$7)[i];
1127 *O << *VI.val;
1128 if (i+1 < $7->size())
1129 *O << ", ";
1130 VI.destroy();
1131 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001132 *O << ") " << *$9 << ' ' << *$10.newTy << ' ' << *$11.val << ' '
1133 << *$12 << ' ' << *$13.newTy << ' ' << *$14.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001134 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1135 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1136 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001137 $$ = 0;
1138 }
Reid Spencer78720742006-12-02 20:21:22 +00001139 | Unwind {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001140 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001141 delete $1;
1142 $$ = 0;
1143 }
1144 | UNREACHABLE {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001145 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001146 delete $1;
1147 $$ = 0;
1148 };
1149
1150JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001151 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1152 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001153 $$ = $1;
1154 }
1155 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001156 $2->insert(0, *$1.newTy + " " );
Reid Spencerf459d392006-12-02 16:19:52 +00001157 *$2 += ", " + *$4.newTy + " " + *$5.val;
1158 $1.destroy(); $4.destroy(); $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001159 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001160 };
1161
1162Inst
1163 : OptAssign InstVal {
Reid Spencerf5626a32007-01-01 01:20:41 +00001164 if (!$1->empty()) {
1165 if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
1166 *$1 += " = ";
1167 $1->insert(0, "; "); // don't actually delete it, just comment it out
1168 delete deleteUselessCastName;
1169 } else {
1170 *$1 += " = ";
1171 }
1172 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001173 *$1 += *$2;
1174 delete $2;
Reid Spencerf5626a32007-01-01 01:20:41 +00001175 deleteUselessCastFlag = false;
Reid Spencere7c3c602006-11-30 06:36:44 +00001176 $$ = $1;
1177 };
1178
1179PHIList
1180 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencerf459d392006-12-02 16:19:52 +00001181 $3.val->insert(0, *$1.newTy + "[");
1182 *$3.val += "," + *$5.val + "]";
1183 $1.destroy(); $5.destroy();
1184 $$ = new std::string(*$3.val);
1185 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001186 }
1187 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001188 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1189 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001190 $$ = $1;
1191 };
1192
1193
1194ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001195 : ResolvedVal {
1196 $$ = new ValueList();
1197 $$->push_back($1);
1198 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001199 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001200 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001201 $$ = $1;
1202 };
1203
1204// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1205ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001206 : ValueRefList { $$ = $1; }
1207 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001208 ;
1209
1210OptTailCall
1211 : TAIL CALL {
1212 *$1 += " " + *$2;
1213 delete $2;
1214 $$ = $1;
1215 }
1216 | CALL
1217 ;
1218
1219InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001220 const char* op = getDivRemOpcode(*$1, $2);
1221 $$ = new std::string(op);
1222 *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1223 delete $1; $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001224 }
1225 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001226 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1227 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001228 $$ = $1;
1229 }
1230 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer229e9362006-12-02 22:14:11 +00001231 *$1 = getCompareOp(*$1, $2);
Reid Spencerf459d392006-12-02 16:19:52 +00001232 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1233 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001234 $$ = $1;
1235 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001236 | ICMP IPredicates Types ValueRef ',' ValueRef {
1237 *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
Reid Spencer57f28f92006-12-03 07:10:26 +00001238 delete $2; $4.destroy(); $6.destroy();
1239 $$ = $1;
1240 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001241 | FCMP FPredicates Types ValueRef ',' ValueRef {
1242 *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
Reid Spencer229e9362006-12-02 22:14:11 +00001243 delete $2; $4.destroy(); $6.destroy();
1244 $$ = $1;
1245 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001246 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001247 *$1 += " " + *$2.val;
1248 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001249 $$ = $1;
1250 }
1251 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001252 const char* shiftop = $1->c_str();
1253 if (*$1 == "shr")
1254 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1255 $$ = new std::string(shiftop);
1256 *$$ += " " + *$2.val + ", " + *$4.val;
1257 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001258 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001259 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001260 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001261 TypeInfo SrcTy = $2.type;
1262 TypeInfo DstTy = $4;
1263 ResolveType(DstTy);
1264 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001265 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001266 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1267 } else {
1268 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001269 }
Reid Spencerf5626a32007-01-01 01:20:41 +00001270 // Check to see if this is a useless cast of a value to the same name
1271 // and the same type. Such casts will probably cause redefinition errors
1272 // when assembled and perform no code gen action so just remove them.
1273 if (*$1 == "cast" || *$1 == "bitcast")
1274 if ($2.type.isInteger() && $4.isInteger() &&
1275 $2.type.getBitWidth() == $4.getBitWidth()) {
1276 deleteUselessCastFlag = true; // Flag the "Inst" rule
1277 deleteUselessCastName = new std::string(*$2.val); // save the name
1278 size_t pos = deleteUselessCastName->find_first_of("%\"",0);
1279 if (pos != std::string::npos) {
1280 // remove the type portion before val
1281 deleteUselessCastName->erase(0, pos);
1282 }
1283 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001284 delete $1; $2.destroy();
1285 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001286 }
1287 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001288 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1289 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001290 $$ = $1;
1291 }
1292 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001293 *$1 += " " + *$2.val + ", " + *$4.newTy;
1294 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001295 $$ = $1;
1296 }
1297 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001298 *$1 += " " + *$2.val + ", " + *$4.val;
1299 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001300 $$ = $1;
1301 }
1302 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001303 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1304 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001305 $$ = $1;
1306 }
1307 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001308 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1309 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001310 $$ = $1;
1311 }
1312 | PHI_TOK PHIList {
1313 *$1 += " " + *$2;
1314 delete $2;
1315 $$ = $1;
1316 }
1317 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1318 if (!$2->empty())
1319 *$1 += " " + *$2;
1320 if (!$1->empty())
1321 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001322 *$1 += *$3.newTy + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001323 for (unsigned i = 0; i < $6->size(); ++i) {
1324 ValueInfo& VI = (*$6)[i];
1325 *$1 += *VI.val;
1326 if (i+1 < $6->size())
1327 *$1 += ", ";
1328 VI.destroy();
1329 }
1330 *$1 += ")";
Reid Spencerf459d392006-12-02 16:19:52 +00001331 delete $2; $3.destroy(); $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001332 $$ = $1;
1333 }
1334 | MemoryInst ;
1335
1336
1337// IndexList - List of indices for GEP based instructions...
1338IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001339 : ',' ValueRefList { $$ = $2; }
1340 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001341 ;
1342
1343OptVolatile
1344 : VOLATILE
1345 | /* empty */ { $$ = new std::string(); }
1346 ;
1347
1348MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001349 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001350 if (!$3->empty())
1351 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001352 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001353 $$ = $1;
1354 }
1355 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001356 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001357 if (!$6->empty())
1358 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001359 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001360 $$ = $1;
1361 }
1362 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001363 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001364 if (!$3->empty())
1365 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001366 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001367 $$ = $1;
1368 }
1369 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001370 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001371 if (!$6->empty())
1372 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001373 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001374 $$ = $1;
1375 }
1376 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001377 *$1 += " " + *$2.val;
1378 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001379 $$ = $1;
1380 }
1381 | OptVolatile LOAD Types ValueRef {
1382 if (!$1->empty())
1383 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001384 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1385 delete $2; $3.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001386 $$ = $1;
1387 }
1388 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1389 if (!$1->empty())
1390 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001391 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1392 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001393 $$ = $1;
1394 }
1395 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf459d392006-12-02 16:19:52 +00001396 // Upgrade the indices
1397 for (unsigned i = 0; i < $4->size(); ++i) {
1398 ValueInfo& VI = (*$4)[i];
1399 if (VI.type.isUnsigned() && !VI.isConstant() &&
1400 VI.type.getBitWidth() < 64) {
1401 std::string* old = VI.val;
1402 *O << " %gep_upgrade" << unique << " = zext " << *old
Reid Spencer71d2ec92006-12-31 06:02:26 +00001403 << " to i64\n";
1404 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
Reid Spencerf459d392006-12-02 16:19:52 +00001405 VI.type.oldTy = ULongTy;
1406 delete old;
1407 }
1408 }
1409 *$1 += " " + *$2.newTy + " " + *$3.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001410 for (unsigned i = 0; i < $4->size(); ++i) {
1411 ValueInfo& VI = (*$4)[i];
1412 *$1 += ", " + *VI.val;
1413 VI.destroy();
1414 }
Reid Spencerf459d392006-12-02 16:19:52 +00001415 $2.destroy(); $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001416 $$ = $1;
1417 };
1418
1419%%
1420
1421int yyerror(const char *ErrorMsg) {
1422 std::string where
1423 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1424 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1425 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1426 if (yychar == YYEMPTY || yychar == 0)
1427 errMsg += "end-of-file.";
1428 else
1429 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
Reid Spencer71d2ec92006-12-31 06:02:26 +00001430 std::cerr << "llvm-upgrade: " << errMsg << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001431 exit(1);
1432}