blob: c9c98cee047ea6a5e259855f8a22ea32c1a7790d [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 <vector>
19#include <map>
Reid Spencere7c3c602006-11-30 06:36:44 +000020#include <utility>
21#include <iostream>
22
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 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 Spencer96839be2006-11-30 16:50:26 +000041void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencere77e35e2006-12-01 20:26:20 +000042 std::ostream &out, bool debug)
Reid Spencere7c3c602006-11-30 06:36:44 +000043{
44 Upgradelineno = 1;
45 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000046 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000047 yydebug = debug;
Reid Spencere7c3c602006-11-30 06:36:44 +000048 O = &out;
49
50 if (yyparse()) {
51 std::cerr << "Parse failed.\n";
52 exit(1);
53 }
54}
55
Reid Spencera50d5962006-12-02 04:11:07 +000056static void ResolveType(TypeInfo& Ty) {
57 if (Ty.oldTy == UnresolvedTy) {
58 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
59 if (I != NamedTypes.end())
60 Ty.oldTy = I->second.oldTy;
Reid Spencer280d8012006-12-01 23:40:53 +000061 else {
Reid Spencera50d5962006-12-02 04:11:07 +000062 std::string msg("Can't resolve type: ");
63 msg += *Ty.newTy;
64 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000065 }
Reid Spencera50d5962006-12-02 04:11:07 +000066 } else if (Ty.oldTy == NumericTy) {
67 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
68 if (ref < EnumeratedTypes.size()) {
69 Ty.oldTy = EnumeratedTypes[ref].oldTy;
70 } else {
71 std::string msg("Can't resolve type: ");
72 msg += *Ty.newTy;
73 yyerror(msg.c_str());
74 }
Reid Spencer280d8012006-12-01 23:40:53 +000075 }
Reid Spencera50d5962006-12-02 04:11:07 +000076 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000077}
78
Reid Spencera50d5962006-12-02 04:11:07 +000079static const char* getCastOpcode(
80 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
81{
Reid Spencere77e35e2006-12-01 20:26:20 +000082 unsigned SrcBits = SrcTy.getBitWidth();
83 unsigned DstBits = DstTy.getBitWidth();
84 const char* opcode = "bitcast";
85 // Run through the possibilities ...
86 if (DstTy.isIntegral()) { // Casting to integral
87 if (SrcTy.isIntegral()) { // Casting from integral
88 if (DstBits < SrcBits)
89 opcode = "trunc";
90 else if (DstBits > SrcBits) { // its an extension
91 if (SrcTy.isSigned())
92 opcode ="sext"; // signed -> SEXT
93 else
94 opcode = "zext"; // unsigned -> ZEXT
95 } else {
96 opcode = "bitcast"; // Same size, No-op cast
97 }
98 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
99 if (DstTy.isSigned())
100 opcode = "fptosi"; // FP -> sint
101 else
102 opcode = "fptoui"; // FP -> uint
103 } else if (SrcTy.isPacked()) {
104 assert(DstBits == SrcTy.getBitWidth() &&
105 "Casting packed to integer of different width");
106 opcode = "bitcast"; // same size, no-op cast
107 } else {
108 assert(SrcTy.isPointer() &&
109 "Casting from a value that is not first-class type");
110 opcode = "ptrtoint"; // ptr -> int
111 }
112 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
113 if (SrcTy.isIntegral()) { // Casting from integral
114 if (SrcTy.isSigned())
115 opcode = "sitofp"; // sint -> FP
116 else
117 opcode = "uitofp"; // uint -> FP
118 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
119 if (DstBits < SrcBits) {
120 opcode = "fptrunc"; // FP -> smaller FP
121 } else if (DstBits > SrcBits) {
122 opcode = "fpext"; // FP -> larger FP
123 } else {
124 opcode ="bitcast"; // same size, no-op cast
125 }
126 } else if (SrcTy.isPacked()) {
127 assert(DstBits == SrcTy.getBitWidth() &&
128 "Casting packed to floating point of different width");
129 opcode = "bitcast"; // same size, no-op cast
130 } else {
131 assert(0 && "Casting pointer or non-first class to float");
132 }
133 } else if (DstTy.isPacked()) {
134 if (SrcTy.isPacked()) {
135 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
136 "Casting packed to packed of different widths");
137 opcode = "bitcast"; // packed -> packed
138 } else if (DstTy.getBitWidth() == SrcBits) {
139 opcode = "bitcast"; // float/int -> packed
140 } else {
141 assert(!"Illegal cast to packed (wrong type or size)");
142 }
143 } else if (DstTy.isPointer()) {
144 if (SrcTy.isPointer()) {
145 opcode = "bitcast"; // ptr -> ptr
146 } else if (SrcTy.isIntegral()) {
147 opcode = "inttoptr"; // int -> ptr
148 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000149 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000150 }
151 } else {
152 assert(!"Casting to type that is not first-class");
153 }
154 return opcode;
155}
156
Reid Spencera50d5962006-12-02 04:11:07 +0000157static std::string getCastUpgrade(
158 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
159{
160 std::string Result;
161 std::string Source = Src;
162 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
163 // fp -> ptr cast is no longer supported but we must upgrade this
164 // by doing a double cast: fp -> int -> ptr
165 if (isConst)
166 Source = "ulong fptoui(" + Source + " to ulong)";
167 else {
168 *O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
169 Source = "ulong %cast_upgrade";
170 }
171 // Update the SrcTy for the getCastOpcode call below
172 SrcTy.destroy();
173 SrcTy.newTy = new std::string("ulong");
174 SrcTy.oldTy = ULongTy;
175 } else if (DstTy.oldTy == BoolTy) {
176 // cast ptr %x to bool was previously defined as setne ptr %x, null
177 // The ptrtoint semantic is to truncate, not compare so we must retain
178 // the original intent by replace the cast with a setne
179 const char* comparator = SrcTy.isPointer() ? ", null" :
180 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
181 if (isConst)
182 Result = "setne (" + Source + comparator + ")";
183 else
184 Result = "setne " + Source + comparator;
185 return Result; // skip cast processing below
186 }
187 ResolveType(SrcTy);
188 ResolveType(DstTy);
189 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
190 if (isConst)
191 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
192 else
193 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
194 return Result;
195}
196
Reid Spencere7c3c602006-11-30 06:36:44 +0000197%}
198
Reid Spencere77e35e2006-12-01 20:26:20 +0000199%file-prefix="UpgradeParser"
200
201%union {
202 std::string* String;
203 TypeInfo Type;
204 ValueInfo Value;
205 ConstInfo Const;
206}
207
Reid Spencerf2d55322006-12-01 21:52:30 +0000208%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000209%token <Type> FLOAT DOUBLE LABEL
210%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000211%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000212%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
213%token <String> IMPLEMENTATION BEGINTOK ENDTOK
214%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
215%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
216%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
217%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
218%token <String> ALIGN
219%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
220%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
221%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
222%token <String> DATALAYOUT
223%token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
224%token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
225%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
226%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000227%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000228%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000229%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
230%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000231
232%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
233%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
234%type <String> ArgTypeListI ConstExpr DefinitionList
235%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
236%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
237%type <String> Function FunctionProto BasicBlock TypeListI
238%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
239%type <String> ValueRefList OptTailCall InstVal IndexList OptVolatile
240%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
241%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencerfcb5df82006-12-01 22:34:43 +0000242%type <String> Name ValueRef ValueRefListE ConstValueRef
243%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
Reid Spencere77e35e2006-12-01 20:26:20 +0000244
245%type <String> ConstVector
246
247%type <Type> IntType SIntType UIntType FPType TypesV Types
248%type <Type> PrimType UpRTypesV UpRTypes
249
Reid Spencerf2d55322006-12-01 21:52:30 +0000250%type <String> IntVal EInt64Val
251%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000252
253%type <Value> ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000254
255%start Module
256
257%%
258
259// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000260IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000261EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000262
263// Operations that are notably excluded from this list include:
264// RET, BR, & SWITCH because they end basic blocks and are treated specially.
265ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
266LogicalOps : AND | OR | XOR;
267SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencerf7bde222006-12-01 22:26:37 +0000268ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000269CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
270 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
271 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000272
273// These are some types that allow classification if we only want a particular
274// thing... for example, only a signed, unsigned, or integral type.
275SIntType : LONG | INT | SHORT | SBYTE;
276UIntType : ULONG | UINT | USHORT | UBYTE;
277IntType : SIntType | UIntType;
278FPType : FLOAT | DOUBLE;
279
280// OptAssign - Value producing statements have an optional assignment component
281OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000282 $$ = $1;
283 }
284 | /*empty*/ {
285 $$ = new std::string("");
286 };
287
288OptLinkage
289 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
290 | EXTERN_WEAK
291 | /*empty*/ { $$ = new std::string(""); } ;
292
293OptCallingConv
294 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000295 | X86_FASTCALLCC_TOK
296 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000297 *$1 += *$2;
298 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000299 $$ = $1;
300 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000301 | /*empty*/ { $$ = new std::string(""); } ;
302
303// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
304// a comma before it.
305OptAlign
306 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000307 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencere7c3c602006-11-30 06:36:44 +0000308 ;
309OptCAlign
310 : /*empty*/ { $$ = new std::string(); }
311 | ',' ALIGN EUINT64VAL {
312 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000313 *$2 += " " + *$3;
314 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000315 $$ = $2;
316 };
317
318SectionString
319 : SECTION STRINGCONSTANT {
320 *$1 += " " + *$2;
321 delete $2;
322 $$ = $1;
323 };
324
325OptSection : /*empty*/ { $$ = new std::string(); }
326 | SectionString;
327
328GlobalVarAttributes
329 : /* empty */ { $$ = new std::string(); }
330 | ',' GlobalVarAttribute GlobalVarAttributes {
331 $2->insert(0, ", ");
332 if (!$3->empty())
333 *$2 += " " + *$3;
334 delete $3;
335 $$ = $2;
336 };
337
338GlobalVarAttribute
339 : SectionString
340 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000341 *$1 += " " + *$2;
342 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000343 $$ = $1;
344 };
345
346//===----------------------------------------------------------------------===//
347// Types includes all predefined types... except void, because it can only be
348// used in specific contexts (function returning void for example). To have
349// access to it, a user must explicitly use TypesV.
350//
351
352// TypesV includes all of 'Types', but it also includes the void type.
353TypesV : Types | VOID ;
354UpRTypesV : UpRTypes | VOID ;
355Types : UpRTypes ;
356
357// Derived types are added later...
358//
359PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000360PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000361UpRTypes
362 : OPAQUE {
363 $$.newTy = $1;
364 $$.oldTy = OpaqueTy;
365 }
366 | SymbolicValueRef {
367 $$.newTy = $1;
368 $$.oldTy = UnresolvedTy;
369 }
370 | PrimType
371 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000372
373// Include derived types in the Types production.
374//
375UpRTypes : '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000376 $2->insert(0, "\\");
377 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000378 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000379 }
380 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000381 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000382 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000383 $$.newTy = $1.newTy;
384 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000385 }
386 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000387 $2->insert(0,"[ ");
388 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000389 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000390 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000391 $$.oldTy = ArrayTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000392 }
393 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000394 $2->insert(0,"< ");
395 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000396 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000397 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000398 $$.oldTy = PackedTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000399 }
400 | '{' TypeListI '}' { // Structure type?
401 $2->insert(0, "{ ");
402 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000403 $$.newTy = $2;
404 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000405 }
406 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000407 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000408 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000409 }
410 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000411 *$1.newTy += '*';
412 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000413 $$ = $1;
414 };
415
416// TypeList - Used for struct declarations and as a basis for function type
417// declaration type lists
418//
Reid Spencere77e35e2006-12-01 20:26:20 +0000419TypeListI
420 : UpRTypes {
421 $$ = $1.newTy;
422 }
423 | TypeListI ',' UpRTypes {
424 *$1 += ", " + *$3.newTy;
425 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000426 $$ = $1;
427 };
428
429// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000430ArgTypeListI
431 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000432 | TypeListI ',' DOTDOTDOT {
433 *$1 += ", ...";
434 delete $3;
435 $$ = $1;
436 }
437 | DOTDOTDOT {
438 $$ = $1;
439 }
440 | /*empty*/ {
441 $$ = new std::string();
442 };
443
444// ConstVal - The various declarations that go into the constant pool. This
445// production is used ONLY to represent constants that show up AFTER a 'const',
446// 'constant' or 'global' token at global scope. Constants that can be inlined
447// into other expressions (such as integers and constexprs) are handled by the
448// ResolvedVal, ValueRef and ConstValueRef productions.
449//
450ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000451 $$.type = $1;
452 $$.cnst = new std::string(*$1.newTy);
453 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000454 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000455 }
456 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000457 $$.type = $1;
458 $$.cnst = new std::string(*$1.newTy);
459 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000460 }
461 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000462 $$.type = $1;
463 $$.cnst = new std::string(*$1.newTy);
464 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000465 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000466 }
467 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000468 $$.type = $1;
469 $$.cnst = new std::string(*$1.newTy);
470 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000471 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000472 }
473 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000474 $$.type = $1;
475 $$.cnst = new std::string(*$1.newTy);
476 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000477 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000478 }
479 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000480 $$.type = $1;
481 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000482 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000483 }
484 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000485 $$.type = $1;
486 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000487 *$$.cnst += " " + *$2;
488 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000489 }
490 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000491 $$.type = $1;
492 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000493 *$$.cnst += " " + *$2;
494 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000495 }
496 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000497 $$.type = $1;
498 $$.cnst = new std::string(*$1.newTy);
499 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000500 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000501 }
502 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000503 $$.type = $1;
504 $$.cnst = new std::string(*$1.newTy);
505 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000506 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000507 }
508 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000509 $$.type = $1;
510 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000511 *$$.cnst += " " + *$2;
512 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000513 }
514 | SIntType EInt64Val { // integral constants
515 $$.type = $1;
516 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000517 *$$.cnst += " " + *$2;
518 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000519 }
520 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000521 $$.type = $1;
522 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000523 *$$.cnst += " " + *$2;
524 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000525 }
526 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000527 $$.type = $1;
528 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000529 *$$.cnst += " " + *$2;
530 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000531 }
532 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000533 $$.type = $1;
534 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000535 *$$.cnst += " " + *$2;
536 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000537 }
538 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000539 $$.type = $1;
540 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000541 *$$.cnst += " " + *$2;
542 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000543 };
544
545
Reid Spencerfcb5df82006-12-01 22:34:43 +0000546ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000547 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000548 TypeInfo DstTy = $5;
549 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000550 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000551 // Call getCastUpgrade to upgrade the old cast
552 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
553 } else {
554 // Nothing to upgrade, just create the cast constant expr
555 $$ = new std::string(*$1);
556 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000557 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000558 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000559 }
560 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000561 *$1 += "(" + *$3.cnst + " " + *$4 + ")";
562 $$ = $1;
563 $3.destroy();
564 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000565 }
566 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000567 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
568 $3.destroy(); $5.destroy(); $7.destroy();
569 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000570 }
571 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000572 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
573 $3.destroy(); $5.destroy();
574 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000575 }
576 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000577 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
578 $3.destroy(); $5.destroy();
579 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000580 }
581 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000582 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
583 $3.destroy(); $5.destroy();
584 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000585 }
586 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000587 const char* shiftop = $1->c_str();
588 if (*$1 == "shr")
589 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
590 $$ = new std::string(shiftop);
591 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
592 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000593 }
594 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000595 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
596 $3.destroy(); $5.destroy();
597 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000598 }
599 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000600 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
601 $3.destroy(); $5.destroy(); $7.destroy();
602 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000603 }
604 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000605 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
606 $3.destroy(); $5.destroy(); $7.destroy();
607 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000608 };
609
610
611// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000612
613ConstVector
614 : ConstVector ',' ConstVal {
615 *$1 += ", " + *$3.cnst;
616 $3.destroy();
617 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000618 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000619 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
620 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000621
622
623// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000624GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000625
626
627//===----------------------------------------------------------------------===//
628// Rules to match Modules
629//===----------------------------------------------------------------------===//
630
631// Module rule: Capture the result of parsing the whole file into a result
632// variable...
633//
634Module : DefinitionList {
635};
636
637// DefinitionList - Top level definitions
638//
639DefinitionList : DefinitionList Function {
640 $$ = 0;
641 }
642 | DefinitionList FunctionProto {
643 *O << *$2 << "\n";
644 delete $2;
645 $$ = 0;
646 }
647 | DefinitionList MODULE ASM_TOK AsmBlock {
648 *O << "module asm " << " " << *$4 << "\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000649 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000650 }
651 | DefinitionList IMPLEMENTATION {
652 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000653 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000654 }
Reid Spencera50d5962006-12-02 04:11:07 +0000655 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000656
657// ConstPool - Constants with optional names assigned to them.
658ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000659 EnumeratedTypes.push_back($4);
660 if (!$2->empty()) {
661 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
662 NamedTypes[*$2].oldTy = $4.oldTy;
663 *O << *$2 << " = ";
664 }
665 *O << "type " << *$4.newTy << "\n";
666 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000667 $$ = 0;
668 }
669 | ConstPool FunctionProto { // Function prototypes can be in const pool
670 *O << *$2 << "\n";
671 delete $2;
672 $$ = 0;
673 }
674 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
675 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
676 delete $2; delete $3; delete $4;
677 $$ = 0;
678 }
679 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000680 if (!$2->empty())
681 *O << *$2 << " = ";
682 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000683 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000684 $$ = 0;
685 }
686 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000687 if (!$2->empty())
688 *O << *$2 << " = ";
689 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000690 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000691 $$ = 0;
692 }
693 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000694 if (!$2->empty())
695 *O << *$2 << " = ";
696 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000697 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000698 $$ = 0;
699 }
700 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencera50d5962006-12-02 04:11:07 +0000701 if (!$2->empty())
702 *O << *$2 << " = ";
703 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000704 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000705 $$ = 0;
706 }
707 | ConstPool TARGET TargetDefinition {
708 *O << *$2 << " " << *$3 << "\n";
709 delete $2; delete $3;
710 $$ = 0;
711 }
712 | ConstPool DEPLIBS '=' LibrariesDefinition {
713 *O << *$2 << " = " << *$4 << "\n";
714 delete $2; delete $4;
715 $$ = 0;
716 }
717 | /* empty: end of list */ {
718 $$ = 0;
719 };
720
721
722AsmBlock : STRINGCONSTANT ;
723
724BigOrLittle : BIG | LITTLE
725
726TargetDefinition
727 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000728 *$1 += " = " + *$3;
729 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000730 $$ = $1;
731 }
732 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000733 *$1 += " = " + *$3;
734 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000735 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000736 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000737 $$ = $1;
738 }
739 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000740 *$1 += " = " + *$3;
741 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000742 $$ = $1;
743 }
744 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000745 *$1 += " = " + *$3;
746 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000747 $$ = $1;
748 };
749
750LibrariesDefinition
751 : '[' LibList ']' {
752 $2->insert(0, "[ ");
753 *$2 += " ]";
754 $$ = $2;
755 };
756
757LibList
758 : LibList ',' STRINGCONSTANT {
759 *$1 += ", " + *$3;
760 delete $3;
761 $$ = $1;
762 }
763 | STRINGCONSTANT
764 | /* empty: end of list */ {
765 $$ = new std::string();
766 };
767
768//===----------------------------------------------------------------------===//
769// Rules to match Function Headers
770//===----------------------------------------------------------------------===//
771
772Name : VAR_ID | STRINGCONSTANT;
773OptName : Name | /*empty*/ { $$ = new std::string(); };
774
775ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000776 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000777 if (!$2->empty())
778 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000779 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000780};
781
782ArgListH : ArgListH ',' ArgVal {
783 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000784 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000785 }
786 | ArgVal {
787 $$ = $1;
788 };
789
790ArgList : ArgListH {
791 $$ = $1;
792 }
793 | ArgListH ',' DOTDOTDOT {
794 *$1 += ", ...";
795 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000796 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000797 }
798 | DOTDOTDOT {
799 $$ = $1;
800 }
Reid Spencerd154b572006-12-01 20:36:40 +0000801 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000802
803FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
804 OptSection OptAlign {
805 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000806 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000807 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000808 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000809 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000810 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000811 }
812 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000813 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000814 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000815 $2.destroy();
816 delete $3;
817 delete $5;
818 delete $7;
819 delete $8;
820 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000821 };
822
823BEGIN : BEGINTOK {
824 $$ = new std::string("begin");
825 }
826 | '{' {
827 $$ = new std::string ("{");
828 }
829
830FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
831 if (!$1->empty()) {
832 *O << *$1 << " ";
833 }
834 *O << *$2 << " " << *$3 << "\n";
835 delete $1; delete $2; delete $3;
836 $$ = 0;
837};
838
839END : ENDTOK { $$ = new std::string("end"); }
840 | '}' { $$ = new std::string("}"); };
841
842Function : FunctionHeader BasicBlockList END {
843 if ($2)
844 *O << *$2;
845 *O << '\n' << *$3 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000846 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000847};
848
Reid Spencere77e35e2006-12-01 20:26:20 +0000849FnDeclareLinkage
850 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000851 | DLLIMPORT
852 | EXTERN_WEAK
853 ;
854
855FunctionProto
856 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000857 if (!$2->empty())
858 *$1 += " " + *$2;
859 *$1 += " " + *$3;
860 delete $2;
861 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000862 $$ = $1;
863 };
864
865//===----------------------------------------------------------------------===//
866// Rules to match Basic Blocks
867//===----------------------------------------------------------------------===//
868
Reid Spencerd154b572006-12-01 20:36:40 +0000869OptSideEffect : /* empty */ { $$ = new std::string(); }
870 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000871
Reid Spencere77e35e2006-12-01 20:26:20 +0000872ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000873 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
874 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +0000875 | '<' ConstVector '>' {
876 $2->insert(0, "<");
877 *$2 += ">";
878 $$ = $2;
879 }
880 | ConstExpr
881 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
882 if (!$2->empty()) {
883 *$1 += " " + *$2;
884 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000885 *$1 += " " + *$3 + ", " + *$5;
886 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +0000887 $$ = $1;
888 };
889
Reid Spencerf2d55322006-12-01 21:52:30 +0000890SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000891
892// ValueRef - A reference to a definition... either constant or symbolic
893ValueRef : SymbolicValueRef | ConstValueRef;
894
895
896// ResolvedVal - a <type> <value> pair. This is used only in cases where the
897// type immediately preceeds the value reference, and allows complex constant
898// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
899ResolvedVal : Types ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000900 $$.type = $1;
901 $$.val = new std::string(*$1.newTy + " ");
902 *$$.val += *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000903 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000904 };
905
906BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +0000907 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000908 }
909 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +0000910 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000911 };
912
913
914// Basic blocks are terminated by branching instructions:
915// br, br/cc, switch, ret
916//
Reid Spencer16244f42006-12-01 21:10:07 +0000917BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +0000918 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000919 };
920
921InstructionList : InstructionList Inst {
922 *O << " " << *$2 << "\n";
923 delete $2;
924 $$ = 0;
925 }
926 | /* empty */ {
927 $$ = 0;
928 }
929 | LABELSTR {
930 *O << *$1 << "\n";
931 delete $1;
932 $$ = 0;
933 };
934
935BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000936 *O << " " << *$1 << " " << *$2.val << "\n";
937 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000938 $$ = 0;
939 }
940 | RET VOID { // Return with no result...
Reid Spencere77e35e2006-12-01 20:26:20 +0000941 *O << " " << *$1 << " " << *$2.newTy << "\n";
942 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000943 $$ = 0;
944 }
945 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencere77e35e2006-12-01 20:26:20 +0000946 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
947 delete $1; $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000948 $$ = 0;
949 } // Conditional Branch...
950 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000951 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
952 << *$5.newTy << " " << *$6 << ", " << *$8.newTy << " " << *$9 << "\n";
953 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
954 $8.destroy(); delete $9;
Reid Spencere7c3c602006-11-30 06:36:44 +0000955 $$ = 0;
956 }
957 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000958 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
959 << " " << *$6 << " [" << *$8 << " ]\n";
960 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000961 $$ = 0;
962 }
963 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000964 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
965 << *$5.newTy << " " << *$6 << "[]\n";
966 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000967 $$ = 0;
968 }
Reid Spencer16244f42006-12-01 21:10:07 +0000969 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencere7c3c602006-11-30 06:36:44 +0000970 TO LABEL ValueRef UNWIND LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +0000971 *O << " ";
972 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +0000973 *O << *$1 << " = ";
Reid Spencer16244f42006-12-01 21:10:07 +0000974 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
975 << *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
976 << *$12 << " " << *$13.newTy << " " << *$14 << "\n";
977 delete $1; delete $2; delete $3; $4.destroy(); delete $5; delete $7;
978 delete $9; $10.destroy(); delete $11; delete $12; $13.destroy();
979 delete $14;
Reid Spencere7c3c602006-11-30 06:36:44 +0000980 $$ = 0;
981 }
982 | UNWIND {
983 *O << " " << *$1 << "\n";
984 delete $1;
985 $$ = 0;
986 }
987 | UNREACHABLE {
988 *O << " " << *$1 << "\n";
989 delete $1;
990 $$ = 0;
991 };
992
993JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +0000994 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +0000995 $2.destroy(); delete $3; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000996 $$ = $1;
997 }
998 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000999 $2->insert(0, *$1.newTy + " " );
1000 *$2 += ", " + *$4.newTy + " " + *$5;
1001 $1.destroy(); $4.destroy(); delete $5;
1002 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001003 };
1004
1005Inst
1006 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001007 if (!$1->empty())
1008 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001009 *$1 += *$2;
1010 delete $2;
1011 $$ = $1;
1012 };
1013
1014PHIList
1015 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencere77e35e2006-12-01 20:26:20 +00001016 $3->insert(0, *$1.newTy + "[");
1017 *$3 += "," + *$5 + "]";
1018 $1.destroy(); delete $5;
1019 $$ = $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001020 }
1021 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1022 *$1 += ", [" + *$4 + "," + *$6 + "]";
1023 delete $4; delete $6;
1024 $$ = $1;
1025 };
1026
1027
1028ValueRefList
Reid Spencere77e35e2006-12-01 20:26:20 +00001029 : ResolvedVal { $$ = new std::string(*$1.val); $1.destroy(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001030 | ValueRefList ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001031 *$1 += ", " + *$3.val;
1032 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001033 $$ = $1;
1034 };
1035
1036// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1037ValueRefListE
1038 : ValueRefList
1039 | /*empty*/ { $$ = new std::string(); }
1040 ;
1041
1042OptTailCall
1043 : TAIL CALL {
1044 *$1 += " " + *$2;
1045 delete $2;
1046 $$ = $1;
1047 }
1048 | CALL
1049 ;
1050
1051InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001052 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1053 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001054 $$ = $1;
1055 }
1056 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001057 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1058 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001059 $$ = $1;
1060 }
1061 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001062 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1063 $2.destroy(); delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001064 $$ = $1;
1065 }
1066 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001067 *$1 += " " + *$2.val;
1068 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001069 $$ = $1;
1070 }
1071 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001072 const char* shiftop = $1->c_str();
1073 if (*$1 == "shr")
1074 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1075 $$ = new std::string(shiftop);
1076 *$$ += " " + *$2.val + ", " + *$4.val;
1077 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001078 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001079 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001080 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001081 TypeInfo SrcTy = $2.type;
1082 TypeInfo DstTy = $4;
1083 ResolveType(DstTy);
1084 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001085 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001086 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1087 } else {
1088 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001089 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001090 delete $1; $2.destroy();
1091 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001092 }
1093 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001094 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1095 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001096 $$ = $1;
1097 }
1098 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001099 *$1 += " " + *$2.val + ", " + *$4.newTy;
1100 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001101 $$ = $1;
1102 }
1103 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001104 *$1 += " " + *$2.val + ", " + *$4.val;
1105 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001106 $$ = $1;
1107 }
1108 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001109 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1110 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001111 $$ = $1;
1112 }
1113 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001114 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1115 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001116 $$ = $1;
1117 }
1118 | PHI_TOK PHIList {
1119 *$1 += " " + *$2;
1120 delete $2;
1121 $$ = $1;
1122 }
1123 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1124 if (!$2->empty())
1125 *$1 += " " + *$2;
1126 if (!$1->empty())
1127 *$1 += " ";
Reid Spencere77e35e2006-12-01 20:26:20 +00001128 *$1 += *$3.newTy + " " + *$4 + "(" + *$6 + ")";
1129 delete $2; $3.destroy(); delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001130 $$ = $1;
1131 }
1132 | MemoryInst ;
1133
1134
1135// IndexList - List of indices for GEP based instructions...
1136IndexList
1137 : ',' ValueRefList {
1138 $2->insert(0, ", ");
1139 $$ = $2;
1140 }
1141 | /* empty */ { $$ = new std::string(); }
1142 ;
1143
1144OptVolatile
1145 : VOLATILE
1146 | /* empty */ { $$ = new std::string(); }
1147 ;
1148
1149MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001150 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001151 if (!$3->empty())
1152 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001153 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001154 $$ = $1;
1155 }
1156 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001157 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001158 if (!$6->empty())
1159 *$1 += " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +00001160 $2.destroy(); $4.destroy(); delete $5; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001161 $$ = $1;
1162 }
1163 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001164 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001165 if (!$3->empty())
1166 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001167 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001168 $$ = $1;
1169 }
1170 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001171 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001172 if (!$6->empty())
1173 *$1 += " " + *$6;
Reid Spencere77e35e2006-12-01 20:26:20 +00001174 $2.destroy(); $4.destroy(); delete $5; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001175 $$ = $1;
1176 }
1177 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001178 *$1 += " " + *$2.val;
1179 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001180 $$ = $1;
1181 }
1182 | OptVolatile LOAD Types ValueRef {
1183 if (!$1->empty())
1184 *$1 += " ";
Reid Spencere77e35e2006-12-01 20:26:20 +00001185 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1186 delete $2; $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001187 $$ = $1;
1188 }
1189 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1190 if (!$1->empty())
1191 *$1 += " ";
Reid Spencere77e35e2006-12-01 20:26:20 +00001192 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1193 delete $2; $3.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001194 $$ = $1;
1195 }
1196 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencera50d5962006-12-02 04:11:07 +00001197 *$1 += " " + *$2.newTy + " " + *$3 + " " + *$4;
Reid Spencere77e35e2006-12-01 20:26:20 +00001198 $2.destroy(); delete $3; delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001199 $$ = $1;
1200 };
1201
1202%%
1203
1204int yyerror(const char *ErrorMsg) {
1205 std::string where
1206 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1207 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1208 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1209 if (yychar == YYEMPTY || yychar == 0)
1210 errMsg += "end-of-file.";
1211 else
1212 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1213 std::cerr << errMsg << '\n';
1214 exit(1);
1215}