blob: 4add8fb44793febd84c7b3dcb9548d7e8323a09c [file] [log] [blame]
Reid Spencere7c3c602006-11-30 06:36:44 +00001//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This header file defines the variables that are shared between the lexer,
11// the parser, and the main program.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef PARSER_INTERNALS_H
16#define PARSER_INTERNALS_H
17
Reid Spencer2b8036e2007-01-02 05:44:33 +000018#include <llvm/ADT/StringExtras.h>
Reid Spencere7c3c602006-11-30 06:36:44 +000019#include <string>
Reid Spencer96839be2006-11-30 16:50:26 +000020#include <istream>
Reid Spencerf8483652006-12-02 15:16:01 +000021#include <vector>
Reid Spencer2b8036e2007-01-02 05:44:33 +000022#include <cassert>
Reid Spencere7c3c602006-11-30 06:36:44 +000023
24// Global variables exported from the lexer...
25
26extern std::string CurFileName;
27extern std::string Textin;
28extern int Upgradelineno;
Reid Spencer96839be2006-11-30 16:50:26 +000029extern std::istream* LexInput;
Reid Spencere7c3c602006-11-30 06:36:44 +000030
Reid Spencer2b8036e2007-01-02 05:44:33 +000031struct TypeInfo;
32typedef std::vector<TypeInfo*> TypeList;
Reid Spencere7c3c602006-11-30 06:36:44 +000033
Reid Spencere77e35e2006-12-01 20:26:20 +000034void UpgradeAssembly(
Reid Spencer71d2ec92006-12-31 06:02:26 +000035 const std::string & infile, std::istream& in, std::ostream &out, bool debug,
36 bool addAttrs);
Reid Spencere7c3c602006-11-30 06:36:44 +000037
Reid Spencer2b8036e2007-01-02 05:44:33 +000038TypeInfo* ResolveType(TypeInfo*& Ty);
39
Reid Spencere7c3c602006-11-30 06:36:44 +000040// Globals exported by the parser...
41extern char* Upgradetext;
42extern int Upgradeleng;
Reid Spencere77e35e2006-12-01 20:26:20 +000043extern unsigned SizeOfPointer;
Reid Spencere7c3c602006-11-30 06:36:44 +000044
45int yyerror(const char *ErrorMsg) ;
46
Reid Spencere77e35e2006-12-01 20:26:20 +000047/// This enum is used to keep track of the original (1.9) type used to form
48/// a type. These are needed for type upgrades and to determine how to upgrade
49/// signed instructions with signless operands.
50enum Types {
51 BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy,
Reid Spencer71d2ec92006-12-31 06:02:26 +000052 FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy,
Reid Spencer7596fd02007-01-03 23:45:17 +000053 OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy
Reid Spencere77e35e2006-12-01 20:26:20 +000054};
55
Reid Spencer2b8036e2007-01-02 05:44:33 +000056/// This type is used to keep track of the signedness of values. Instead
57/// of creating llvm::Value directly, the parser will create ValueInfo which
58/// associates a Value* with a Signedness indication.
59struct ValueInfo {
60 std::string* val;
61 TypeInfo* type;
62 bool constant;
63 bool isConstant() const { return constant; }
64 inline void destroy();
65};
66
Reid Spencere77e35e2006-12-01 20:26:20 +000067/// This type is used to keep track of the signedness of the obsolete
68/// integer types. Instead of creating an llvm::Type directly, the Lexer will
69/// create instances of TypeInfo which retains the signedness indication so
70/// it can be used by the parser for upgrade decisions.
71/// For example if "uint" is encountered then the "first" field will be set
72/// to "int32" and the "second" field will be set to "isUnsigned". If the
73/// type is not obsolete then "second" will be set to "isSignless".
74struct TypeInfo {
Reid Spencer2b8036e2007-01-02 05:44:33 +000075 TypeInfo()
76 : newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0),
77 nelems(0) {
Reid Spencer999b2df2006-12-05 19:18:29 +000078 }
79
Reid Spencer2b8036e2007-01-02 05:44:33 +000080 TypeInfo(const char * newType, Types oldType)
81 : newTy(0), oldTy(oldType), elemTy(0), resultTy(0), elements(0), nelems(0) {
82 newTy = new std::string(newType);
83 }
Reid Spencera8ca0902006-12-02 20:19:56 +000084
Reid Spencer2b8036e2007-01-02 05:44:33 +000085 TypeInfo(std::string *newType, Types oldType, TypeInfo* eTy = 0,
86 TypeInfo *rTy = 0)
87 : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(rTy), elements(0),
88 nelems(0) {
89 }
90
91 TypeInfo(std::string *newType, Types oldType, TypeInfo *eTy, uint64_t elems)
92 : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(0), elements(0),
93 nelems(elems) {
94 }
95
96 TypeInfo(std::string *newType, Types oldType, TypeList* TL)
97 : newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL),
98 nelems(0) {
99 }
100
101 TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL)
102 : newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy),
103 elements(TL), nelems(0) {
104 }
105
106 TypeInfo(const TypeInfo& that)
107 : newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0),
108 nelems(0) {
109 *this = that;
110 }
111
112 TypeInfo& operator=(const TypeInfo& that) {
113 oldTy = that.oldTy;
114 nelems = that.nelems;
115 if (that.newTy)
116 newTy = new std::string(*that.newTy);
117 if (that.elemTy)
118 elemTy = that.elemTy->clone();
119 if (that.resultTy)
120 resultTy = that.resultTy->clone();
121 if (that.elements) {
122 elements = new std::vector<TypeInfo*>(that.elements->size());
123 *elements = *that.elements;
124 }
125 return *this;
126 }
127
128 ~TypeInfo() {
129 delete newTy; delete elemTy; delete resultTy; delete elements;
130 }
131
132 TypeInfo* clone() const {
133 return new TypeInfo(*this);
134 }
135
136 Types getElementTy() const {
137 if (elemTy) {
138 return elemTy->oldTy;
139 }
140 return UnresolvedTy;
141 }
142
143 const std::string& getNewTy() const { return *newTy; }
144 void setOldTy(Types Ty) { oldTy = Ty; }
145
146 TypeInfo* getResultType() const { return resultTy; }
147 TypeInfo* getElementType() const { return elemTy; }
148
149 TypeInfo* getPointerType() const {
150 std::string* ty = new std::string(*newTy + "*");
151 return new TypeInfo(ty, PointerTy, this->clone(), (TypeInfo*)0);
152 }
153
154 bool isUnresolved() const { return oldTy == UnresolvedTy; }
Reid Spencer7596fd02007-01-03 23:45:17 +0000155 bool isUpReference() const { return oldTy == UpRefTy; }
Reid Spencer2b8036e2007-01-02 05:44:33 +0000156 bool isVoid() const { return oldTy == VoidTy; }
157 bool isBool() const { return oldTy == BoolTy; }
Reid Spencera50d5962006-12-02 04:11:07 +0000158 bool isSigned() const {
Reid Spencere77e35e2006-12-01 20:26:20 +0000159 return oldTy == SByteTy || oldTy == ShortTy ||
160 oldTy == IntTy || oldTy == LongTy;
161 }
162
Reid Spencera50d5962006-12-02 04:11:07 +0000163 bool isUnsigned() const {
Reid Spencere77e35e2006-12-01 20:26:20 +0000164 return oldTy == UByteTy || oldTy == UShortTy ||
165 oldTy == UIntTy || oldTy == ULongTy;
166 }
167
Reid Spencer49aeed72006-12-06 06:25:22 +0000168
Reid Spencera50d5962006-12-02 04:11:07 +0000169 bool isSignless() const { return !isSigned() && !isUnsigned(); }
170 bool isInteger() const { return isSigned() || isUnsigned(); }
171 bool isIntegral() const { return oldTy == BoolTy || isInteger(); }
172 bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; }
173 bool isPacked() const { return oldTy == PackedTy; }
174 bool isPointer() const { return oldTy == PointerTy; }
Reid Spencer2b8036e2007-01-02 05:44:33 +0000175 bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; }
176 bool isArray() const { return oldTy == ArrayTy; }
Reid Spencera50d5962006-12-02 04:11:07 +0000177 bool isOther() const {
178 return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); }
Reid Spencer2b8036e2007-01-02 05:44:33 +0000179 bool isFunction() const { return oldTy == FunctionTy; }
180 bool isComposite() const {
181 return isStruct() || isPointer() || isArray() || isPacked();
182 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000183
Reid Spencer71d2ec92006-12-31 06:02:26 +0000184 bool isAttributeCandidate() const {
185 return isIntegral() && getBitWidth() < 32;
186 }
187
Reid Spencera50d5962006-12-02 04:11:07 +0000188 unsigned getBitWidth() const {
Reid Spencere77e35e2006-12-01 20:26:20 +0000189 switch (oldTy) {
Reid Spencer2b8036e2007-01-02 05:44:33 +0000190 default:
Reid Spencere77e35e2006-12-01 20:26:20 +0000191 case LabelTy:
192 case VoidTy : return 0;
193 case BoolTy : return 1;
194 case SByteTy: case UByteTy : return 8;
195 case ShortTy: case UShortTy : return 16;
196 case IntTy: case UIntTy: case FloatTy: return 32;
197 case LongTy: case ULongTy: case DoubleTy : return 64;
198 case PointerTy: return SizeOfPointer; // global var
Reid Spencer2b8036e2007-01-02 05:44:33 +0000199 case PackedTy:
200 case ArrayTy:
201 return nelems * elemTy->getBitWidth();
202 case StructTy:
203 case PackedStructTy: {
204 uint64_t size = 0;
205 for (unsigned i = 0; i < elements->size(); i++) {
206 ResolveType((*elements)[i]);
207 size += (*elements)[i]->getBitWidth();
208 }
209 return size;
210 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000211 }
212 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000213
Reid Spencer2b8036e2007-01-02 05:44:33 +0000214 TypeInfo* getIndexedType(const ValueInfo& VI) {
215 if (isStruct()) {
216 if (VI.isConstant() && VI.type->isInteger()) {
217 size_t pos = VI.val->find(' ') + 1;
218 if (pos < VI.val->size()) {
219 uint64_t idx = atoi(VI.val->substr(pos).c_str());
220 return (*elements)[idx];
221 } else {
222 yyerror("Invalid value for constant integer");
223 return 0;
224 }
225 } else {
226 yyerror("Structure requires constant index");
227 return 0;
228 }
229 }
230 if (isArray() || isPacked() || isPointer())
231 return elemTy;
232 yyerror("Invalid type for getIndexedType");
233 return 0;
234 }
235
Reid Spencer7596fd02007-01-03 23:45:17 +0000236 unsigned getNumStructElements() const {
237 return (elements ? elements->size() : 0);
238 }
239
240 TypeInfo* getElement(unsigned idx) {
241 if (elements)
242 if (idx < elements->size())
243 return (*elements)[idx];
244 return 0;
245 }
246
Reid Spencer2b8036e2007-01-02 05:44:33 +0000247private:
248 std::string* newTy;
249 Types oldTy;
250 TypeInfo *elemTy;
251 TypeInfo *resultTy;
252 TypeList *elements;
253 uint64_t nelems;
Reid Spencere77e35e2006-12-01 20:26:20 +0000254};
255
256/// This type is used to keep track of the signedness of constants.
257struct ConstInfo {
258 std::string *cnst;
Reid Spencer2b8036e2007-01-02 05:44:33 +0000259 TypeInfo *type;
Reid Spencer7596fd02007-01-03 23:45:17 +0000260 void destroy() { delete cnst; }
Reid Spencere77e35e2006-12-01 20:26:20 +0000261};
262
Reid Spencerf8483652006-12-02 15:16:01 +0000263typedef std::vector<ValueInfo> ValueList;
264
Reid Spencer7596fd02007-01-03 23:45:17 +0000265inline void ValueInfo::destroy() { delete val; }
Reid Spencerf8483652006-12-02 15:16:01 +0000266
Reid Spencere7c3c602006-11-30 06:36:44 +0000267#endif