1//===------------------------- ParameterType.h ---------------------------===//
2//
3//                              SPIR Tools
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9/*
10 * Contributed by: Intel Corporation.
11 */
12
13#ifndef __PARAMETER_TYPE_H__
14#define __PARAMETER_TYPE_H__
15
16#include "Refcount.h"
17#include <string>
18#include <vector>
19
20// The Type class hierarchy models the different types in OCL.
21
22namespace SPIR {
23
24  // Supported SPIR versions
25  enum SPIRversion {
26    SPIR12 = 1,
27    SPIR20 = 2
28  };
29
30  // Error Status values
31  enum MangleError {
32    MANGLE_SUCCESS,
33    MANGLE_TYPE_NOT_SUPPORTED,
34    MANGLE_NULL_FUNC_DESCRIPTOR
35  };
36
37  enum TypePrimitiveEnum {
38    PRIMITIVE_FIRST,
39    PRIMITIVE_BOOL = PRIMITIVE_FIRST,
40    PRIMITIVE_UCHAR,
41    PRIMITIVE_CHAR,
42    PRIMITIVE_USHORT,
43    PRIMITIVE_SHORT,
44    PRIMITIVE_UINT,
45    PRIMITIVE_INT,
46    PRIMITIVE_ULONG,
47    PRIMITIVE_LONG,
48    PRIMITIVE_HALF,
49    PRIMITIVE_FLOAT,
50    PRIMITIVE_DOUBLE,
51    PRIMITIVE_VOID,
52    PRIMITIVE_VAR_ARG,
53    PRIMITIVE_STRUCT_FIRST,
54    PRIMITIVE_IMAGE_1D_T = PRIMITIVE_STRUCT_FIRST,
55    PRIMITIVE_IMAGE_1D_ARRAY_T,
56    PRIMITIVE_IMAGE_1D_BUFFER_T,
57    PRIMITIVE_IMAGE_2D_T,
58    PRIMITIVE_IMAGE_2D_ARRAY_T,
59    PRIMITIVE_IMAGE_3D_T,
60    PRIMITIVE_IMAGE_2D_MSAA_T,
61    PRIMITIVE_IMAGE_2D_ARRAY_MSAA_T,
62    PRIMITIVE_IMAGE_2D_MSAA_DEPTH_T,
63    PRIMITIVE_IMAGE_2D_ARRAY_MSAA_DEPTH_T,
64    PRIMITIVE_IMAGE_2D_DEPTH_T,
65    PRIMITIVE_IMAGE_2D_ARRAY_DEPTH_T,
66    PRIMITIVE_EVENT_T,
67    PRIMITIVE_PIPE_T,
68    PRIMITIVE_RESERVE_ID_T,
69    PRIMITIVE_QUEUE_T,
70    PRIMITIVE_NDRANGE_T,
71    PRIMITIVE_CLK_EVENT_T,
72    PRIMITIVE_STRUCT_LAST = PRIMITIVE_CLK_EVENT_T,
73    PRIMITIVE_SAMPLER_T,
74    PRIMITIVE_KERNEL_ENQUEUE_FLAGS_T,
75    PRIMITIVE_CLK_PROFILING_INFO,
76    PRIMITIVE_LAST = PRIMITIVE_CLK_PROFILING_INFO,
77    PRIMITIVE_NONE,
78    // Keep this at the end.
79    PRIMITIVE_NUM = PRIMITIVE_NONE
80  };
81
82  enum TypeEnum {
83    TYPE_ID_PRIMITIVE,
84    TYPE_ID_POINTER,
85    TYPE_ID_VECTOR,
86    TYPE_ID_ATOMIC,
87    TYPE_ID_BLOCK,
88    TYPE_ID_STRUCTURE
89  };
90
91  enum TypeAttributeEnum {
92    ATTR_QUALIFIER_FIRST = 0,
93    ATTR_RESTRICT = ATTR_QUALIFIER_FIRST,
94    ATTR_VOLATILE,
95    ATTR_CONST,
96    ATTR_QUALIFIER_LAST = ATTR_CONST,
97    ATTR_ADDR_SPACE_FIRST,
98    ATTR_PRIVATE = ATTR_ADDR_SPACE_FIRST,
99    ATTR_GLOBAL,
100    ATTR_CONSTANT,
101    ATTR_LOCAL,
102    ATTR_GENERIC,
103    ATTR_ADDR_SPACE_LAST = ATTR_GENERIC,
104    ATTR_NONE,
105    ATTR_NUM = ATTR_NONE
106  };
107
108  // Forward declaration for abstract structure.
109  struct ParamType;
110  typedef RefCount<ParamType> RefParamType;
111
112  // Forward declaration for abstract structure.
113  struct TypeVisitor;
114
115  struct ParamType {
116    /// @brief Constructor.
117    /// @param TypeEnum type id.
118    ParamType(TypeEnum typeId) : m_typeId(typeId) {};
119
120    /// @brief Destructor.
121    virtual ~ParamType() {};
122
123    /// Abstract Methods ///
124
125    /// @brief Visitor service method. (see TypeVisitor for more details).
126    ///        When overridden in subclasses, preform a 'double dispatch' to the
127    ///        appropriate visit method in the given visitor.
128    /// @param TypeVisitor type visitor.
129    virtual MangleError accept(TypeVisitor*) const = 0;
130
131    /// @brief Returns a string representation of the underlying type.
132    /// @return type as string.
133    virtual std::string toString() const = 0;
134
135    /// @brief Returns true if given param type is equal to this type.
136    /// @param ParamType given param type.
137    /// @return true if given param type is equal to this type and false otherwise.
138    virtual bool equals(const ParamType*) const = 0;
139
140    /// Common Base-Class Methods ///
141
142    /// @brief Returns type id of underlying type.
143    /// @return type id.
144    TypeEnum getTypeId() const {
145      return m_typeId;
146    }
147
148  private:
149    // @brief Default Constructor.
150    ParamType();
151
152  protected:
153    /// An enumeration to identify the type id of this instance.
154    TypeEnum m_typeId;
155  };
156
157
158  struct PrimitiveType : public ParamType {
159    /// An enumeration to identify the type id of this class.
160    const static TypeEnum enumTy;
161
162    /// @brief Constructor.
163    /// @param TypePrimitiveEnum primitive id.
164    PrimitiveType(TypePrimitiveEnum);
165
166    /// Implementation of Abstract Methods ///
167
168    /// @brief Visitor service method. (see TypeVisitor for more details).
169    ///        When overridden in subclasses, preform a 'double dispatch' to the
170    ///        appropriate visit method in the given visitor.
171    /// @param TypeVisitor type visitor.
172    MangleError accept(TypeVisitor*) const;
173
174    /// @brief Returns a string representation of the underlying type.
175    /// @return type as string.
176    std::string toString() const;
177
178    /// @brief Returns true if given param type is equal to this type.
179    /// @param ParamType given param type.
180    /// @return true if given param type is equal to this type and false otherwise.
181    bool equals(const ParamType*) const;
182
183    /// Non-Common Methods ///
184
185    /// @brief Returns the primitive enumeration of the type.
186    /// @return primitive type.
187    TypePrimitiveEnum getPrimitive() const {
188      return m_primitive;
189    }
190
191  protected:
192    /// An enumeration to identify the primitive type.
193    TypePrimitiveEnum m_primitive;
194  };
195
196  struct PointerType: public ParamType {
197    /// An enumeration to identify the type id of this class.
198    const static TypeEnum enumTy;
199
200    /// @brief Constructor.
201    /// @param RefParamType the type of pointee (that the pointer points at).
202    PointerType(const RefParamType type);
203
204    /// Implementation of Abstract Methods ///
205
206    /// @brief Visitor service method. (see TypeVisitor for more details).
207    ///        When overridden in subclasses, preform a 'double dispatch' to the
208    ///        appropriate visit method in the given visitor.
209    /// @param TypeVisitor type visitor
210    MangleError accept(TypeVisitor*) const;
211
212    /// @brief Returns a string representation of the underlying type.
213    /// @return type as string.
214    std::string toString() const;
215
216    /// @brief Returns true if given param type is equal to this type.
217    /// @param ParamType given param type.
218    /// @return true if given param type is equal to this type and false otherwise.
219    bool equals(const ParamType*) const;
220
221    /// Non-Common Methods ///
222
223    /// @brief Returns the type the pointer is pointing at.
224    /// @return pointee type.
225    const RefParamType& getPointee() const {
226      return m_pType;
227    }
228
229    /// @brief Sets the address space attribute - default is __private
230    /// @param TypeAttributeEnum address space attribute id.
231    void setAddressSpace(TypeAttributeEnum attr);
232
233    /// @brief Returns the pointer's address space.
234    /// @return pointer's address space.
235    TypeAttributeEnum getAddressSpace() const;
236
237    /// @brief Adds or removes a pointer's qualifier.
238    /// @param TypeAttributeEnum qual - qualifier to add/remove.
239    /// @param bool enabled - true if qualifier should exist false otherwise.
240    ///        default is set to false.
241    void setQualifier(TypeAttributeEnum qual, bool enabled);
242
243    /// @brief Checks if the pointer has a certain qualifier.
244    /// @param TypeAttributeEnum qual - qualifier to check.
245    /// @return true if the qualifier exists and false otherwise.
246    bool hasQualifier(TypeAttributeEnum qual) const;
247
248  private:
249    /// The type this pointer is pointing at.
250    RefParamType m_pType;
251    /// Array of the pointer's enabled type qualifiers.
252    bool m_qualifiers[ATTR_QUALIFIER_LAST - ATTR_QUALIFIER_FIRST + 1];
253    /// Pointer's address space.
254    TypeAttributeEnum m_address_space;
255  };
256
257  struct VectorType : public ParamType {
258    /// An enumeration to identify the type id of this class.
259    const static TypeEnum enumTy;
260
261    /// @brief Constructor.
262    /// @param RefParamType the type of each scalar element in the vector.
263    /// @param int the length of the vector.
264    VectorType(const RefParamType type, int len);
265
266    /// Implementation of Abstract Methods ///
267
268    /// @brief Visitor service method. (see TypeVisitor for more details).
269    ///        When overridden in subclasses, preform a 'double dispatch' to the
270    ///        appropriate visit method in the given visitor.
271    /// @param TypeVisitor type visitor.
272    MangleError accept(TypeVisitor*) const;
273
274    /// @brief Returns a string representation of the underlying type.
275    /// @return type as string.
276    std::string toString() const;
277
278    /// @brief Returns true if given param type is equal to this type.
279    /// @param ParamType given param type.
280    /// @return true if given param type is equal to this type and false otherwise.
281    bool equals(const ParamType*) const;
282
283    /// Non-Common Methods ///
284
285    /// @brief Returns the type the vector is packing.
286    /// @return scalar type.
287    const RefParamType& getScalarType() const {
288      return m_pType;
289    }
290
291    /// @brief Returns the length of the vector type.
292    /// @return vector type length.
293    int getLength() const {
294      return m_len;
295    }
296
297  private:
298    /// The scalar type of this vector type.
299    RefParamType m_pType;
300    /// The length of the vector.
301    int m_len;
302  };
303
304  struct AtomicType: public ParamType {
305    ///an enumeration to identify the type id of this class
306    const static TypeEnum enumTy;
307
308    /// @brief Constructor
309    /// @param RefParamType the type refernced as atomic.
310    AtomicType(const RefParamType type);
311
312    /// Implementation of Abstract Methods ///
313
314    /// @brief visitor service method. (see TypeVisitor for more details).
315    ///       When overridden in subclasses, preform a 'double dispatch' to the
316    ///       appropriate visit method in the given visitor.
317    /// @param TypeVisitor type visitor
318    MangleError accept(TypeVisitor*) const;
319
320    /// @brief returns a string representation of the underlying type.
321    /// @return type as string
322    std::string toString() const;
323
324    /// @brief returns true if given param type is equal to this type.
325    /// @param ParamType given param type
326    /// @return true if given param type is equal to this type and false otherwise
327    bool equals(const ParamType*) const;
328
329    /// Non-Common Methods ///
330
331    /// @brief returns the base type of the atomic parameter.
332    /// @return base type
333    const RefParamType& getBaseType() const {
334      return m_pType;
335    }
336
337  private:
338    ///the type this pointer is pointing at
339    RefParamType m_pType;
340  };
341
342  struct BlockType : public ParamType {
343    ///an enumeration to identify the type id of this class
344    const static TypeEnum enumTy;
345
346    ///@brief Constructor
347    BlockType();
348
349    /// Implementation of Abstract Methods ///
350
351    /// @brief visitor service method. (see TypeVisitor for more details).
352    ///       When overridden in subclasses, preform a 'double dispatch' to the
353    ///       appropriate visit method in the given visitor.
354    /// @param TypeVisitor type visitor
355    MangleError accept(TypeVisitor*) const;
356
357    /// @brief returns a string representation of the underlying type.
358    /// @return type as string
359    std::string toString() const;
360
361    /// @brief returns true if given param type is equal to this type.
362    /// @param ParamType given param type
363    /// @return true if given param type is equal to this type and false otherwise
364    bool equals(const ParamType*) const;
365
366    /// Non-Common Methods ///
367
368    /// @brief returns the number of parameters of the block.
369    /// @return parameters count
370    unsigned int getNumOfParams() const {
371      return (unsigned int)m_params.size();
372    }
373
374    ///@brief returns the type of parameter "index" of the block.
375    // @param index the sequential number of the queried parameter
376    ///@return parameter type
377    const RefParamType& getParam(unsigned int index) const {
378      assert(m_params.size() > index && "index is OOB");
379      return m_params[index];
380    }
381
382    ///@brief set the type of parameter "index" of the block.
383    // @param index the sequential number of the queried parameter
384    // @param type the parameter type
385    void setParam(unsigned int index, RefParamType type) {
386      if(index < getNumOfParams()) {
387        m_params[index] = type;
388      }
389      else if (index == getNumOfParams()) {
390        m_params.push_back(type);
391      }
392      else {
393        assert(false && "index is OOB");
394      }
395    }
396
397  protected:
398    ///an enumeration to identify the primitive type
399    std::vector<RefParamType> m_params;
400  };
401
402
403  struct UserDefinedType : public ParamType {
404    /// An enumeration to identify the type id of this class.
405    const static TypeEnum enumTy;
406
407    /// @brief Constructor.
408    UserDefinedType(const std::string&);
409
410    /// Implementation of Abstract Methods ///
411
412    /// @brief Visitor service method. (see TypeVisitor for more details).
413    ///        When overridden in subclasses, preform a 'double dispatch' to the
414    ///        appropriate visit method in the given visitor.
415    /// @param TypeVisitor type visitor.
416    MangleError accept(TypeVisitor*) const;
417
418    /// @brief Returns a string representation of the underlying type.
419    /// @return type as string.
420    std::string toString() const;
421
422    /// @brief Returns true if given param type is equal to this type.
423    /// @param ParamType given param type.
424    /// @return true if given param type is equal to this type and false otherwise.
425    bool equals(const ParamType*) const;
426
427  protected:
428    /// The name of the user defined type.
429    std::string m_name;
430  };
431
432
433  /// @brief Can be overridden so an object of static type Type* will
434  ///        dispatch the correct visit method according to its dynamic type.
435  struct TypeVisitor{
436    SPIRversion spirVer;
437    TypeVisitor(SPIRversion ver) : spirVer(ver) {};
438
439    /// should usually have virtual destructor if there are any
440    /// virtual functions
441    virtual ~TypeVisitor() { }
442
443    virtual MangleError visit(const PrimitiveType*)   = 0;
444    virtual MangleError visit(const VectorType*)      = 0;
445    virtual MangleError visit(const PointerType*)     = 0;
446    virtual MangleError visit(const AtomicType*)      = 0;
447    virtual MangleError visit(const BlockType*)       = 0;
448    virtual MangleError visit(const UserDefinedType*) = 0;
449  };
450
451  /// @brief Template dynamic cast function for ParamType derived classes.
452  /// @param ParamType given param type.
453  /// @return required casting type if given param type is an instance if
454  //          that type, NULL otherwise.
455  template <typename T>
456  T* dyn_cast(ParamType* pType) {
457    assert(pType && "dyn_cast does not support casting of NULL");
458    return (T::enumTy == pType->getTypeId()) ? (T*)pType : NULL;
459  }
460
461  /// @brief Template dynamic cast function for ParamType derived classes
462  ///        (the constant version).
463  /// @param ParamType given param type.
464  /// @return required casting type if given param type is an instance if
465  //          that type, NULL otherwise.
466  template <typename T>
467  const T* dyn_cast(const ParamType* pType) {
468    assert(pType && "dyn_cast does not support casting of NULL");
469    return (T::enumTy == pType->getTypeId()) ? (const T*)pType : NULL;
470  }
471
472} // End SPIR namespace
473#endif //__PARAMETER_TYPE_H__
474