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 
18 namespace SPIR {
19   //
20   // Primitive Type
21   //
22 
PrimitiveType(TypePrimitiveEnum primitive)23   PrimitiveType::PrimitiveType(TypePrimitiveEnum primitive) :
24    ParamType(TYPE_ID_PRIMITIVE), m_primitive(primitive) {
25   }
26 
27 
accept(TypeVisitor * visitor) const28   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 
toString() const35   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 
equals(const ParamType * type) const43   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 
PointerType(const RefParamType type)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 
accept(TypeVisitor * visitor) const61   MangleError PointerType::accept(TypeVisitor* visitor) const {
62     return visitor->visit(this);
63   }
64 
setAddressSpace(TypeAttributeEnum attr)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 
getAddressSpace() const72   TypeAttributeEnum PointerType::getAddressSpace() const {
73     return m_address_space;
74   }
75 
setQualifier(TypeAttributeEnum qual,bool enabled)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 
hasQualifier(TypeAttributeEnum qual) const83   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 
toString() const90   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 
equals(const ParamType * type) const103   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 
VectorType(const RefParamType type,int len)124   VectorType::VectorType(const RefParamType type, int len) :
125     ParamType(TYPE_ID_VECTOR), m_pType(type), m_len(len) {
126   }
127 
accept(TypeVisitor * visitor) const128   MangleError VectorType::accept(TypeVisitor* visitor) const {
129     return visitor->visit(this);
130   }
131 
toString() const132   std::string VectorType::toString() const {
133     std::stringstream myName;
134     myName << getScalarType()->toString();
135     myName << m_len;
136     return myName.str();
137   }
138 
equals(const ParamType * type) const139   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 
AtomicType(const RefParamType type)149   AtomicType::AtomicType(const RefParamType type) :
150     ParamType(TYPE_ID_ATOMIC), m_pType(type) {
151   }
152 
accept(TypeVisitor * visitor) const153   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 
toString() const160   std::string AtomicType::toString() const {
161     std::stringstream myName;
162     myName << "atomic_" << getBaseType()->toString();
163     return myName.str();
164   }
165 
equals(const ParamType * type) const166   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 
BlockType()175   BlockType::BlockType() :
176     ParamType(TYPE_ID_BLOCK) {
177   }
178 
accept(TypeVisitor * visitor) const179   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 
toString() const186   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 
equals(const ParamType * type) const197   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   //
UserDefinedType(const std::string & name)213   UserDefinedType::UserDefinedType(const std::string& name):
214     ParamType(TYPE_ID_STRUCTURE), m_name(name) {
215   }
216 
accept(TypeVisitor * visitor) const217   MangleError UserDefinedType::accept(TypeVisitor* visitor) const {
218     return visitor->visit(this);
219   }
220 
toString() const221   std::string UserDefinedType::toString() const {
222     std::stringstream myName;
223     myName << m_name;
224     return myName.str();
225   }
226 
equals(const ParamType * pType) const227   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