fit in 80 cols
[oota-llvm.git] / tools / llvm-upgrade / UpgradeInternals.h
1 //===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group 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 various variables that are shared among the
11 //  different components of the parser...
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef PARSER_INTERNALS_H
16 #define PARSER_INTERNALS_H
17
18 #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>
24 #include <iostream>
25
26
27 // Global variables exported from the lexer.
28 extern int yydebug;
29 extern void error(const std::string& msg, int line = -1);
30 extern char* Upgradetext;
31 extern int   Upgradeleng;
32 extern int Upgradelineno;
33
34 namespace llvm {
35
36 class Module;
37 Module* UpgradeAssembly(const std::string &infile, std::istream& in, 
38                         bool debug, bool addAttrs);
39
40 extern std::istream* LexInput;
41
42 // 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 //
49 char *UnEscapeLexed(char *Buffer, bool AllowNull = false);
50
51 /// InlineAsmDescriptor - This is a simple class that holds info about inline
52 /// asm blocks, for use by ValID.
53 struct 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
61 /// 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.
68 struct 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
78 private:
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   };
86 public:
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
143
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 //
151 struct 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   };
166   Signedness S;
167
168   static ValID create(int Num) {
169     ValID D; D.Type = NumberVal; D.Num = Num; D.S.makeSignless();
170     return D;
171   }
172
173   static ValID create(char *Name) {
174     ValID D; D.Type = NameVal; D.Name = Name; D.S.makeSignless();
175     return D;
176   }
177
178   static ValID create(int64_t Val) {
179     ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; 
180     D.S.makeSigned();
181     return D;
182   }
183
184   static ValID create(uint64_t Val) {
185     ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; 
186     D.S.makeUnsigned();
187     return D;
188   }
189
190   static ValID create(double Val) {
191     ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val;
192     D.S.makeSignless();
193     return D;
194   }
195
196   static ValID createNull() {
197     ValID D; D.Type = ConstNullVal;
198     D.S.makeSignless();
199     return D;
200   }
201
202   static ValID createUndef() {
203     ValID D; D.Type = ConstUndefVal;
204     D.S.makeSignless();
205     return D;
206   }
207
208   static ValID createZeroInit() {
209     ValID D; D.Type = ConstZeroVal;
210     D.S.makeSignless();
211     return D;
212   }
213   
214   static ValID create(Constant *Val) {
215     ValID D; D.Type = ConstantVal; D.ConstantValue = Val;
216     D.S.makeSignless();
217     return D;
218   }
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);
226     D.S.makeSignless();
227     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
284 /// 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.
287 enum TermOps {
288   RetOp, BrOp, SwitchOp, InvokeOp, UnwindOp, UnreachableOp
289 };
290
291 enum BinaryOps {
292   AddOp, SubOp, MulOp,
293   DivOp, UDivOp, SDivOp, FDivOp, 
294   RemOp, URemOp, SRemOp, FRemOp, 
295   AndOp, OrOp, XorOp,
296   ShlOp, ShrOp, LShrOp, AShrOp,
297   SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT
298 };
299
300 enum MemoryOps {
301   MallocOp, FreeOp, AllocaOp, LoadOp, StoreOp, GetElementPtrOp
302 };
303
304 enum OtherOps {
305   PHIOp, CallOp, SelectOp, UserOp1, UserOp2, VAArg,
306   ExtractElementOp, InsertElementOp, ShuffleVectorOp,
307   ICmpOp, FCmpOp
308 };
309
310 enum CastOps {
311   CastOp, TruncOp, ZExtOp, SExtOp, FPTruncOp, FPExtOp, FPToUIOp, FPToSIOp,
312   UIToFPOp, SIToFPOp, PtrToIntOp, IntToPtrOp, BitCastOp
313 };
314
315 // An enumeration for the old calling conventions, ala LLVM 1.9
316 namespace OldCallingConv {
317   enum ID {
318     C = 0, CSRet = 1, Fast = 8, Cold = 9, X86_StdCall = 64, X86_FastCall = 65,
319     None = 99999
320   };
321 }
322
323 /// 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. 
327 struct TypeInfo {
328   const llvm::Type *T;
329   Signedness S;
330   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(); }
355 };
356
357 struct PATypeInfo {
358   llvm::PATypeHolder* PAT;
359   Signedness S;
360   void destroy() { S.destroy(); delete PAT; }
361 };
362
363 struct ConstInfo {
364   llvm::Constant* C;
365   Signedness S;
366   void destroy() { S.destroy(); }
367 };
368
369 struct ValueInfo {
370   llvm::Value* V;
371   Signedness S;
372   void destroy() { S.destroy(); }
373 };
374
375 struct InstrInfo {
376   llvm::Instruction *I;
377   Signedness S;
378   void destroy() { S.destroy(); }
379 };
380
381 struct TermInstInfo {
382   llvm::TerminatorInst *TI;
383   Signedness S;
384   void destroy() { S.destroy(); }
385 };
386
387 struct PHIListInfo {
388   std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *P;
389   Signedness S;
390   void destroy() { S.destroy(); delete P; }
391 };
392
393 } // End llvm namespace
394
395 #endif