aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/DerivedTypes.h
blob: 405a632d359381a283257a3fffc89612295b14f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//===-- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*--=//
//
// This file contains the declarations of classes that represent "derived 
// types".  These are things like "arrays of x" or "structure of x, y, z" or
// "method returning x taking (y,z) as parameters", etc...
//
// The implementations of these classes live in the Type.cpp file.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DERIVED_TYPES_H
#define LLVM_DERIVED_TYPES_H

#include "llvm/Type.h"
#include "llvm/CodeGen/TargetMachine.h"
#include <vector>

// Future derived types: SIMD packed format


class MethodType : public Type {
public:
  typedef vector<const Type*> ParamTypes;
private:
  const Type *ResultType;
  ParamTypes ParamTys;

  MethodType(const MethodType &);                   // Do not implement
  const MethodType &operator=(const MethodType &);  // Do not implement
protected:
  // This should really be private, but it squelches a bogus warning
  // from GCC to make them protected:  warning: `class MethodType' only 
  // defines private constructors and has no friends

  // Private ctor - Only can be created by a static member...
  MethodType(const Type *Result, const vector<const Type*> &Params, 
             const string &Name);
public:

  inline const Type *getReturnType() const { return ResultType; }
  inline const ParamTypes &getParamTypes() const { return ParamTys; }

  static const MethodType *getMethodType(const Type *Result, 
                                         const ParamTypes &Params);
  static const MethodType *get(const Type *Result, const ParamTypes &Params) {
    return getMethodType(Result, Params);
  }
};



class ArrayType : public Type {
private:
  const Type *ElementType;
  int NumElements;       // >= 0 for sized array, -1 for unbounded/unknown array

  ArrayType(const ArrayType &);                   // Do not implement
  const ArrayType &operator=(const ArrayType &);  // Do not implement
protected:
  // This should really be private, but it squelches a bogus warning
  // from GCC to make them protected:  warning: `class ArrayType' only 
  // defines private constructors and has no friends


  // Private ctor - Only can be created by a static member...
  ArrayType(const Type *ElType, int NumEl, const string &Name);
public:

  inline const Type *getElementType() const { return ElementType; }
  inline int         getNumElements() const { return NumElements; }

  inline bool isSized()   const { return NumElements >= 0; }
  inline bool isUnsized() const { return NumElements == -1; }

  static const ArrayType *getArrayType(const Type *ElementType, 
				       int NumElements = -1);
  static const ArrayType *get(const Type *ElementType, int NumElements = -1) {
    return getArrayType(ElementType, NumElements);
  }
};

class StructType : public Type {
public:
  typedef vector<const Type*> ElementTypes;

private:
  ElementTypes ETypes;
  struct StructSizeAndOffsetInfo {
    int storageSize;			// -1 until the value is computd
    vector<int> memberOffsets;		// -1 until values are computed 
    const TargetMachine* targetInfo;
  }
  *layoutCache;
  
private:
  StructType(const StructType &);                   // Do not implement
  const StructType &operator=(const StructType &);  // Do not implement
  
protected:
  // This should really be private, but it squelches a bogus warning
  // from GCC to make them protected:  warning: `class StructType' only 
  // defines private constructors and has no friends

  // Private ctor - Only can be created by a static member...
  StructType(const vector<const Type*> &Types, const string &Name);
  
  // Reset cached info so it will be computed when first requested
  void ResetCachedInfo() const;
  
public:

  inline const ElementTypes &getElementTypes() const { return ETypes; }
  static const StructType *getStructType(const ElementTypes &Params);
  static const StructType *get(const ElementTypes &Params) {
    return getStructType(Params);
  }
  unsigned int		   getStorageSize(const TargetMachine& tmi) const;
  unsigned int		   getElementOffset(int i, const TargetMachine& tmi) const;
};


inline unsigned int
StructType::getStorageSize(const TargetMachine& tmi) const
{
  if (layoutCache->targetInfo != NULL && ! (* layoutCache->targetInfo == tmi))
    {// target machine has changed (hey it could happen). discard cached info.
      ResetCachedInfo();
      layoutCache->targetInfo = &tmi;
    }
  
  if (layoutCache->storageSize < 0)
    {
      layoutCache->storageSize = tmi.findOptimalStorageSize(this);
      assert(layoutCache->storageSize >= 0);
    }
  
  return layoutCache->storageSize;
}


inline unsigned int
StructType::getElementOffset(int i, const TargetMachine& tmi) const
{
  if (layoutCache->targetInfo != NULL && ! (* layoutCache->targetInfo == tmi))
    {// target machine has changed (hey it could happen). discard cached info.
      ResetCachedInfo();
    }
  
  if (layoutCache->memberOffsets[i] < 0)
    {
      layoutCache->targetInfo = &tmi;	// remember which target was used
      
      unsigned int* offsetVec = tmi.findOptimalMemberOffsets(this);
      for (unsigned i=0, N=layoutCache->memberOffsets.size(); i < N; i++)
	{
	  layoutCache->memberOffsets[i] = offsetVec[i];
	  assert(layoutCache->memberOffsets[i] >= 0);
	}
      delete[] offsetVec; 
    }
  
  return layoutCache->memberOffsets[i];
}


inline void
StructType::ResetCachedInfo() const
{
  layoutCache->storageSize = -1;
  layoutCache->memberOffsets.insert(layoutCache->memberOffsets.begin(),
				    ETypes.size(), -1);
  layoutCache->targetInfo = NULL;
}


class PointerType : public Type {
private:
  const Type *ValueType;

  PointerType(const PointerType &);                   // Do not implement
  const PointerType &operator=(const PointerType &);  // Do not implement
protected:
  // This should really be private, but it squelches a bogus warning
  // from GCC to make them protected:  warning: `class PointerType' only 
  // defines private constructors and has no friends


  // Private ctor - Only can be created by a static member...
  PointerType(const Type *ElType);
public:

  inline const Type *getValueType() const { return ValueType; }


  static const PointerType *getPointerType(const Type *ElementType);
  static const PointerType *get(const Type *ElementType) {
    return getPointerType(ElementType);
  }
};

#endif