199e5cfbb2381ff99e928bfc20b6e64214631ea5
[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 is distributed under the University of Illinois Open Source
6 // 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     APFloat *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(APFloat* 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->compare(*V.ConstPoolFP) ==
275                                APFloat::cmpLessThan;
276     case ConstNullVal:  return false;
277     case ConstUndefVal: return false;
278     case ConstZeroVal: return false;
279     case ConstantVal:   return ConstantValue < V.ConstantValue;
280     default:  assert(0 && "Unknown value type!"); return false;
281     }
282   }
283 };
284
285 /// The following enums are used to keep track of prior opcodes. The lexer will
286 /// retain the ability to parse obsolete opcode mnemonics and generates semantic
287 /// values containing one of these enumerators.
288 enum TermOps {
289   RetOp, BrOp, SwitchOp, InvokeOp, UnwindOp, UnreachableOp
290 };
291
292 enum BinaryOps {
293   AddOp, SubOp, MulOp,
294   DivOp, UDivOp, SDivOp, FDivOp, 
295   RemOp, URemOp, SRemOp, FRemOp, 
296   AndOp, OrOp, XorOp,
297   ShlOp, ShrOp, LShrOp, AShrOp,
298   SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT
299 };
300
301 enum MemoryOps {
302   MallocOp, FreeOp, AllocaOp, LoadOp, StoreOp, GetElementPtrOp
303 };
304
305 enum OtherOps {
306   PHIOp, CallOp, SelectOp, UserOp1, UserOp2, VAArg,
307   ExtractElementOp, InsertElementOp, ShuffleVectorOp,
308   ICmpOp, FCmpOp
309 };
310
311 enum CastOps {
312   CastOp, TruncOp, ZExtOp, SExtOp, FPTruncOp, FPExtOp, FPToUIOp, FPToSIOp,
313   UIToFPOp, SIToFPOp, PtrToIntOp, IntToPtrOp, BitCastOp
314 };
315
316 // An enumeration for the old calling conventions, ala LLVM 1.9
317 namespace OldCallingConv {
318   enum ID {
319     C = 0, CSRet = 1, Fast = 8, Cold = 9, X86_StdCall = 64, X86_FastCall = 65,
320     None = 99999
321   };
322 }
323
324 /// These structures are used as the semantic values returned from various
325 /// productions in the grammar. They simply bundle an LLVM IR object with
326 /// its Signedness value. These help track signedness through the various
327 /// productions. 
328 struct TypeInfo {
329   const llvm::Type *T;
330   Signedness S;
331   bool operator<(const TypeInfo& that) const {
332     if (this == &that)
333       return false;
334     if (T < that.T)
335       return true;
336     if (T == that.T) {
337       bool result = S < that.S;
338 //#define TYPEINFO_DEBUG
339 #ifdef TYPEINFO_DEBUG
340       std::cerr << (result?"true  ":"false ") << T->getDescription() << " (";
341       S.dump();
342       std::cerr << ") < " << that.T->getDescription() << " (";
343       that.S.dump();
344       std::cerr << ")\n";
345 #endif
346       return result;
347     }
348     return false;
349   }
350   bool operator==(const TypeInfo& that) const {
351     if (this == &that)
352       return true;
353     return T == that.T && S == that.S;
354   }
355   void destroy() { S.destroy(); }
356 };
357
358 struct PATypeInfo {
359   llvm::PATypeHolder* PAT;
360   Signedness S;
361   void destroy() { S.destroy(); delete PAT; }
362 };
363
364 struct ConstInfo {
365   llvm::Constant* C;
366   Signedness S;
367   void destroy() { S.destroy(); }
368 };
369
370 struct ValueInfo {
371   llvm::Value* V;
372   Signedness S;
373   void destroy() { S.destroy(); }
374 };
375
376 struct InstrInfo {
377   llvm::Instruction *I;
378   Signedness S;
379   void destroy() { S.destroy(); }
380 };
381
382 struct TermInstInfo {
383   llvm::TerminatorInst *TI;
384   Signedness S;
385   void destroy() { S.destroy(); }
386 };
387
388 struct PHIListInfo {
389   std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *P;
390   Signedness S;
391   void destroy() { S.destroy(); delete P; }
392 };
393
394 } // End llvm namespace
395
396 #endif