1//===------------------------ ParameterType.cpp --------------------------===//
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#include "ParameterType.h"
13#include "ManglingUtils.h"
14#include <assert.h>
15#include <cctype>
16#include <sstream>
17
18namespace SPIR {
19  //
20  // Primitive Type
21  //
22
23  PrimitiveType::PrimitiveType(TypePrimitiveEnum primitive) :
24   ParamType(TYPE_ID_PRIMITIVE), m_primitive(primitive) {
25  }
26
27
28  MangleError PrimitiveType::accept(TypeVisitor* visitor) const {
29    if (getSupportedVersion(this->getPrimitive()) >= SPIR20 && visitor->spirVer < SPIR20) {
30      return MANGLE_TYPE_NOT_SUPPORTED;
31    }
32    return visitor->visit(this);
33  }
34
35  std::string PrimitiveType::toString() const {
36    assert( (m_primitive >= PRIMITIVE_FIRST
37      && m_primitive <= PRIMITIVE_LAST) && "illegal primitive");
38    std::stringstream myName;
39    myName << readablePrimitiveString(m_primitive);
40    return myName.str();
41  }
42
43  bool PrimitiveType::equals(const ParamType* type) const {
44    const PrimitiveType* p = SPIR::dyn_cast<PrimitiveType>(type);
45    return p && (m_primitive == p->m_primitive);
46  }
47
48
49  //
50  // Pointer Type
51  //
52
53  PointerType::PointerType(const RefParamType type) :
54    ParamType(TYPE_ID_POINTER), m_pType(type) {
55    for (unsigned int i = ATTR_QUALIFIER_FIRST; i <= ATTR_QUALIFIER_LAST; i++) {
56      setQualifier((TypeAttributeEnum)i, false);
57    }
58    m_address_space = ATTR_PRIVATE;
59  }
60
61  MangleError PointerType::accept(TypeVisitor* visitor) const {
62    return visitor->visit(this);
63  }
64
65  void PointerType::setAddressSpace(TypeAttributeEnum attr) {
66    if (attr < ATTR_ADDR_SPACE_FIRST || attr > ATTR_ADDR_SPACE_LAST) {
67      return;
68    }
69    m_address_space = attr;
70  }
71
72  TypeAttributeEnum PointerType::getAddressSpace() const {
73    return m_address_space;
74  }
75
76  void PointerType::setQualifier(TypeAttributeEnum qual, bool enabled) {
77    if (qual < ATTR_QUALIFIER_FIRST || qual > ATTR_QUALIFIER_LAST) {
78      return;
79    }
80    m_qualifiers[qual - ATTR_QUALIFIER_FIRST] = enabled;
81  }
82
83  bool PointerType::hasQualifier(TypeAttributeEnum qual) const {
84    if (qual < ATTR_QUALIFIER_FIRST || qual > ATTR_QUALIFIER_LAST) {
85      return false;
86    }
87    return m_qualifiers[qual - ATTR_QUALIFIER_FIRST];
88  }
89
90  std::string PointerType::toString() const {
91    std::stringstream myName;
92    for (unsigned int i = ATTR_QUALIFIER_FIRST; i <= ATTR_QUALIFIER_LAST; i++) {
93      TypeAttributeEnum qual = (TypeAttributeEnum)i;
94      if (hasQualifier(qual)) {
95        myName << getReadableAttribute(qual) << " ";
96      }
97    }
98    myName << getReadableAttribute(TypeAttributeEnum(m_address_space)) << " ";
99    myName << getPointee()->toString() << " *";
100    return myName.str();
101  }
102
103  bool PointerType::equals(const ParamType* type) const {
104    const PointerType* p = SPIR::dyn_cast<PointerType>(type);
105    if (!p) {
106      return false;
107    }
108    if (getAddressSpace() != p->getAddressSpace()) {
109      return false;
110    }
111    for (unsigned int i = ATTR_QUALIFIER_FIRST; i <= ATTR_QUALIFIER_LAST; i++) {
112      TypeAttributeEnum qual = (TypeAttributeEnum)i;
113      if (hasQualifier(qual) != p->hasQualifier(qual)) {
114        return false;
115      }
116    }
117    return (*getPointee()).equals(&*(p->getPointee()));
118  }
119
120  //
121  // Vector Type
122  //
123
124  VectorType::VectorType(const RefParamType type, int len) :
125    ParamType(TYPE_ID_VECTOR), m_pType(type), m_len(len) {
126  }
127
128  MangleError VectorType::accept(TypeVisitor* visitor) const {
129    return visitor->visit(this);
130  }
131
132  std::string VectorType::toString() const {
133    std::stringstream myName;
134    myName << getScalarType()->toString();
135    myName << m_len;
136    return myName.str();
137  }
138
139  bool VectorType::equals(const ParamType* type) const {
140    const VectorType* pVec = SPIR::dyn_cast<VectorType>(type);
141    return pVec && (m_len == pVec->m_len) &&
142      (*getScalarType()).equals(&*(pVec->getScalarType()));
143  }
144
145  //
146  //Atomic Type
147  //
148
149  AtomicType::AtomicType(const RefParamType type) :
150    ParamType(TYPE_ID_ATOMIC), m_pType(type) {
151  }
152
153  MangleError AtomicType::accept(TypeVisitor* visitor) const {
154    if (visitor->spirVer < SPIR20) {
155      return MANGLE_TYPE_NOT_SUPPORTED;
156    }
157    return visitor->visit(this);
158  }
159
160  std::string AtomicType::toString() const {
161    std::stringstream myName;
162    myName << "atomic_" << getBaseType()->toString();
163    return myName.str();
164  }
165
166  bool AtomicType::equals(const ParamType* type) const {
167    const AtomicType* a = dyn_cast<AtomicType>(type);
168    return (a && (*getBaseType()).equals(&*(a->getBaseType())));
169  }
170
171  //
172  //Block Type
173  //
174
175  BlockType::BlockType() :
176    ParamType(TYPE_ID_BLOCK) {
177  }
178
179  MangleError BlockType::accept(TypeVisitor* visitor) const {
180    if (visitor->spirVer < SPIR20) {
181      return MANGLE_TYPE_NOT_SUPPORTED;
182    }
183    return visitor->visit(this);
184  }
185
186  std::string BlockType::toString() const {
187    std::stringstream myName;
188    myName << "void (";
189    for (unsigned int i=0; i<getNumOfParams(); ++i) {
190      if (i>0) myName << ", ";
191      myName << m_params[i]->toString();
192    }
193    myName << ")*";
194    return myName.str();
195  }
196
197  bool BlockType::equals(const ParamType* type) const {
198    const BlockType* pBlock = dyn_cast<BlockType>(type);
199    if (!pBlock || getNumOfParams() != pBlock->getNumOfParams() ) {
200      return false;
201    }
202    for (unsigned int i=0; i<getNumOfParams(); ++i) {
203      if (!getParam(i)->equals(&*pBlock->getParam(i))) {
204        return false;
205      }
206    }
207    return true;
208  }
209
210  //
211  // User Defined Type
212  //
213  UserDefinedType::UserDefinedType(const std::string& name):
214    ParamType(TYPE_ID_STRUCTURE), m_name(name) {
215  }
216
217  MangleError UserDefinedType::accept(TypeVisitor* visitor) const {
218    return visitor->visit(this);
219  }
220
221  std::string UserDefinedType::toString() const {
222    std::stringstream myName;
223    myName << m_name;
224    return myName.str();
225  }
226
227  bool UserDefinedType::equals(const ParamType* pType) const {
228    const UserDefinedType* pTy = SPIR::dyn_cast<UserDefinedType>(pType);
229    return pTy && (m_name == pTy->m_name);
230  }
231
232
233  //
234  // Static enums
235  //
236  const TypeEnum PrimitiveType::enumTy    = TYPE_ID_PRIMITIVE;
237  const TypeEnum PointerType::enumTy      = TYPE_ID_POINTER;
238  const TypeEnum VectorType::enumTy       = TYPE_ID_VECTOR;
239  const TypeEnum AtomicType::enumTy       = TYPE_ID_ATOMIC;
240  const TypeEnum BlockType::enumTy        = TYPE_ID_BLOCK;
241  const TypeEnum UserDefinedType::enumTy  = TYPE_ID_STRUCTURE;
242
243} // End SPIR namespace
244