blob: af6bb3d58121651acd36ac79725889c512d0ea44 [file] [log] [blame]
Reid Spencer96839be2006-11-30 16:50:26 +00001//===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
Reid Spencere7c3c602006-11-30 06:36:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Reid Spencer96839be2006-11-30 16:50:26 +000010// This file implements the bison parser for LLVM 1.9 assembly language.
Reid Spencere7c3c602006-11-30 06:36:44 +000011//
12//===----------------------------------------------------------------------===//
13
14%{
Reid Spencere7c3c602006-11-30 06:36:44 +000015#include "ParserInternals.h"
16#include <llvm/ADT/StringExtras.h>
Reid Spencere7c3c602006-11-30 06:36:44 +000017#include <algorithm>
Reid Spencera50d5962006-12-02 04:11:07 +000018#include <map>
Reid Spencere7c3c602006-11-30 06:36:44 +000019#include <utility>
20#include <iostream>
21
Reid Spencere77e35e2006-12-01 20:26:20 +000022#define YYERROR_VERBOSE 1
Reid Spencer96839be2006-11-30 16:50:26 +000023#define YYINCLUDED_STDLIB_H
Reid Spencere77e35e2006-12-01 20:26:20 +000024#define YYDEBUG 1
Reid Spencere7c3c602006-11-30 06:36:44 +000025
26int yylex(); // declaration" of xxx warnings.
27int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000028extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000029
30static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000031static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000032std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000033unsigned SizeOfPointer = 32;
Reid Spencerf459d392006-12-02 16:19:52 +000034static uint64_t unique = 1;
Reid Spencer96839be2006-11-30 16:50:26 +000035
Reid Spencera50d5962006-12-02 04:11:07 +000036typedef std::vector<TypeInfo> TypeVector;
37static TypeVector EnumeratedTypes;
38typedef std::map<std::string,TypeInfo> TypeMap;
39static TypeMap NamedTypes;
40
Reid Spencerf8483652006-12-02 15:16:01 +000041void destroy(ValueList* VL) {
42 while (!VL->empty()) {
43 ValueInfo& VI = VL->back();
44 VI.destroy();
45 VL->pop_back();
46 }
47 delete VL;
48}
49
Reid Spencer96839be2006-11-30 16:50:26 +000050void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencere77e35e2006-12-01 20:26:20 +000051 std::ostream &out, bool debug)
Reid Spencere7c3c602006-11-30 06:36:44 +000052{
53 Upgradelineno = 1;
54 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000055 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000056 yydebug = debug;
Reid Spencere7c3c602006-11-30 06:36:44 +000057 O = &out;
58
59 if (yyparse()) {
60 std::cerr << "Parse failed.\n";
61 exit(1);
62 }
63}
64
Reid Spencera50d5962006-12-02 04:11:07 +000065static void ResolveType(TypeInfo& Ty) {
66 if (Ty.oldTy == UnresolvedTy) {
67 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
68 if (I != NamedTypes.end())
69 Ty.oldTy = I->second.oldTy;
Reid Spencer280d8012006-12-01 23:40:53 +000070 else {
Reid Spencera50d5962006-12-02 04:11:07 +000071 std::string msg("Can't resolve type: ");
72 msg += *Ty.newTy;
73 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000074 }
Reid Spencera50d5962006-12-02 04:11:07 +000075 } else if (Ty.oldTy == NumericTy) {
76 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
77 if (ref < EnumeratedTypes.size()) {
78 Ty.oldTy = EnumeratedTypes[ref].oldTy;
79 } else {
80 std::string msg("Can't resolve type: ");
81 msg += *Ty.newTy;
82 yyerror(msg.c_str());
83 }
Reid Spencer280d8012006-12-01 23:40:53 +000084 }
Reid Spencera50d5962006-12-02 04:11:07 +000085 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000086}
87
Reid Spencera50d5962006-12-02 04:11:07 +000088static const char* getCastOpcode(
89 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
90{
Reid Spencere77e35e2006-12-01 20:26:20 +000091 unsigned SrcBits = SrcTy.getBitWidth();
92 unsigned DstBits = DstTy.getBitWidth();
93 const char* opcode = "bitcast";
94 // Run through the possibilities ...
95 if (DstTy.isIntegral()) { // Casting to integral
96 if (SrcTy.isIntegral()) { // Casting from integral
97 if (DstBits < SrcBits)
98 opcode = "trunc";
99 else if (DstBits > SrcBits) { // its an extension
100 if (SrcTy.isSigned())
101 opcode ="sext"; // signed -> SEXT
102 else
103 opcode = "zext"; // unsigned -> ZEXT
104 } else {
105 opcode = "bitcast"; // Same size, No-op cast
106 }
107 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
108 if (DstTy.isSigned())
109 opcode = "fptosi"; // FP -> sint
110 else
111 opcode = "fptoui"; // FP -> uint
112 } else if (SrcTy.isPacked()) {
113 assert(DstBits == SrcTy.getBitWidth() &&
114 "Casting packed to integer of different width");
115 opcode = "bitcast"; // same size, no-op cast
116 } else {
117 assert(SrcTy.isPointer() &&
118 "Casting from a value that is not first-class type");
119 opcode = "ptrtoint"; // ptr -> int
120 }
121 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
122 if (SrcTy.isIntegral()) { // Casting from integral
123 if (SrcTy.isSigned())
124 opcode = "sitofp"; // sint -> FP
125 else
126 opcode = "uitofp"; // uint -> FP
127 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
128 if (DstBits < SrcBits) {
129 opcode = "fptrunc"; // FP -> smaller FP
130 } else if (DstBits > SrcBits) {
131 opcode = "fpext"; // FP -> larger FP
132 } else {
133 opcode ="bitcast"; // same size, no-op cast
134 }
135 } else if (SrcTy.isPacked()) {
136 assert(DstBits == SrcTy.getBitWidth() &&
137 "Casting packed to floating point of different width");
138 opcode = "bitcast"; // same size, no-op cast
139 } else {
140 assert(0 && "Casting pointer or non-first class to float");
141 }
142 } else if (DstTy.isPacked()) {
143 if (SrcTy.isPacked()) {
144 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
145 "Casting packed to packed of different widths");
146 opcode = "bitcast"; // packed -> packed
147 } else if (DstTy.getBitWidth() == SrcBits) {
148 opcode = "bitcast"; // float/int -> packed
149 } else {
150 assert(!"Illegal cast to packed (wrong type or size)");
151 }
152 } else if (DstTy.isPointer()) {
153 if (SrcTy.isPointer()) {
154 opcode = "bitcast"; // ptr -> ptr
155 } else if (SrcTy.isIntegral()) {
156 opcode = "inttoptr"; // int -> ptr
157 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000158 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000159 }
160 } else {
161 assert(!"Casting to type that is not first-class");
162 }
163 return opcode;
164}
165
Reid Spencera50d5962006-12-02 04:11:07 +0000166static std::string getCastUpgrade(
167 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
168{
169 std::string Result;
170 std::string Source = Src;
171 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
172 // fp -> ptr cast is no longer supported but we must upgrade this
173 // by doing a double cast: fp -> int -> ptr
174 if (isConst)
175 Source = "ulong fptoui(" + Source + " to ulong)";
176 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000177 *O << " %cast_upgrade" << unique << " = fptoui " << Source
178 << " to ulong\n";
179 Source = "ulong %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000180 }
181 // Update the SrcTy for the getCastOpcode call below
182 SrcTy.destroy();
183 SrcTy.newTy = new std::string("ulong");
184 SrcTy.oldTy = ULongTy;
185 } else if (DstTy.oldTy == BoolTy) {
186 // cast ptr %x to bool was previously defined as setne ptr %x, null
187 // The ptrtoint semantic is to truncate, not compare so we must retain
188 // the original intent by replace the cast with a setne
189 const char* comparator = SrcTy.isPointer() ? ", null" :
190 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
191 if (isConst)
192 Result = "setne (" + Source + comparator + ")";
193 else
194 Result = "setne " + Source + comparator;
195 return Result; // skip cast processing below
196 }
197 ResolveType(SrcTy);
198 ResolveType(DstTy);
199 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
200 if (isConst)
201 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
202 else
203 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
204 return Result;
205}
206
Reid Spencere7c3c602006-11-30 06:36:44 +0000207%}
208
Reid Spencere77e35e2006-12-01 20:26:20 +0000209%file-prefix="UpgradeParser"
210
211%union {
212 std::string* String;
213 TypeInfo Type;
214 ValueInfo Value;
215 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000216 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000217}
218
Reid Spencerf2d55322006-12-01 21:52:30 +0000219%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000220%token <Type> FLOAT DOUBLE LABEL
221%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000222%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000223%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
224%token <String> IMPLEMENTATION BEGINTOK ENDTOK
225%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
226%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
227%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
228%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
229%token <String> ALIGN
230%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
231%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
232%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
233%token <String> DATALAYOUT
234%token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
235%token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
236%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
237%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000238%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000239%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000240%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
241%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000242
243%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
244%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
245%type <String> ArgTypeListI ConstExpr DefinitionList
246%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
247%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
248%type <String> Function FunctionProto BasicBlock TypeListI
249%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
Reid Spencerf8483652006-12-02 15:16:01 +0000250%type <String> OptTailCall InstVal OptVolatile
Reid Spencere77e35e2006-12-01 20:26:20 +0000251%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
252%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencerf459d392006-12-02 16:19:52 +0000253%type <String> Name ConstValueRef ConstVector
Reid Spencerfcb5df82006-12-01 22:34:43 +0000254%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
Reid Spencere77e35e2006-12-01 20:26:20 +0000255
Reid Spencerf8483652006-12-02 15:16:01 +0000256%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000257
258%type <Type> IntType SIntType UIntType FPType TypesV Types
259%type <Type> PrimType UpRTypesV UpRTypes
260
Reid Spencerf2d55322006-12-01 21:52:30 +0000261%type <String> IntVal EInt64Val
262%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000263
Reid Spencerf459d392006-12-02 16:19:52 +0000264%type <Value> ValueRef ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000265
266%start Module
267
268%%
269
270// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000271IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000272EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000273
274// Operations that are notably excluded from this list include:
275// RET, BR, & SWITCH because they end basic blocks and are treated specially.
276ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
277LogicalOps : AND | OR | XOR;
278SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencerf7bde222006-12-01 22:26:37 +0000279ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000280CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
281 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
282 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000283
284// These are some types that allow classification if we only want a particular
285// thing... for example, only a signed, unsigned, or integral type.
286SIntType : LONG | INT | SHORT | SBYTE;
287UIntType : ULONG | UINT | USHORT | UBYTE;
288IntType : SIntType | UIntType;
289FPType : FLOAT | DOUBLE;
290
291// OptAssign - Value producing statements have an optional assignment component
292OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000293 $$ = $1;
294 }
295 | /*empty*/ {
296 $$ = new std::string("");
297 };
298
299OptLinkage
300 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
301 | EXTERN_WEAK
302 | /*empty*/ { $$ = new std::string(""); } ;
303
304OptCallingConv
305 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000306 | X86_FASTCALLCC_TOK
307 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000308 *$1 += *$2;
309 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000310 $$ = $1;
311 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000312 | /*empty*/ { $$ = new std::string(""); } ;
313
314// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
315// a comma before it.
316OptAlign
317 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000318 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencere7c3c602006-11-30 06:36:44 +0000319 ;
320OptCAlign
321 : /*empty*/ { $$ = new std::string(); }
322 | ',' ALIGN EUINT64VAL {
323 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000324 *$2 += " " + *$3;
325 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000326 $$ = $2;
327 };
328
329SectionString
330 : SECTION STRINGCONSTANT {
331 *$1 += " " + *$2;
332 delete $2;
333 $$ = $1;
334 };
335
336OptSection : /*empty*/ { $$ = new std::string(); }
337 | SectionString;
338
339GlobalVarAttributes
340 : /* empty */ { $$ = new std::string(); }
341 | ',' GlobalVarAttribute GlobalVarAttributes {
342 $2->insert(0, ", ");
343 if (!$3->empty())
344 *$2 += " " + *$3;
345 delete $3;
346 $$ = $2;
347 };
348
349GlobalVarAttribute
350 : SectionString
351 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000352 *$1 += " " + *$2;
353 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000354 $$ = $1;
355 };
356
357//===----------------------------------------------------------------------===//
358// Types includes all predefined types... except void, because it can only be
359// used in specific contexts (function returning void for example). To have
360// access to it, a user must explicitly use TypesV.
361//
362
363// TypesV includes all of 'Types', but it also includes the void type.
364TypesV : Types | VOID ;
365UpRTypesV : UpRTypes | VOID ;
366Types : UpRTypes ;
367
368// Derived types are added later...
369//
370PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000371PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000372UpRTypes
373 : OPAQUE {
374 $$.newTy = $1;
375 $$.oldTy = OpaqueTy;
376 }
377 | SymbolicValueRef {
378 $$.newTy = $1;
379 $$.oldTy = UnresolvedTy;
380 }
381 | PrimType
382 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000383
384// Include derived types in the Types production.
385//
386UpRTypes : '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000387 $2->insert(0, "\\");
388 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000389 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000390 }
391 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000392 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000393 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000394 $$.newTy = $1.newTy;
395 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000396 }
397 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000398 $2->insert(0,"[ ");
399 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000400 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000401 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000402 $$.oldTy = ArrayTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000403 }
404 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000405 $2->insert(0,"< ");
406 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000407 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000408 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000409 $$.oldTy = PackedTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000410 }
411 | '{' TypeListI '}' { // Structure type?
412 $2->insert(0, "{ ");
413 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000414 $$.newTy = $2;
415 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000416 }
417 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000418 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000419 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000420 }
421 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000422 *$1.newTy += '*';
423 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000424 $$ = $1;
425 };
426
427// TypeList - Used for struct declarations and as a basis for function type
428// declaration type lists
429//
Reid Spencere77e35e2006-12-01 20:26:20 +0000430TypeListI
431 : UpRTypes {
432 $$ = $1.newTy;
433 }
434 | TypeListI ',' UpRTypes {
435 *$1 += ", " + *$3.newTy;
436 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000437 $$ = $1;
438 };
439
440// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000441ArgTypeListI
442 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000443 | TypeListI ',' DOTDOTDOT {
444 *$1 += ", ...";
445 delete $3;
446 $$ = $1;
447 }
448 | DOTDOTDOT {
449 $$ = $1;
450 }
451 | /*empty*/ {
452 $$ = new std::string();
453 };
454
455// ConstVal - The various declarations that go into the constant pool. This
456// production is used ONLY to represent constants that show up AFTER a 'const',
457// 'constant' or 'global' token at global scope. Constants that can be inlined
458// into other expressions (such as integers and constexprs) are handled by the
459// ResolvedVal, ValueRef and ConstValueRef productions.
460//
461ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000462 $$.type = $1;
463 $$.cnst = new std::string(*$1.newTy);
464 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000465 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000466 }
467 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000468 $$.type = $1;
469 $$.cnst = new std::string(*$1.newTy);
470 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000471 }
472 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000473 $$.type = $1;
474 $$.cnst = new std::string(*$1.newTy);
475 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000476 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000477 }
478 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000479 $$.type = $1;
480 $$.cnst = new std::string(*$1.newTy);
481 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000482 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000483 }
484 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000485 $$.type = $1;
486 $$.cnst = new std::string(*$1.newTy);
487 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000488 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000489 }
490 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000491 $$.type = $1;
492 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000493 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000494 }
495 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000496 $$.type = $1;
497 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000498 *$$.cnst += " " + *$2;
499 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000500 }
501 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000502 $$.type = $1;
503 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000504 *$$.cnst += " " + *$2;
505 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000506 }
507 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000508 $$.type = $1;
509 $$.cnst = new std::string(*$1.newTy);
510 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000511 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000512 }
513 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000514 $$.type = $1;
515 $$.cnst = new std::string(*$1.newTy);
516 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000517 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000518 }
519 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000520 $$.type = $1;
521 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000522 *$$.cnst += " " + *$2;
523 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000524 }
525 | SIntType EInt64Val { // integral constants
526 $$.type = $1;
527 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000528 *$$.cnst += " " + *$2;
529 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000530 }
531 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000532 $$.type = $1;
533 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000534 *$$.cnst += " " + *$2;
535 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000536 }
537 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000538 $$.type = $1;
539 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000540 *$$.cnst += " " + *$2;
541 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000542 }
543 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000544 $$.type = $1;
545 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000546 *$$.cnst += " " + *$2;
547 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000548 }
549 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000550 $$.type = $1;
551 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000552 *$$.cnst += " " + *$2;
553 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000554 };
555
556
Reid Spencerfcb5df82006-12-01 22:34:43 +0000557ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000558 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000559 TypeInfo DstTy = $5;
560 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000561 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000562 // Call getCastUpgrade to upgrade the old cast
563 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
564 } else {
565 // Nothing to upgrade, just create the cast constant expr
566 $$ = new std::string(*$1);
567 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000568 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000569 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000570 }
571 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000572 *$1 += "(" + *$3.cnst;
573 for (unsigned i = 0; i < $4->size(); ++i) {
574 ValueInfo& VI = (*$4)[i];
575 *$1 += ", " + *VI.val;
576 VI.destroy();
577 }
578 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000579 $$ = $1;
580 $3.destroy();
581 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000582 }
583 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000584 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
585 $3.destroy(); $5.destroy(); $7.destroy();
586 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000587 }
588 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000589 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
590 $3.destroy(); $5.destroy();
591 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000592 }
593 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000594 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
595 $3.destroy(); $5.destroy();
596 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000597 }
598 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000599 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
600 $3.destroy(); $5.destroy();
601 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000602 }
603 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000604 const char* shiftop = $1->c_str();
605 if (*$1 == "shr")
606 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
607 $$ = new std::string(shiftop);
608 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
609 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000610 }
611 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000612 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
613 $3.destroy(); $5.destroy();
614 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000615 }
616 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000617 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
618 $3.destroy(); $5.destroy(); $7.destroy();
619 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000620 }
621 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000622 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
623 $3.destroy(); $5.destroy(); $7.destroy();
624 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000625 };
626
627
628// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000629
630ConstVector
631 : ConstVector ',' ConstVal {
632 *$1 += ", " + *$3.cnst;
633 $3.destroy();
634 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000635 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000636 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
637 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000638
639
640// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000641GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000642
643
644//===----------------------------------------------------------------------===//
645// Rules to match Modules
646//===----------------------------------------------------------------------===//
647
648// Module rule: Capture the result of parsing the whole file into a result
649// variable...
650//
651Module : DefinitionList {
652};
653
654// DefinitionList - Top level definitions
655//
656DefinitionList : DefinitionList Function {
657 $$ = 0;
658 }
659 | DefinitionList FunctionProto {
660 *O << *$2 << "\n";
661 delete $2;
662 $$ = 0;
663 }
664 | DefinitionList MODULE ASM_TOK AsmBlock {
665 *O << "module asm " << " " << *$4 << "\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000666 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000667 }
668 | DefinitionList IMPLEMENTATION {
669 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000670 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000671 }
Reid Spencera50d5962006-12-02 04:11:07 +0000672 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000673
674// ConstPool - Constants with optional names assigned to them.
675ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000676 EnumeratedTypes.push_back($4);
677 if (!$2->empty()) {
678 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
679 NamedTypes[*$2].oldTy = $4.oldTy;
680 *O << *$2 << " = ";
681 }
682 *O << "type " << *$4.newTy << "\n";
683 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000684 $$ = 0;
685 }
686 | ConstPool FunctionProto { // Function prototypes can be in const pool
687 *O << *$2 << "\n";
688 delete $2;
689 $$ = 0;
690 }
691 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
692 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
693 delete $2; delete $3; delete $4;
694 $$ = 0;
695 }
696 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000697 if (!$2->empty())
698 *O << *$2 << " = ";
699 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000700 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000701 $$ = 0;
702 }
703 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000704 if (!$2->empty())
705 *O << *$2 << " = ";
706 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000707 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000708 $$ = 0;
709 }
710 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000711 if (!$2->empty())
712 *O << *$2 << " = ";
713 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000714 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000715 $$ = 0;
716 }
717 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000718 if (!$2->empty())
719 *O << *$2 << " = ";
720 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000721 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000722 $$ = 0;
723 }
724 | ConstPool TARGET TargetDefinition {
725 *O << *$2 << " " << *$3 << "\n";
726 delete $2; delete $3;
727 $$ = 0;
728 }
729 | ConstPool DEPLIBS '=' LibrariesDefinition {
730 *O << *$2 << " = " << *$4 << "\n";
731 delete $2; delete $4;
732 $$ = 0;
733 }
734 | /* empty: end of list */ {
735 $$ = 0;
736 };
737
738
739AsmBlock : STRINGCONSTANT ;
740
741BigOrLittle : BIG | LITTLE
742
743TargetDefinition
744 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000745 *$1 += " = " + *$3;
746 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000747 $$ = $1;
748 }
749 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000750 *$1 += " = " + *$3;
751 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000752 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000753 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000754 $$ = $1;
755 }
756 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000757 *$1 += " = " + *$3;
758 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000759 $$ = $1;
760 }
761 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000762 *$1 += " = " + *$3;
763 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000764 $$ = $1;
765 };
766
767LibrariesDefinition
768 : '[' LibList ']' {
769 $2->insert(0, "[ ");
770 *$2 += " ]";
771 $$ = $2;
772 };
773
774LibList
775 : LibList ',' STRINGCONSTANT {
776 *$1 += ", " + *$3;
777 delete $3;
778 $$ = $1;
779 }
780 | STRINGCONSTANT
781 | /* empty: end of list */ {
782 $$ = new std::string();
783 };
784
785//===----------------------------------------------------------------------===//
786// Rules to match Function Headers
787//===----------------------------------------------------------------------===//
788
789Name : VAR_ID | STRINGCONSTANT;
790OptName : Name | /*empty*/ { $$ = new std::string(); };
791
792ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000793 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000794 if (!$2->empty())
795 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000796 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000797};
798
799ArgListH : ArgListH ',' ArgVal {
800 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000801 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000802 }
803 | ArgVal {
804 $$ = $1;
805 };
806
807ArgList : ArgListH {
808 $$ = $1;
809 }
810 | ArgListH ',' DOTDOTDOT {
811 *$1 += ", ...";
812 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000813 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000814 }
815 | DOTDOTDOT {
816 $$ = $1;
817 }
Reid Spencerd154b572006-12-01 20:36:40 +0000818 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000819
820FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
821 OptSection OptAlign {
822 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000823 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000824 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000825 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000826 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000827 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000828 }
829 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000830 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000831 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000832 $2.destroy();
833 delete $3;
834 delete $5;
835 delete $7;
836 delete $8;
837 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000838 };
839
840BEGIN : BEGINTOK {
841 $$ = new std::string("begin");
842 }
843 | '{' {
844 $$ = new std::string ("{");
845 }
846
847FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
848 if (!$1->empty()) {
849 *O << *$1 << " ";
850 }
851 *O << *$2 << " " << *$3 << "\n";
852 delete $1; delete $2; delete $3;
853 $$ = 0;
854};
855
856END : ENDTOK { $$ = new std::string("end"); }
857 | '}' { $$ = new std::string("}"); };
858
859Function : FunctionHeader BasicBlockList END {
860 if ($2)
861 *O << *$2;
862 *O << '\n' << *$3 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000863 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000864};
865
Reid Spencere77e35e2006-12-01 20:26:20 +0000866FnDeclareLinkage
867 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000868 | DLLIMPORT
869 | EXTERN_WEAK
870 ;
871
872FunctionProto
873 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000874 if (!$2->empty())
875 *$1 += " " + *$2;
876 *$1 += " " + *$3;
877 delete $2;
878 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000879 $$ = $1;
880 };
881
882//===----------------------------------------------------------------------===//
883// Rules to match Basic Blocks
884//===----------------------------------------------------------------------===//
885
Reid Spencerd154b572006-12-01 20:36:40 +0000886OptSideEffect : /* empty */ { $$ = new std::string(); }
887 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000888
Reid Spencere77e35e2006-12-01 20:26:20 +0000889ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000890 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
891 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +0000892 | '<' ConstVector '>' {
893 $2->insert(0, "<");
894 *$2 += ">";
895 $$ = $2;
896 }
897 | ConstExpr
898 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
899 if (!$2->empty()) {
900 *$1 += " " + *$2;
901 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000902 *$1 += " " + *$3 + ", " + *$5;
903 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +0000904 $$ = $1;
905 };
906
Reid Spencerf2d55322006-12-01 21:52:30 +0000907SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000908
909// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +0000910ValueRef
911 : SymbolicValueRef {
912 $$.val = $1;
913 $$.constant = false;
914 $$.type.newTy = 0;
915 $$.type.oldTy = UnresolvedTy;
916 }
917 | ConstValueRef {
918 $$.val = $1;
919 $$.constant = true;
920 $$.type.newTy = 0;
921 $$.type.oldTy = UnresolvedTy;
922 }
923 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000924
925// ResolvedVal - a <type> <value> pair. This is used only in cases where the
926// type immediately preceeds the value reference, and allows complex constant
927// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
928ResolvedVal : Types ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +0000929 $$ = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000930 $$.type = $1;
Reid Spencerf459d392006-12-02 16:19:52 +0000931 $$.val->insert(0, *$1.newTy + " ");
Reid Spencere7c3c602006-11-30 06:36:44 +0000932 };
933
934BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +0000935 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000936 }
937 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +0000938 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000939 };
940
941
942// Basic blocks are terminated by branching instructions:
943// br, br/cc, switch, ret
944//
Reid Spencer16244f42006-12-01 21:10:07 +0000945BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +0000946 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000947 };
948
949InstructionList : InstructionList Inst {
950 *O << " " << *$2 << "\n";
951 delete $2;
952 $$ = 0;
953 }
954 | /* empty */ {
955 $$ = 0;
956 }
957 | LABELSTR {
958 *O << *$1 << "\n";
959 delete $1;
960 $$ = 0;
961 };
962
963BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000964 *O << " " << *$1 << " " << *$2.val << "\n";
965 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000966 $$ = 0;
967 }
968 | RET VOID { // Return with no result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000969 *O << " " << *$1 << " " << *$2.newTy << "\n";
970 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000971 $$ = 0;
972 }
973 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencerf459d392006-12-02 16:19:52 +0000974 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << "\n";
975 delete $1; $2.destroy(); $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000976 $$ = 0;
977 } // Conditional Branch...
978 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +0000979 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
980 << *$5.newTy << " " << *$6.val << ", " << *$8.newTy << " "
981 << *$9.val << "\n";
982 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
983 $8.destroy(); $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000984 $$ = 0;
985 }
986 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencerf459d392006-12-02 16:19:52 +0000987 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
988 << *$5.newTy << " " << *$6.val << " [" << *$8 << " ]\n";
989 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
990 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000991 $$ = 0;
992 }
993 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencerf459d392006-12-02 16:19:52 +0000994 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
995 << *$5.newTy << " " << *$6.val << "[]\n";
996 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000997 $$ = 0;
998 }
Reid Spencer16244f42006-12-01 21:10:07 +0000999 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencere7c3c602006-11-30 06:36:44 +00001000 TO LABEL ValueRef UNWIND LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001001 *O << " ";
1002 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +00001003 *O << *$1 << " = ";
Reid Spencerf459d392006-12-02 16:19:52 +00001004 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001005 for (unsigned i = 0; i < $7->size(); ++i) {
1006 ValueInfo& VI = (*$7)[i];
1007 *O << *VI.val;
1008 if (i+1 < $7->size())
1009 *O << ", ";
1010 VI.destroy();
1011 }
Reid Spencerf459d392006-12-02 16:19:52 +00001012 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11.val << " "
1013 << *$12 << " " << *$13.newTy << " " << *$14.val << "\n";
1014 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1015 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1016 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001017 $$ = 0;
1018 }
1019 | UNWIND {
1020 *O << " " << *$1 << "\n";
1021 delete $1;
1022 $$ = 0;
1023 }
1024 | UNREACHABLE {
1025 *O << " " << *$1 << "\n";
1026 delete $1;
1027 $$ = 0;
1028 };
1029
1030JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001031 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1032 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001033 $$ = $1;
1034 }
1035 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001036 $2->insert(0, *$1.newTy + " " );
Reid Spencerf459d392006-12-02 16:19:52 +00001037 *$2 += ", " + *$4.newTy + " " + *$5.val;
1038 $1.destroy(); $4.destroy(); $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001039 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001040 };
1041
1042Inst
1043 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001044 if (!$1->empty())
1045 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001046 *$1 += *$2;
1047 delete $2;
1048 $$ = $1;
1049 };
1050
1051PHIList
1052 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencerf459d392006-12-02 16:19:52 +00001053 $3.val->insert(0, *$1.newTy + "[");
1054 *$3.val += "," + *$5.val + "]";
1055 $1.destroy(); $5.destroy();
1056 $$ = new std::string(*$3.val);
1057 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001058 }
1059 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001060 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1061 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001062 $$ = $1;
1063 };
1064
1065
1066ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001067 : ResolvedVal {
1068 $$ = new ValueList();
1069 $$->push_back($1);
1070 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001071 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001072 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001073 $$ = $1;
1074 };
1075
1076// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1077ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001078 : ValueRefList { $$ = $1; }
1079 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001080 ;
1081
1082OptTailCall
1083 : TAIL CALL {
1084 *$1 += " " + *$2;
1085 delete $2;
1086 $$ = $1;
1087 }
1088 | CALL
1089 ;
1090
1091InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001092 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1093 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001094 $$ = $1;
1095 }
1096 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001097 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1098 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001099 $$ = $1;
1100 }
1101 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001102 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1103 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001104 $$ = $1;
1105 }
1106 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001107 *$1 += " " + *$2.val;
1108 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001109 $$ = $1;
1110 }
1111 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001112 const char* shiftop = $1->c_str();
1113 if (*$1 == "shr")
1114 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1115 $$ = new std::string(shiftop);
1116 *$$ += " " + *$2.val + ", " + *$4.val;
1117 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001118 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001119 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001120 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001121 TypeInfo SrcTy = $2.type;
1122 TypeInfo DstTy = $4;
1123 ResolveType(DstTy);
1124 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001125 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001126 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1127 } else {
1128 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001129 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001130 delete $1; $2.destroy();
1131 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001132 }
1133 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001134 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1135 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001136 $$ = $1;
1137 }
1138 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001139 *$1 += " " + *$2.val + ", " + *$4.newTy;
1140 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001141 $$ = $1;
1142 }
1143 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001144 *$1 += " " + *$2.val + ", " + *$4.val;
1145 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001146 $$ = $1;
1147 }
1148 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001149 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1150 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001151 $$ = $1;
1152 }
1153 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001154 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1155 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001156 $$ = $1;
1157 }
1158 | PHI_TOK PHIList {
1159 *$1 += " " + *$2;
1160 delete $2;
1161 $$ = $1;
1162 }
1163 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1164 if (!$2->empty())
1165 *$1 += " " + *$2;
1166 if (!$1->empty())
1167 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001168 *$1 += *$3.newTy + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001169 for (unsigned i = 0; i < $6->size(); ++i) {
1170 ValueInfo& VI = (*$6)[i];
1171 *$1 += *VI.val;
1172 if (i+1 < $6->size())
1173 *$1 += ", ";
1174 VI.destroy();
1175 }
1176 *$1 += ")";
Reid Spencerf459d392006-12-02 16:19:52 +00001177 delete $2; $3.destroy(); $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001178 $$ = $1;
1179 }
1180 | MemoryInst ;
1181
1182
1183// IndexList - List of indices for GEP based instructions...
1184IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001185 : ',' ValueRefList { $$ = $2; }
1186 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001187 ;
1188
1189OptVolatile
1190 : VOLATILE
1191 | /* empty */ { $$ = new std::string(); }
1192 ;
1193
1194MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001195 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001196 if (!$3->empty())
1197 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001198 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001199 $$ = $1;
1200 }
1201 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001202 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001203 if (!$6->empty())
1204 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001205 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001206 $$ = $1;
1207 }
1208 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001209 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001210 if (!$3->empty())
1211 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001212 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001213 $$ = $1;
1214 }
1215 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001216 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001217 if (!$6->empty())
1218 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001219 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001220 $$ = $1;
1221 }
1222 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001223 *$1 += " " + *$2.val;
1224 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001225 $$ = $1;
1226 }
1227 | OptVolatile LOAD Types ValueRef {
1228 if (!$1->empty())
1229 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001230 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1231 delete $2; $3.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001232 $$ = $1;
1233 }
1234 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1235 if (!$1->empty())
1236 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001237 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1238 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001239 $$ = $1;
1240 }
1241 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf459d392006-12-02 16:19:52 +00001242 // Upgrade the indices
1243 for (unsigned i = 0; i < $4->size(); ++i) {
1244 ValueInfo& VI = (*$4)[i];
1245 if (VI.type.isUnsigned() && !VI.isConstant() &&
1246 VI.type.getBitWidth() < 64) {
1247 std::string* old = VI.val;
1248 *O << " %gep_upgrade" << unique << " = zext " << *old
1249 << " to ulong\n";
1250 VI.val = new std::string("ulong %gep_upgrade" + llvm::utostr(unique++));
1251 VI.type.oldTy = ULongTy;
1252 delete old;
1253 }
1254 }
1255 *$1 += " " + *$2.newTy + " " + *$3.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001256 for (unsigned i = 0; i < $4->size(); ++i) {
1257 ValueInfo& VI = (*$4)[i];
1258 *$1 += ", " + *VI.val;
1259 VI.destroy();
1260 }
Reid Spencerf459d392006-12-02 16:19:52 +00001261 $2.destroy(); $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001262 $$ = $1;
1263 };
1264
1265%%
1266
1267int yyerror(const char *ErrorMsg) {
1268 std::string where
1269 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1270 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1271 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1272 if (yychar == YYEMPTY || yychar == 0)
1273 errMsg += "end-of-file.";
1274 else
1275 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1276 std::cerr << errMsg << '\n';
1277 exit(1);
1278}