Add support for extern varargs methods & varargs method calls
[oota-llvm.git] / include / llvm / DerivedTypes.h
1 //===-- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*--=//
2 //
3 // This file contains the declarations of classes that represent "derived 
4 // types".  These are things like "arrays of x" or "structure of x, y, z" or
5 // "method returning x taking (y,z) as parameters", etc...
6 //
7 // The implementations of these classes live in the Type.cpp file.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef LLVM_DERIVED_TYPES_H
12 #define LLVM_DERIVED_TYPES_H
13
14 #include "llvm/Type.h"
15 #include "llvm/CodeGen/TargetMachine.h"
16 #include <vector>
17
18 // Future derived types: SIMD packed format
19
20
21 class MethodType : public Type {
22 public:
23   typedef vector<const Type*> ParamTypes;
24 private:
25   const Type *ResultType;
26   ParamTypes ParamTys;
27   bool isVarArgs;
28
29   MethodType(const MethodType &);                   // Do not implement
30   const MethodType &operator=(const MethodType &);  // Do not implement
31 protected:
32   // This should really be private, but it squelches a bogus warning
33   // from GCC to make them protected:  warning: `class MethodType' only 
34   // defines private constructors and has no friends
35
36   // Private ctor - Only can be created by a static member...
37   MethodType(const Type *Result, const vector<const Type*> &Params, 
38              bool IsVarArgs, const string &Name);
39 public:
40
41   inline bool isVarArg() const { return isVarArgs; }
42   inline const Type *getReturnType() const { return ResultType; }
43   inline const ParamTypes &getParamTypes() const { return ParamTys; }
44
45   static const MethodType *getMethodType(const Type *Result, 
46                                          const ParamTypes &Params);
47   static const MethodType *get(const Type *Result, const ParamTypes &Params) {
48     return getMethodType(Result, Params);
49   }
50 };
51
52
53 class ArrayType : public Type {
54 private:
55   const Type *ElementType;
56   int NumElements;       // >= 0 for sized array, -1 for unbounded/unknown array
57
58   ArrayType(const ArrayType &);                   // Do not implement
59   const ArrayType &operator=(const ArrayType &);  // Do not implement
60 protected:
61   // This should really be private, but it squelches a bogus warning
62   // from GCC to make them protected:  warning: `class ArrayType' only 
63   // defines private constructors and has no friends
64
65
66   // Private ctor - Only can be created by a static member...
67   ArrayType(const Type *ElType, int NumEl, const string &Name);
68 public:
69
70   inline const Type *getElementType() const { return ElementType; }
71   inline int         getNumElements() const { return NumElements; }
72
73   inline bool isSized()   const { return NumElements >= 0; }
74   inline bool isUnsized() const { return NumElements == -1; }
75
76   static const ArrayType *getArrayType(const Type *ElementType, 
77                                        int NumElements = -1);
78   static const ArrayType *get(const Type *ElementType, int NumElements = -1) {
79     return getArrayType(ElementType, NumElements);
80   }
81 };
82
83
84 class StructType : public Type {
85 public:
86   typedef vector<const Type*> ElementTypes;
87
88 private:
89   ElementTypes ETypes;
90   struct StructSizeAndOffsetInfo {
91     int storageSize;                    // -1 until the value is computd
92     vector<int> memberOffsets;          // -1 until values are computed 
93     const TargetMachine* targetInfo;
94   } *layoutCache;
95   
96 private:
97   StructType(const StructType &);                   // Do not implement
98   const StructType &operator=(const StructType &);  // Do not implement
99   
100 protected:
101   // This should really be private, but it squelches a bogus warning
102   // from GCC to make them protected:  warning: `class StructType' only 
103   // defines private constructors and has no friends
104
105   // Private ctor - Only can be created by a static member...
106   StructType(const vector<const Type*> &Types, const string &Name);
107   
108   // Reset cached info so it will be computed when first requested
109   void ResetCachedInfo() const {
110     layoutCache->storageSize = -1;
111     layoutCache->memberOffsets.insert(layoutCache->memberOffsets.begin(),
112                                       ETypes.size(), -1);
113     layoutCache->targetInfo = 0;
114   }
115   
116 public:
117   inline const ElementTypes &getElementTypes() const { return ETypes; }
118   static const StructType *getStructType(const ElementTypes &Params);
119   static const StructType *get(const ElementTypes &Params) {
120     return getStructType(Params);
121   }
122
123
124   unsigned int getStorageSize(const TargetMachine& tmi) const {
125     if (layoutCache->targetInfo && layoutCache->targetInfo != &tmi) {
126       // target machine has changed (hey it could happen). discard cached info.
127       ResetCachedInfo();
128       layoutCache->targetInfo = &tmi;
129     }
130   
131     if (layoutCache->storageSize < 0) {
132       layoutCache->storageSize = tmi.findOptimalStorageSize(this);
133       assert(layoutCache->storageSize >= 0);
134     }
135     return layoutCache->storageSize;
136   }
137   unsigned int getElementOffset(int i, const TargetMachine& tmi) const {
138     // target machine has changed (hey it could happen). discard cached info.
139     if (layoutCache->targetInfo && layoutCache->targetInfo != &tmi)
140       ResetCachedInfo();
141   
142     if (layoutCache->memberOffsets[i] < 0) {
143       layoutCache->targetInfo = &tmi;  // remember which target was used
144       
145       unsigned int *offsetVec = tmi.findOptimalMemberOffsets(this);
146       for (unsigned i=0, N=layoutCache->memberOffsets.size(); i < N; ++i) {
147         layoutCache->memberOffsets[i] = offsetVec[i];
148         assert(layoutCache->memberOffsets[i] >= 0);
149       }
150       delete[] offsetVec; 
151     }
152     
153     return layoutCache->memberOffsets[i];
154   }
155 };
156
157
158 class PointerType : public Type {
159 private:
160   const Type *ValueType;
161
162   PointerType(const PointerType &);                   // Do not implement
163   const PointerType &operator=(const PointerType &);  // Do not implement
164 protected:
165   // This should really be private, but it squelches a bogus warning
166   // from GCC to make them protected:  warning: `class PointerType' only 
167   // defines private constructors and has no friends
168
169
170   // Private ctor - Only can be created by a static member...
171   PointerType(const Type *ElType);
172 public:
173
174   inline const Type *getValueType() const { return ValueType; }
175
176
177   static const PointerType *getPointerType(const Type *ElementType);
178   static const PointerType *get(const Type *ElementType) {
179     return getPointerType(ElementType);
180   }
181 };
182
183 #endif