blob: 0e0040079604209062b3fcaa913b38b620a336f7 [file] [log] [blame]
Reid Spencerefd53d52007-01-26 08:18:34 +00001//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
Reid Spencer90eb4d62007-01-05 17:18:58 +00002//
3// The LLVM Compiler Infrastructure
4//
Reid Spencerefd53d52007-01-26 08:18:34 +00005// This file was developed by the LLVM research group and is distributed under
Reid Spencer90eb4d62007-01-05 17:18:58 +00006// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Reid Spencerefd53d52007-01-26 08:18:34 +000010// This header file defines the various variables that are shared among the
11// different components of the parser...
Reid Spencer90eb4d62007-01-05 17:18:58 +000012//
13//===----------------------------------------------------------------------===//
14
Reid Spencerefd53d52007-01-26 08:18:34 +000015#ifndef PARSER_INTERNALS_H
16#define PARSER_INTERNALS_H
Reid Spencer90eb4d62007-01-05 17:18:58 +000017
Reid Spencerefd53d52007-01-26 08:18:34 +000018#include "llvm/Constants.h"
19#include "llvm/DerivedTypes.h"
20#include "llvm/Function.h"
21#include "llvm/Instructions.h"
22#include "llvm/ADT/StringExtras.h"
23#include <list>
Reid Spencer3e5affd2007-03-21 17:14:36 +000024#include <iostream>
Reid Spencerefd53d52007-01-26 08:18:34 +000025
Reid Spencer90eb4d62007-01-05 17:18:58 +000026
Reid Spencere0a15bb2007-01-15 00:25:53 +000027// Global variables exported from the lexer.
Reid Spencerefd53d52007-01-26 08:18:34 +000028extern int yydebug;
29extern void error(const std::string& msg, int line = -1);
Reid Spencer90eb4d62007-01-05 17:18:58 +000030extern char* Upgradetext;
31extern int Upgradeleng;
Reid Spencerefd53d52007-01-26 08:18:34 +000032extern int Upgradelineno;
Reid Spencer90eb4d62007-01-05 17:18:58 +000033
Reid Spencerefd53d52007-01-26 08:18:34 +000034namespace llvm {
Reid Spencer90eb4d62007-01-05 17:18:58 +000035
Reid Spencerefd53d52007-01-26 08:18:34 +000036class Module;
37Module* UpgradeAssembly(const std::string &infile, std::istream& in,
38 bool debug, bool addAttrs);
39
Reid Spencerefd53d52007-01-26 08:18:34 +000040extern std::istream* LexInput;
Reid Spencer90eb4d62007-01-05 17:18:58 +000041
Reid Spencerefd53d52007-01-26 08:18:34 +000042// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
43// appropriate character. If AllowNull is set to false, a \00 value will cause
44// an error.
45//
46// If AllowNull is set to true, the return value of the function points to the
47// last character of the string in memory.
48//
49char *UnEscapeLexed(char *Buffer, bool AllowNull = false);
Reid Spencer90eb4d62007-01-05 17:18:58 +000050
Reid Spencerefd53d52007-01-26 08:18:34 +000051/// InlineAsmDescriptor - This is a simple class that holds info about inline
52/// asm blocks, for use by ValID.
53struct InlineAsmDescriptor {
54 std::string AsmString, Constraints;
55 bool HasSideEffects;
56
57 InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE)
58 : AsmString(as), Constraints(c), HasSideEffects(HSE) {}
59};
60
Reid Spencer3e5affd2007-03-21 17:14:36 +000061/// This class keeps track of the signedness of a type or value. It allows the
62/// signedness of a composite type to be captured in a relatively simple form.
63/// This is needed in order to retain the signedness of pre LLVM 2.0 types so
64/// they can be upgraded properly. Signedness of composite types must be
65/// captured in order to accurately get the signedness of a value through a
66/// GEP instruction.
67/// @brief Class to track signedness of types and values.
68struct Signedness {
69 /// The basic kinds of signedness values.
70 enum Kind {
71 Signless, ///< The type doesn't have any sign.
72 Unsigned, ///< The type is an unsigned integer.
73 Signed, ///< The type is a signed integer.
74 Named, ///< The type is a named type (probably forward ref or up ref).
75 Composite ///< The type is composite (struct, array, pointer).
76 };
77
78private:
79 /// @brief Keeps track of Signedness for composite types
80 typedef std::vector<Signedness> SignVector;
81 Kind kind; ///< The kind of signedness node
82 union {
83 SignVector *sv; ///< The vector of Signedness for composite types
84 std::string *name; ///< The name of the type for named types.
85 };
86public:
87 /// The Signedness class is used as a member of a union so it cannot have
88 /// a constructor or assignment operator. This function suffices.
89 /// @brief Copy one signedness value to another
90 void copy(const Signedness &that);
91 /// The Signedness class is used as a member of a union so it cannot have
92 /// a destructor.
93 /// @brief Release memory, if any allocated.
94 void destroy();
95
96 /// @brief Make a Signless node.
97 void makeSignless() { kind = Signless; sv = 0; }
98 /// @brief Make a Signed node.
99 void makeSigned() { kind = Signed; sv = 0; }
100 /// @brief Make an Unsigned node.
101 void makeUnsigned() { kind = Unsigned; sv = 0; }
102 /// @brief Make a Named node.
103 void makeNamed(const std::string& nm){
104 kind = Named; name = new std::string(nm);
105 }
106 /// @brief Make an empty Composite node.
107 void makeComposite() { kind = Composite; sv = new SignVector(); }
108 /// @brief Make an Composite node, with the first element given.
109 void makeComposite(const Signedness &S) {
110 kind = Composite;
111 sv = new SignVector();
112 sv->push_back(S);
113 }
114 /// @brief Add an element to a Composite node.
115 void add(const Signedness &S) {
116 assert(isComposite() && "Must be composite to use add");
117 sv->push_back(S);
118 }
119 bool operator<(const Signedness &that) const;
120 bool operator==(const Signedness &that) const;
121 bool isSigned() const { return kind == Signed; }
122 bool isUnsigned() const { return kind == Unsigned; }
123 bool isSignless() const { return kind == Signless; }
124 bool isNamed() const { return kind == Named; }
125 bool isComposite() const { return kind == Composite; }
126 /// This is used by GetElementPtr to extract the sign of an element.
127 /// @brief Get a specific element from a Composite node.
128 Signedness get(uint64_t idx) const {
129 assert(isComposite() && "Invalid Signedness type for get()");
130 assert(sv && idx < sv->size() && "Invalid index");
131 return (*sv)[idx];
132 }
133 /// @brief Get the name from a Named node.
134 const std::string& getName() const {
135 assert(isNamed() && "Can't get name from non-name Sign");
136 return *name;
137 }
138#ifndef NDEBUG
139 void dump() const;
140#endif
141};
142
Reid Spencerefd53d52007-01-26 08:18:34 +0000143
144// ValID - Represents a reference of a definition of some sort. This may either
145// be a numeric reference or a symbolic (%var) reference. This is just a
146// discriminated union.
147//
148// Note that I can't implement this class in a straight forward manner with
149// constructors and stuff because it goes in a union.
150//
151struct ValID {
152 enum {
153 NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal,
154 ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal
155 } Type;
156
157 union {
158 int Num; // If it's a numeric reference
159 char *Name; // If it's a named reference. Memory must be free'd.
160 int64_t ConstPool64; // Constant pool reference. This is the value
161 uint64_t UConstPool64;// Unsigned constant pool reference.
162 double ConstPoolFP; // Floating point constant pool reference
163 Constant *ConstantValue; // Fully resolved constant for ConstantVal case.
164 InlineAsmDescriptor *IAD;
165 };
Reid Spencer3e5affd2007-03-21 17:14:36 +0000166 Signedness S;
Reid Spencerefd53d52007-01-26 08:18:34 +0000167
Reid Spencer44f87ee2007-03-15 03:25:34 +0000168 static ValID create(int Num) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000169 ValID D; D.Type = NumberVal; D.Num = Num; D.S.makeSignless();
170 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000171 }
172
Reid Spencer44f87ee2007-03-15 03:25:34 +0000173 static ValID create(char *Name) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000174 ValID D; D.Type = NameVal; D.Name = Name; D.S.makeSignless();
175 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000176 }
177
178 static ValID create(int64_t Val) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000179 ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val;
180 D.S.makeSigned();
181 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000182 }
183
184 static ValID create(uint64_t Val) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000185 ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val;
186 D.S.makeUnsigned();
187 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000188 }
189
190 static ValID create(double Val) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000191 ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val;
192 D.S.makeSignless();
193 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000194 }
195
196 static ValID createNull() {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000197 ValID D; D.Type = ConstNullVal;
198 D.S.makeSignless();
199 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000200 }
201
202 static ValID createUndef() {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000203 ValID D; D.Type = ConstUndefVal;
204 D.S.makeSignless();
205 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000206 }
207
208 static ValID createZeroInit() {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000209 ValID D; D.Type = ConstZeroVal;
210 D.S.makeSignless();
211 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000212 }
213
Reid Spencer44f87ee2007-03-15 03:25:34 +0000214 static ValID create(Constant *Val) {
Reid Spencer3e5affd2007-03-21 17:14:36 +0000215 ValID D; D.Type = ConstantVal; D.ConstantValue = Val;
216 D.S.makeSignless();
217 return D;
Reid Spencerefd53d52007-01-26 08:18:34 +0000218 }
219
220 static ValID createInlineAsm(const std::string &AsmString,
221 const std::string &Constraints,
222 bool HasSideEffects) {
223 ValID D;
224 D.Type = InlineAsmVal;
225 D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects);
Reid Spencer3e5affd2007-03-21 17:14:36 +0000226 D.S.makeSignless();
Reid Spencerefd53d52007-01-26 08:18:34 +0000227 return D;
228 }
229
230 inline void destroy() const {
231 if (Type == NameVal)
232 free(Name); // Free this strdup'd memory.
233 else if (Type == InlineAsmVal)
234 delete IAD;
235 }
236
237 inline ValID copy() const {
238 if (Type != NameVal) return *this;
239 ValID Result = *this;
240 Result.Name = strdup(Name);
241 return Result;
242 }
243
244 inline std::string getName() const {
245 switch (Type) {
246 case NumberVal : return std::string("#") + itostr(Num);
247 case NameVal : return Name;
248 case ConstFPVal : return ftostr(ConstPoolFP);
249 case ConstNullVal : return "null";
250 case ConstUndefVal : return "undef";
251 case ConstZeroVal : return "zeroinitializer";
252 case ConstUIntVal :
253 case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
254 case ConstantVal:
255 if (ConstantValue == ConstantInt::get(Type::Int1Ty, true))
256 return "true";
257 if (ConstantValue == ConstantInt::get(Type::Int1Ty, false))
258 return "false";
259 return "<constant expression>";
260 default:
261 assert(0 && "Unknown value!");
262 abort();
263 return "";
264 }
265 }
266
267 bool operator<(const ValID &V) const {
268 if (Type != V.Type) return Type < V.Type;
269 switch (Type) {
270 case NumberVal: return Num < V.Num;
271 case NameVal: return strcmp(Name, V.Name) < 0;
272 case ConstSIntVal: return ConstPool64 < V.ConstPool64;
273 case ConstUIntVal: return UConstPool64 < V.UConstPool64;
274 case ConstFPVal: return ConstPoolFP < V.ConstPoolFP;
275 case ConstNullVal: return false;
276 case ConstUndefVal: return false;
277 case ConstZeroVal: return false;
278 case ConstantVal: return ConstantValue < V.ConstantValue;
279 default: assert(0 && "Unknown value type!"); return false;
280 }
281 }
282};
283
Reid Spencer9373d272007-01-26 17:13:53 +0000284/// The following enums are used to keep track of prior opcodes. The lexer will
285/// retain the ability to parse obsolete opcode mnemonics and generates semantic
286/// values containing one of these enumerators.
Reid Spencerefd53d52007-01-26 08:18:34 +0000287enum TermOps {
288 RetOp, BrOp, SwitchOp, InvokeOp, UnwindOp, UnreachableOp
289};
290
291enum BinaryOps {
292 AddOp, SubOp, MulOp,
293 DivOp, UDivOp, SDivOp, FDivOp,
294 RemOp, URemOp, SRemOp, FRemOp,
295 AndOp, OrOp, XorOp,
Reid Spencer832254e2007-02-02 02:16:23 +0000296 ShlOp, ShrOp, LShrOp, AShrOp,
Reid Spencerefd53d52007-01-26 08:18:34 +0000297 SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT
298};
299
300enum MemoryOps {
301 MallocOp, FreeOp, AllocaOp, LoadOp, StoreOp, GetElementPtrOp
302};
303
304enum OtherOps {
Reid Spencer832254e2007-02-02 02:16:23 +0000305 PHIOp, CallOp, SelectOp, UserOp1, UserOp2, VAArg,
Reid Spencerefd53d52007-01-26 08:18:34 +0000306 ExtractElementOp, InsertElementOp, ShuffleVectorOp,
Reid Spencer832254e2007-02-02 02:16:23 +0000307 ICmpOp, FCmpOp
Reid Spencerefd53d52007-01-26 08:18:34 +0000308};
309
310enum CastOps {
311 CastOp, TruncOp, ZExtOp, SExtOp, FPTruncOp, FPExtOp, FPToUIOp, FPToSIOp,
312 UIToFPOp, SIToFPOp, PtrToIntOp, IntToPtrOp, BitCastOp
313};
314
Reid Spencer43f76c92007-01-29 05:41:09 +0000315// An enumeration for the old calling conventions, ala LLVM 1.9
316namespace OldCallingConv {
317 enum ID {
Reid Spencer2dcb5832007-02-08 09:08:23 +0000318 C = 0, CSRet = 1, Fast = 8, Cold = 9, X86_StdCall = 64, X86_FastCall = 65,
319 None = 99999
Reid Spencer43f76c92007-01-29 05:41:09 +0000320 };
321}
322
Reid Spencer9373d272007-01-26 17:13:53 +0000323/// These structures are used as the semantic values returned from various
324/// productions in the grammar. They simply bundle an LLVM IR object with
325/// its Signedness value. These help track signedness through the various
326/// productions.
Reid Spencerefd53d52007-01-26 08:18:34 +0000327struct TypeInfo {
328 const llvm::Type *T;
329 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000330 bool operator<(const TypeInfo& that) const {
331 if (this == &that)
332 return false;
333 if (T < that.T)
334 return true;
335 if (T == that.T) {
336 bool result = S < that.S;
337//#define TYPEINFO_DEBUG
338#ifdef TYPEINFO_DEBUG
339 std::cerr << (result?"true ":"false ") << T->getDescription() << " (";
340 S.dump();
341 std::cerr << ") < " << that.T->getDescription() << " (";
342 that.S.dump();
343 std::cerr << ")\n";
344#endif
345 return result;
346 }
347 return false;
348 }
349 bool operator==(const TypeInfo& that) const {
350 if (this == &that)
351 return true;
352 return T == that.T && S == that.S;
353 }
354 void destroy() { S.destroy(); }
Reid Spencerefd53d52007-01-26 08:18:34 +0000355};
356
357struct PATypeInfo {
Reid Spencer2dcb5832007-02-08 09:08:23 +0000358 llvm::PATypeHolder* PAT;
Reid Spencerefd53d52007-01-26 08:18:34 +0000359 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000360 void destroy() { S.destroy(); delete PAT; }
Reid Spencerefd53d52007-01-26 08:18:34 +0000361};
362
363struct ConstInfo {
364 llvm::Constant* C;
365 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000366 void destroy() { S.destroy(); }
Reid Spencerefd53d52007-01-26 08:18:34 +0000367};
368
369struct ValueInfo {
370 llvm::Value* V;
371 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000372 void destroy() { S.destroy(); }
Reid Spencerefd53d52007-01-26 08:18:34 +0000373};
374
375struct InstrInfo {
376 llvm::Instruction *I;
377 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000378 void destroy() { S.destroy(); }
379};
380
381struct TermInstInfo {
382 llvm::TerminatorInst *TI;
383 Signedness S;
384 void destroy() { S.destroy(); }
Reid Spencerefd53d52007-01-26 08:18:34 +0000385};
386
387struct PHIListInfo {
388 std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *P;
389 Signedness S;
Reid Spencer3e5affd2007-03-21 17:14:36 +0000390 void destroy() { S.destroy(); delete P; }
Reid Spencerefd53d52007-01-26 08:18:34 +0000391};
392
393} // End llvm namespace
Reid Spencer90eb4d62007-01-05 17:18:58 +0000394
395#endif