slang_rs_export_type.h revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
1#ifndef _SLANG_COMPILER_RS_EXPORT_TYPE_H 2#define _SLANG_COMPILER_RS_EXPORT_TYPE_H 3 4#include <set> 5#include <list> 6#include <string> 7 8#include "llvm/ADT/StringRef.h" 9#include "llvm/ADT/StringMap.h" 10#include "llvm/ADT/SmallPtrSet.h" 11 12#include "clang/AST/Type.h" 13#include "clang/AST/Decl.h" 14 15#define GET_CANONICAL_TYPE(T) \ 16 (((T) == NULL) ? NULL : (T)->getCanonicalTypeInternal().getTypePtr()) 17#define UNSAFE_CAST_TYPE(TT, T) \ 18 static_cast<TT*>(T->getCanonicalTypeInternal().getTypePtr()) 19#define GET_CONSTANT_ARRAY_ELEMENT_TYPE(T) \ 20 (((T) == NULL) ? NULL : \ 21 GET_CANONICAL_TYPE((T)->getElementType().getTypePtr())) 22#define GET_EXT_VECTOR_ELEMENT_TYPE(T) \ 23 (((T) == NULL) ? NULL : \ 24 GET_CANONICAL_TYPE((T)->getElementType().getTypePtr())) 25#define GET_POINTEE_TYPE(T) \ 26 (((T) == NULL) ? NULL : \ 27 GET_CANONICAL_TYPE((T)->getPointeeType().getTypePtr())) 28 29namespace llvm { 30 class Type; 31} // namespace llvm 32 33namespace slang { 34 35 class RSContext; 36 class RSExportPrimitiveType; 37 class RSExportConstantArrayType; 38 class RSExportVectorType; 39 class RSExportRecordType; 40 class RSExportFunction; 41 42class RSExportType { 43 friend class RSExportElement; 44 public: 45 typedef enum { 46 ExportClassPrimitive, 47 ExportClassPointer, 48 ExportClassConstantArray, 49 ExportClassVector, 50 ExportClassRecord 51 } ExportClass; 52 53 private: 54 RSContext *mContext; 55 std::string mName; 56 57 // Cache the result after calling convertToLLVMType() at the first time 58 mutable const llvm::Type *mLLVMType; 59 60 protected: 61 RSExportType(RSContext *Context, const llvm::StringRef &Name); 62 63 // Let's make it private since there're some prerequisites to call this 64 // function. 65 // 66 // @T was normalized by calling RSExportType::TypeExportable(). 67 // @TypeName was retrieve from RSExportType::GetTypeName() before calling 68 // this. 69 // 70 static RSExportType *Create(RSContext *Context, 71 const clang::Type *T, 72 const llvm::StringRef &TypeName); 73 74 static llvm::StringRef GetTypeName(const clang::Type *T); 75 // Return the type that can be used to create RSExportType, will always return 76 // the canonical type 77 static const clang::Type 78 *TypeExportable(const clang::Type *T, 79 // Contain the checked type for recursion 80 llvm::SmallPtrSet<const clang::Type*, 8> &SPS); 81 82 // This function convert the RSExportType to LLVM type. Actually, it should be 83 // "convert Clang type to LLVM type." However, clang doesn't make this API 84 // (lib/CodeGen/CodeGenTypes.h) public, we need to do by ourselves. 85 // 86 // Once we can get LLVM type, we can use LLVM to get alignment information, 87 // allocation size of a given type and structure layout that LLVM used 88 // (all of these information are target dependent) without dealing with these 89 // by ourselves. 90 virtual const llvm::Type *convertToLLVMType() const = 0; 91 92 virtual ~RSExportType() {} 93 public: 94 static bool NormalizeType(const clang::Type *&T, llvm::StringRef &TypeName); 95 // @T may not be normalized 96 static RSExportType *Create(RSContext *Context, const clang::Type *T); 97 static RSExportType *CreateFromDecl(RSContext *Context, 98 const clang::VarDecl *VD); 99 100 static const clang::Type *GetTypeOfDecl(const clang::DeclaratorDecl *DD); 101 102 virtual ExportClass getClass() const = 0; 103 104 inline const llvm::Type *getLLVMType() const { 105 if (mLLVMType == NULL) 106 mLLVMType = convertToLLVMType(); 107 return mLLVMType; 108 } 109 110 // Return the number of bits necessary to hold the specified RSExportType 111 static size_t GetTypeStoreSize(const RSExportType *ET); 112 113 // The size of allocation of specified RSExportType (alignment considered) 114 static size_t GetTypeAllocSize(const RSExportType *ET); 115 static unsigned char GetTypeAlignment(const RSExportType *ET); 116 117 const std::string &getName() const { return mName; } 118 inline RSContext *getRSContext() const { return mContext; } 119}; // RSExportType 120 121// Primitive types 122class RSExportPrimitiveType : public RSExportType { 123 friend class RSExportType; 124 friend class RSExportElement; 125 public: 126 // From graphics/java/android/renderscript/Element.java: Element.DataType 127 typedef enum { 128 DataTypeUnknown = -1, 129 130 DataTypeFloat16 = 0, 131 DataTypeFloat32, 132 DataTypeFloat64, 133 DataTypeSigned8, 134 DataTypeSigned16, 135 DataTypeSigned32, 136 DataTypeSigned64, 137 DataTypeUnsigned8, 138 DataTypeUnsigned16, 139 DataTypeUnsigned32, 140 DataTypeUnSigned64, 141 142 DataTypeBoolean, 143 144 DataTypeUnsigned565, 145 DataTypeUnsigned5551, 146 DataTypeUnsigned4444, 147 148 DataTypeRSMatrix2x2, 149 DataTypeRSMatrix3x3, 150 DataTypeRSMatrix4x4, 151 152 DataTypeRSElement, 153 DataTypeRSType, 154 DataTypeRSAllocation, 155 DataTypeRSSampler, 156 DataTypeRSScript, 157 DataTypeRSMesh, 158 DataTypeRSProgramFragment, 159 DataTypeRSProgramVertex, 160 DataTypeRSProgramRaster, 161 DataTypeRSProgramStore, 162 DataTypeRSFont, 163 164 DataTypeMax 165 } DataType; 166 167 // From graphics/java/android/renderscript/Element.java: Element.DataKind 168 typedef enum { 169 DataKindUser, 170 DataKindPixelL, 171 DataKindPixelA, 172 DataKindPixelLA, 173 DataKindPixelRGB, 174 DataKindPixelRGBA 175 } DataKind; 176 177 private: 178 DataType mType; 179 DataKind mKind; 180 bool mNormalized; 181 182 typedef llvm::StringMap<DataType> RSObjectTypeMapTy; 183 static RSObjectTypeMapTy *RSObjectTypeMap; 184 185 static llvm::Type *RSObjectLLVMType; 186 187 static const size_t SizeOfDataTypeInBits[]; 188 // @T was normalized by calling RSExportType::TypeExportable() before calling 189 // this. 190 // @TypeName was retrieved from RSExportType::GetTypeName() before calling 191 // this 192 static RSExportPrimitiveType *Create(RSContext *Context, 193 const clang::Type *T, 194 const llvm::StringRef &TypeName, 195 DataKind DK = DataKindUser, 196 bool Normalized = false); 197 198 protected: 199 // T is normalized by calling RSExportType::TypeExportable() before 200 // calling this 201 static bool IsPrimitiveType(const clang::Type *T); 202 203 static DataType GetDataType(const clang::Type *T); 204 205 RSExportPrimitiveType(RSContext *Context, 206 const llvm::StringRef &Name, 207 DataType DT, 208 DataKind DK, 209 bool Normalized) 210 : RSExportType(Context, Name), 211 mType(DT), 212 mKind(DK), 213 mNormalized(Normalized) { 214 return; 215 } 216 217 virtual const llvm::Type *convertToLLVMType() const; 218 public: 219 // @T may not be normalized 220 static RSExportPrimitiveType *Create(RSContext *Context, 221 const clang::Type *T, 222 DataKind DK = DataKindUser); 223 224 static DataType GetRSObjectType(const llvm::StringRef &TypeName); 225 static DataType GetRSObjectType(const clang::Type *T); 226 227 static size_t GetSizeInBits(const RSExportPrimitiveType *EPT); 228 229 virtual ExportClass getClass() const; 230 231 inline DataType getType() const { return mType; } 232 inline DataKind getKind() const { return mKind; } 233 inline bool isRSObjectType() const { 234 return ((mType >= DataTypeRSElement) && (mType < DataTypeMax)); 235 } 236}; // RSExportPrimitiveType 237 238 239class RSExportPointerType : public RSExportType { 240 friend class RSExportType; 241 friend class RSExportElement; 242 friend class RSExportFunc; 243 244 private: 245 const RSExportType *mPointeeType; 246 247 RSExportPointerType(RSContext *Context, 248 const llvm::StringRef &Name, 249 const RSExportType *PointeeType) 250 : RSExportType(Context, Name), 251 mPointeeType(PointeeType) { 252 return; 253 } 254 255 // @PT was normalized by calling RSExportType::TypeExportable() before calling 256 // this. 257 static RSExportPointerType *Create(RSContext *Context, 258 const clang::PointerType *PT, 259 const llvm::StringRef &TypeName); 260 261 virtual const llvm::Type *convertToLLVMType() const; 262 public: 263 static const clang::Type *IntegerType; 264 265 virtual ExportClass getClass() const; 266 267 inline const RSExportType *getPointeeType() const { return mPointeeType; } 268}; // RSExportPointerType 269 270 271class RSExportConstantArrayType : public RSExportPrimitiveType { 272 friend class RSExportType; 273 friend class RSExportElement; 274 friend class RSExportFunc; 275 276 private: 277 int mNumElement; // number of element 278 279 RSExportConstantArrayType(RSContext *Context, 280 const llvm::StringRef &Name, 281 DataType DT, 282 DataKind DK, 283 bool Normalized, 284 int NumElement) 285 : RSExportPrimitiveType(Context, Name, DT, DK, Normalized), 286 mNumElement(NumElement) { 287 return; 288 } 289 290 static RSExportConstantArrayType *Create(RSContext *Context, 291 const clang::ConstantArrayType *ECT, 292 const llvm::StringRef &TypeName, 293 DataKind DK = DataKindUser, 294 bool Normalized = false); 295 virtual const llvm::Type *convertToLLVMType() const; 296 public: 297 static llvm::StringRef GetTypeName(const clang::ConstantArrayType *ECT); 298 299 virtual ExportClass getClass() const; 300 301 inline int getNumElement() const { return mNumElement; } 302}; 303 304 305class RSExportVectorType : public RSExportPrimitiveType { 306 friend class RSExportType; 307 friend class RSExportElement; 308 309 private: 310 int mNumElement; // number of element 311 312 RSExportVectorType(RSContext *Context, 313 const llvm::StringRef &Name, 314 DataType DT, 315 DataKind DK, 316 bool Normalized, 317 int NumElement) 318 : RSExportPrimitiveType(Context, Name, DT, DK, Normalized), 319 mNumElement(NumElement) { 320 return; 321 } 322 323 // @EVT was normalized by calling RSExportType::TypeExportable() before 324 // calling this. 325 static RSExportVectorType *Create(RSContext *Context, 326 const clang::ExtVectorType *EVT, 327 const llvm::StringRef &TypeName, 328 DataKind DK = DataKindUser, 329 bool Normalized = false); 330 331 static const char *VectorTypeNameStore[][3]; 332 333 virtual const llvm::Type *convertToLLVMType() const; 334 public: 335 static llvm::StringRef GetTypeName(const clang::ExtVectorType *EVT); 336 337 virtual ExportClass getClass() const; 338 339 inline int getNumElement() const { return mNumElement; } 340}; 341 342class RSExportRecordType : public RSExportType { 343 friend class RSExportType; 344 friend class RSExportElement; 345 friend class RSExportFunc; 346 public: 347 class Field { 348 private: 349 const RSExportType *mType; 350 // Field name 351 std::string mName; 352 // Link to the struct that contain this field 353 const RSExportRecordType *mParent; 354 // Index in the container 355 unsigned int mIndex; 356 357 public: 358 Field(const RSExportType *T, 359 const llvm::StringRef &Name, 360 const RSExportRecordType *Parent, 361 unsigned int Index) 362 : mType(T), 363 mName(Name.data(), Name.size()), 364 mParent(Parent), 365 mIndex(Index) { 366 return; 367 } 368 369 inline const RSExportRecordType *getParent() const { return mParent; } 370 inline unsigned int getIndex() const { return mIndex; } 371 inline const RSExportType *getType() const { return mType; } 372 inline const std::string &getName() const { return mName; } 373 size_t getOffsetInParent() const; 374 }; 375 376 typedef std::list<const Field*>::const_iterator const_field_iterator; 377 378 inline const_field_iterator fields_begin() const { 379 return this->mFields.begin(); 380 } 381 inline const_field_iterator fields_end() const { 382 return this->mFields.end(); 383 } 384 385 private: 386 std::list<const Field*> mFields; 387 bool mIsPacked; 388 // Artificial export struct type is not exported by user (and thus it won't 389 // get reflected) 390 bool mIsArtificial; 391 size_t AllocSize; 392 393 RSExportRecordType(RSContext *Context, 394 const llvm::StringRef &Name, 395 bool IsPacked, 396 bool IsArtificial = false) 397 : RSExportType(Context, Name), 398 mIsPacked(IsPacked), 399 mIsArtificial(IsArtificial) { 400 return; 401 } 402 403 // @RT was normalized by calling RSExportType::TypeExportable() before calling 404 // this. 405 // @TypeName was retrieved from RSExportType::GetTypeName() before calling 406 // this. 407 static RSExportRecordType *Create(RSContext *Context, 408 const clang::RecordType *RT, 409 const llvm::StringRef &TypeName, 410 bool mIsArtificial = false); 411 412 virtual const llvm::Type *convertToLLVMType() const; 413 public: 414 virtual ExportClass getClass() const; 415 416 inline bool isPacked() const { return mIsPacked; } 417 inline bool isArtificial() const { return mIsArtificial; } 418 inline size_t getAllocSize() const { return AllocSize; } 419 420 ~RSExportRecordType() { 421 for (std::list<const Field*>::iterator I = mFields.begin(), 422 E = mFields.end(); 423 I != E; 424 I++) 425 if (*I != NULL) 426 delete *I; 427 return; 428 } 429}; // RSExportRecordType 430 431} // namespace slang 432 433#endif // _SLANG_COMPILER_RS_EXPORT_TYPE_H 434