blob: f2a66d206f1fc3a502c68578fdf99346d345ff55 [file] [log] [blame]
#ifndef _SLANG_COMPILER_RS_EXPORT_TYPE_HPP
# define _SLANG_COMPILER_RS_EXPORT_TYPE_HPP
#include <set>
#include <list>
#include <string>
#include "llvm/ADT/StringRef.h" /* for class llvm::StringRef */
#include "llvm/ADT/StringMap.h" /* for class llvm::StringMap */
#include "llvm/ADT/SmallPtrSet.h" /* for class llvm::SmallPtrSet */
#include "clang/AST/Type.h" /* for clang::Type and clang::QualType */
#include "clang/AST/Decl.h" /* for clang::VarDecl and clang::DeclaratorDecl */
#define GET_CANONICAL_TYPE(T) (((T) == NULL) ? NULL : (T)->getCanonicalTypeInternal().getTypePtr())
#define UNSAFE_CAST_TYPE(TT, T) static_cast<TT*>(T->getCanonicalTypeInternal().getTypePtr())
#define GET_EXT_VECTOR_ELEMENT_TYPE(T) (((T) == NULL) ? NULL : GET_CANONICAL_TYPE((T)->getElementType().getTypePtr()))
#define GET_POINTEE_TYPE(T) (((T) == NULL) ? NULL : GET_CANONICAL_TYPE((T)->getPointeeType().getTypePtr()))
namespace llvm {
class Type;
} /* namespace llvm */
namespace slang {
class RSContext;
class RSExportPrimitiveType;
class RSExportVectorType;
class RSExportRecordType;
class RSExportFunction;
using namespace clang;
class RSExportType {
friend class RSExportElement;
public:
typedef enum {
ExportClassPrimitive,
ExportClassPointer,
ExportClassVector,
ExportClassRecord
} ExportClass;
private:
RSContext* mContext;
std::string mName;
mutable const llvm::Type* mLLVMType; /* Cache the result after calling convertToLLVMType() at the first time */
protected:
RSExportType(RSContext* Context, const llvm::StringRef& Name);
/*
* Let's make it private since there're some prerequisites to call this function.
*
* @T was normalized by calling RSExportType::TypeExportable().
* @TypeName was retrieve from RSExportType::GetTypeName() before calling this.
*/
static RSExportType* Create(RSContext* Context, const Type* T, const llvm::StringRef& TypeName);
static llvm::StringRef GetTypeName(const Type* T);
/* Return the type that can be used to create RSExportType, will always return the canonical type */
static const Type* TypeExportable(const Type* T, llvm::SmallPtrSet<const Type*, 8>& SPS /* contain the checked type for recursion */);
/* This function convert the RSExportType to LLVM type. Actually, it should be "convert Clang type to LLVM type."
* However, clang doesn't make this API (lib/CodeGen/CodeGenTypes.h) public, we need to do by ourselves.
*
* Once we can get LLVM type, we can use LLVM to get alignment information, allocation size of a given type and structure
* layout that LLVM used (all of these information are target dependent) without deal with these by ourselves.
*/
virtual const llvm::Type* convertToLLVMType() const = 0;
public:
static bool NormalizeType(const Type*& T, llvm::StringRef& TypeName);
/* @T may not be normalized */
static RSExportType* Create(RSContext* Context, const Type* T);
static RSExportType* CreateFromDecl(RSContext* Context, const VarDecl* VD);
static const Type* GetTypeOfDecl(const DeclaratorDecl* DD);
virtual ExportClass getClass() const = 0;
inline const llvm::Type* getLLVMType() const {
if(mLLVMType == NULL)
mLLVMType = convertToLLVMType();
return mLLVMType;
}
/* Return the number of bits necessary to hold the specified RSExportType */
static size_t GetTypeStoreSize(const RSExportType* ET);
/* The size of allocation of specified RSExportType (alignment considered) */
static size_t GetTypeAllocSize(const RSExportType* ET);
const std::string& getName() const { return mName; }
inline RSContext* getRSContext() const { return mContext; }
}; /* RSExportType */
/* Primitive types */
class RSExportPrimitiveType : public RSExportType {
friend class RSExportType;
friend class RSExportElement;
public:
/* From graphics/java/android/renderscript/Element.java: Element.DataType */
typedef enum {
DataTypeUnknown = -1,
//DataTypeFloat16 = 1,
DataTypeFloat32 = 2,
//DataTypeFloat64 = 3,
DataTypeSigned8 = 4,
DataTypeSigned16 = 5,
DataTypeSigned32 = 6,
//DataTypeSigned64 = 7,
DataTypeUnsigned8 = 8,
DataTypeUnsigned16 = 9,
DataTypeUnsigned32 = 10,
//DataTypeUnSigned64 = 11,
DataTypeUnsigned565 = 12,
DataTypeUnsigned5551 = 13,
DataTypeUnsigned4444 = 14,
DataTypeBool = 15,
DataTypeRSElement = 16,
DataTypeRSType = 17,
DataTypeRSAllocation = 18,
DataTypeRSSampler = 19,
DataTypeRSScript = 20,
DataTypeRSMesh = 21,
DataTypeRSProgramFragment = 22,
DataTypeRSProgramVertex = 23,
DataTypeRSProgramRaster = 24,
DataTypeRSProgramStore = 25,
DataTypeRSFont = 26,
DataTypeMax
} DataType;
/* From graphics/java/android/renderscript/Element.java: Element.DataKind */
typedef enum {
DataKindUser = 0,
DataKindColor = 1,
DataKindPosition = 2,
DataKindTexture = 3,
DataKindNormal = 4,
DataKindIndex = 5,
DataKindPointSize = 6,
DataKindPixelL = 7,
DataKindPixelA = 8,
DataKindPixelLA = 9,
DataKindPixelRGB = 10,
DataKindPixelRGBA = 11
} DataKind;
private:
DataType mType;
DataKind mKind;
bool mNormalized;
typedef llvm::StringMap<DataType> RSObjectTypeMapTy;
static RSObjectTypeMapTy* RSObjectTypeMap;
static llvm::Type* RSObjectLLVMType;
static const size_t SizeOfDataTypeInBits[];
/*
* @T was normalized by calling RSExportType::TypeExportable() before calling this.
* @TypeName was retrieved from RSExportType::GetTypeName() before calling this
*/
static RSExportPrimitiveType* Create(RSContext* Context, const Type* T, const llvm::StringRef& TypeName, DataKind DK = DataKindUser, bool Normalized = false);
protected:
/* T is normalized by calling RSExportType::TypeExportable() before calling this */
static bool IsPrimitiveType(const Type* T);
static DataType GetDataType(const Type* T);
RSExportPrimitiveType(RSContext* Context, const llvm::StringRef& Name, DataType DT, DataKind DK, bool Normalized) :
RSExportType(Context, Name),
mType(DT),
mKind(DK),
mNormalized(Normalized)
{
return;
}
virtual const llvm::Type* convertToLLVMType() const;
public:
/* @T may not be normalized */
static RSExportPrimitiveType* Create(RSContext* Context, const Type* T, DataKind DK = DataKindUser);
static DataType GetRSObjectType(const llvm::StringRef& TypeName);
static DataType GetRSObjectType(const Type* T);
static size_t GetSizeInBits(const RSExportPrimitiveType* EPT);
virtual ExportClass getClass() const;
inline DataType getType() const { return mType; }
inline DataKind getKind() const { return mKind; }
inline bool isRSObjectType() const { return ((mType >= DataTypeRSElement) && (mType < DataTypeMax)); }
}; /* RSExportPrimitiveType */
class RSExportPointerType : public RSExportType {
friend class RSExportType;
friend class RSExportElement;
private:
const RSExportType* mPointeeType;
RSExportPointerType(RSContext* Context,
const llvm::StringRef& Name,
const RSExportType* PointeeType) :
RSExportType(Context, Name),
mPointeeType(PointeeType)
{
return;
}
/*
* @PT was normalized by calling RSExportType::TypeExportable() before calling this.
*/
static RSExportPointerType* Create(RSContext* Context, const PointerType* PT, const llvm::StringRef& TypeName);
virtual const llvm::Type* convertToLLVMType() const;
public:
static const Type* IntegerType;
virtual ExportClass getClass() const;
inline const RSExportType* getPointeeType() const { return mPointeeType; }
}; /* RSExportPointerType */
class RSExportVectorType : public RSExportPrimitiveType {
friend class RSExportType;
friend class RSExportElement;
private:
int mNumElement; /* number of element */
RSExportVectorType(RSContext* Context,
const llvm::StringRef& Name,
DataType DT,
DataKind DK,
bool Normalized,
int NumElement) :
RSExportPrimitiveType(Context, Name, DT, DK, Normalized),
mNumElement(NumElement)
{
return;
}
/*
* @EVT was normalized by calling RSExportType::TypeExportable() before calling this.
*/
static RSExportVectorType* Create(RSContext* Context, const ExtVectorType* EVT, const llvm::StringRef& TypeName, DataKind DK = DataKindUser, bool Normalized = false);
static const char* VectorTypeNameStore[][3];
virtual const llvm::Type* convertToLLVMType() const;
public:
static llvm::StringRef GetTypeName(const ExtVectorType* EVT);
virtual ExportClass getClass() const;
inline int getNumElement() const { return mNumElement; }
};
class RSExportRecordType : public RSExportType {
friend class RSExportType;
friend class RSExportElement;
friend class RSExportFunc;
public:
class Field {
private:
/* Link to the struct that contain this field */
const RSExportRecordType* mParent;
/* Index in the container */
unsigned int mIndex;
const RSExportType* mType;
/* Field name */
std::string mName;
public:
Field(const RSExportType* T, const llvm::StringRef& Name, const RSExportRecordType* Parent, unsigned int Index) :
mType(T),
mName(Name.data(), Name.size()),
mParent(Parent),
mIndex(Index)
{
return;
}
inline const RSExportRecordType* getParent() const { return mParent; }
inline unsigned int getIndex() const { return mIndex; }
inline const RSExportType* getType() const { return mType; }
inline const std::string& getName() const { return mName; }
size_t getOffsetInParent() const;
};
typedef std::list<const Field*>::const_iterator const_field_iterator;
inline const_field_iterator fields_begin() const { return this->mFields.begin(); }
inline const_field_iterator fields_end() const { return this->mFields.end(); }
private:
std::list<const Field*> mFields;
bool mIsPacked;
bool mIsArtificial; /* Artificial export struct type is not exported by user (and thus it won't get reflected) */
RSExportRecordType(RSContext* Context,
const llvm::StringRef& Name,
bool IsPacked,
bool IsArtificial = false) :
RSExportType(Context, Name),
mIsPacked(IsPacked),
mIsArtificial(IsArtificial)
{
return;
}
/*
* @RT was normalized by calling RSExportType::TypeExportable() before calling this.
* @TypeName was retrieved from RSExportType::GetTypeName() before calling this.
*/
static RSExportRecordType* Create(RSContext* Context, const RecordType* RT, const llvm::StringRef& TypeName, bool mIsArtificial = false);
virtual const llvm::Type* convertToLLVMType() const;
public:
virtual ExportClass getClass() const;
inline bool isPacked() const { return mIsPacked; }
inline bool isArtificial() const { return mIsArtificial; }
~RSExportRecordType() {
for(std::list<const Field*>::iterator it = mFields.begin();
it != mFields.end();
it++)
if(*it != NULL)
delete *it;
return;
}
}; /* RSExportRecordType */
} /* namespace slang */
#endif /* _SLANG_COMPILER_RS_EXPORT_TYPE_HPP */