Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1 | //===-- 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 Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 18 | #include <llvm/ADT/StringExtras.h> |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 19 | #include <string> |
Reid Spencer | 96839be | 2006-11-30 16:50:26 +0000 | [diff] [blame] | 20 | #include <istream> |
Reid Spencer | f848365 | 2006-12-02 15:16:01 +0000 | [diff] [blame] | 21 | #include <vector> |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 22 | #include <cassert> |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 23 | |
| 24 | // Global variables exported from the lexer... |
| 25 | |
| 26 | extern std::string CurFileName; |
| 27 | extern std::string Textin; |
| 28 | extern int Upgradelineno; |
Reid Spencer | 96839be | 2006-11-30 16:50:26 +0000 | [diff] [blame] | 29 | extern std::istream* LexInput; |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 30 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 31 | struct TypeInfo; |
| 32 | typedef std::vector<TypeInfo*> TypeList; |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 33 | |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 34 | void UpgradeAssembly( |
Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 35 | const std::string & infile, std::istream& in, std::ostream &out, bool debug, |
| 36 | bool addAttrs); |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 37 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 38 | TypeInfo* ResolveType(TypeInfo*& Ty); |
| 39 | |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 40 | // Globals exported by the parser... |
| 41 | extern char* Upgradetext; |
| 42 | extern int Upgradeleng; |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 43 | extern unsigned SizeOfPointer; |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 44 | |
| 45 | int yyerror(const char *ErrorMsg) ; |
| 46 | |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 47 | /// 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. |
| 50 | enum Types { |
| 51 | BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy, |
Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 52 | FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy, |
Reid Spencer | 7596fd0 | 2007-01-03 23:45:17 +0000 | [diff] [blame] | 53 | OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 54 | }; |
| 55 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 56 | /// 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. |
| 59 | struct ValueInfo { |
| 60 | std::string* val; |
| 61 | TypeInfo* type; |
| 62 | bool constant; |
| 63 | bool isConstant() const { return constant; } |
| 64 | inline void destroy(); |
| 65 | }; |
| 66 | |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 67 | /// 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". |
| 74 | struct TypeInfo { |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 75 | TypeInfo() |
| 76 | : newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0), |
| 77 | nelems(0) { |
Reid Spencer | 999b2df | 2006-12-05 19:18:29 +0000 | [diff] [blame] | 78 | } |
| 79 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 80 | 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 Spencer | a8ca090 | 2006-12-02 20:19:56 +0000 | [diff] [blame] | 84 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 85 | 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 Spencer | 7596fd0 | 2007-01-03 23:45:17 +0000 | [diff] [blame] | 155 | bool isUpReference() const { return oldTy == UpRefTy; } |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 156 | bool isVoid() const { return oldTy == VoidTy; } |
| 157 | bool isBool() const { return oldTy == BoolTy; } |
Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 158 | bool isSigned() const { |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 159 | return oldTy == SByteTy || oldTy == ShortTy || |
| 160 | oldTy == IntTy || oldTy == LongTy; |
| 161 | } |
| 162 | |
Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 163 | bool isUnsigned() const { |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 164 | return oldTy == UByteTy || oldTy == UShortTy || |
| 165 | oldTy == UIntTy || oldTy == ULongTy; |
| 166 | } |
| 167 | |
Reid Spencer | 49aeed7 | 2006-12-06 06:25:22 +0000 | [diff] [blame] | 168 | |
Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 169 | 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 Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 175 | bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; } |
| 176 | bool isArray() const { return oldTy == ArrayTy; } |
Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 177 | bool isOther() const { |
| 178 | return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); } |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 179 | bool isFunction() const { return oldTy == FunctionTy; } |
| 180 | bool isComposite() const { |
| 181 | return isStruct() || isPointer() || isArray() || isPacked(); |
| 182 | } |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 183 | |
Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 184 | bool isAttributeCandidate() const { |
| 185 | return isIntegral() && getBitWidth() < 32; |
| 186 | } |
| 187 | |
Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 188 | unsigned getBitWidth() const { |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 189 | switch (oldTy) { |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 190 | default: |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 191 | 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 Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 199 | 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 Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 211 | } |
| 212 | } |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 213 | |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 214 | 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 Spencer | 7596fd0 | 2007-01-03 23:45:17 +0000 | [diff] [blame] | 236 | 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 Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 247 | private: |
| 248 | std::string* newTy; |
| 249 | Types oldTy; |
| 250 | TypeInfo *elemTy; |
| 251 | TypeInfo *resultTy; |
| 252 | TypeList *elements; |
| 253 | uint64_t nelems; |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 254 | }; |
| 255 | |
| 256 | /// This type is used to keep track of the signedness of constants. |
| 257 | struct ConstInfo { |
| 258 | std::string *cnst; |
Reid Spencer | 2b8036e | 2007-01-02 05:44:33 +0000 | [diff] [blame] | 259 | TypeInfo *type; |
Reid Spencer | 7596fd0 | 2007-01-03 23:45:17 +0000 | [diff] [blame] | 260 | void destroy() { delete cnst; } |
Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 261 | }; |
| 262 | |
Reid Spencer | f848365 | 2006-12-02 15:16:01 +0000 | [diff] [blame] | 263 | typedef std::vector<ValueInfo> ValueList; |
| 264 | |
Reid Spencer | 7596fd0 | 2007-01-03 23:45:17 +0000 | [diff] [blame] | 265 | inline void ValueInfo::destroy() { delete val; } |
Reid Spencer | f848365 | 2006-12-02 15:16:01 +0000 | [diff] [blame] | 266 | |
Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 267 | #endif |