slang_rs_export_type.cpp revision 8d75dc46a30e8617bd29dfe00492c5aab02dacf5
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <vector>
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_context.hpp"
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type.hpp"
5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_element.hpp"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Type.h"
8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/DerivedTypes.h"
9462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/ADT/StringExtras.h"  /* for function llvm::utostr_32() */
11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetData.h" /* for class llvm::TargetData and class llvm::StructLayout */
12462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
130a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao#include "clang/AST/RecordLayout.h"
140a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao
15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang {
16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportType ******************************/
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool RSExportType::NormalizeType(const Type*& T, llvm::StringRef& TypeName) {
19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::SmallPtrSet<const Type*, 8> SPS = llvm::SmallPtrSet<const Type*, 8>();
20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
211f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    if((T = RSExportType::TypeExportable(T, SPS)) == NULL)
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* TODO: warning the user: type not exportable */
23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Get type name */
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    TypeName = RSExportType::GetTypeName(T);
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(TypeName.empty())
28f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        /* TODO: warning the user: the type is unnamed */
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst Type* RSExportType::GetTypeOfDecl(const DeclaratorDecl* DD) {
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(DD && DD->getTypeSourceInfo()) {
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        QualType T = DD->getTypeSourceInfo()->getType();
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(T.isNull())
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return NULL;
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        else
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return T.getTypePtr();
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
42cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    return NULL;
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaollvm::StringRef RSExportType::GetTypeName(const Type* T) {
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    T = GET_CANONICAL_TYPE(T);
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(T == NULL)
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return llvm::StringRef();
49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(T->getTypeClass()) {
51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Builtin:
52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const BuiltinType* BT = UNSAFE_CAST_TYPE(BuiltinType, T);
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            switch(BT->getKind()) {
56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                case builtin_type:  \
58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* Compiler is smart enough to optimize following *big if branches* since they all become "constant comparison" after macro expansion */  \
59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    if(type == RSExportPrimitiveType::DataTypeFloat32) return "float";  \
6070842c7439bd523611f3ed232ecc6de844932145Stephen Hines                    else if(type == RSExportPrimitiveType::DataTypeFloat64) return "double";  \
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeUnsigned8) return "uchar";   \
62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeUnsigned16) return "ushort"; \
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeUnsigned32) return "uint";   \
64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeSigned8) return "char";  \
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeSigned16) return "short";    \
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeSigned32) return "int";  \
678d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines                    else if(type == RSExportPrimitiveType::DataTypeSigned64) return "long";  \
681f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao                    else if(type == RSExportPrimitiveType::DataTypeBool) return "bool";  \
698d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines                    else assert(false && "Unknown data type of supported builtin");  \
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                break;
71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type_support.inc"
72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7370842c7439bd523611f3ed232ecc6de844932145Stephen Hines                default: assert(false && "Unknown data type of the builtin"); break;
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Record:
79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RecordDecl* RD = T->getAsStructureType()->getDecl();
81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            llvm::StringRef Name = RD->getName();
82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(Name.empty()) {
831f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao                if(RD->getTypedefForAnonDecl() != NULL)
84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    Name = RD->getTypedefForAnonDecl()->getName();
85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                if(Name.empty())
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* Try to find a name from redeclaration (i.e. typedef) */
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    for(TagDecl::redecl_iterator RI = RD->redecls_begin();
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        RI != RD->redecls_end();
90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        RI++)
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    {
92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        assert(*RI != NULL && "cannot be NULL object");
93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        Name = (*RI)->getName();
95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        if(!Name.empty())
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                            break;
97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    }
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return Name;
100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Pointer:
104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* "*" plus pointee name */
106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const Type* PT = GET_POINTEE_TYPE(T);
107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            llvm::StringRef PointeeName;
108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(NormalizeType(PT, PointeeName)) {
1094d7dc59dd4d82aeeb7d77d1cfc048944e6e2bdbaShih-wei Liao                char* Name = new char[ 1 /* * */ + PointeeName.size() + 1 ];
110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                Name[0] = '*';
111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                memcpy(Name + 1, PointeeName.data(), PointeeName.size());
1124d7dc59dd4d82aeeb7d77d1cfc048944e6e2bdbaShih-wei Liao                Name[PointeeName.size() + 1] = '\0';
113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return Name;
114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
118f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        case Type::ConstantArray:
119f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        {
120f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            const ConstantArrayType* ECT = UNSAFE_CAST_TYPE(ConstantArrayType, T);
121f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            return RSExportConstantArrayType::GetTypeName(ECT);
122f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        }
123f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        break;
124f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::ExtVector:
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const ExtVectorType* EVT = UNSAFE_CAST_TYPE(ExtVectorType, T);
128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return RSExportVectorType::GetTypeName(EVT);
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return llvm::StringRef();
137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst Type* RSExportType::TypeExportable(const Type* T, llvm::SmallPtrSet<const Type*, 8>& SPS) {
140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Normailize first */
141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((T = GET_CANONICAL_TYPE(T)) == NULL)
142462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(SPS.count(T))
145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return T;
1461f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(T->getTypeClass()) {
148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Builtin:
149462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const BuiltinType* BT = UNSAFE_CAST_TYPE(BuiltinType, T);
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            switch(BT->getKind()) {
153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                case builtin_type:
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type_support.inc"
156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    return T;
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                break;
158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                default:
160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    return NULL;
161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                break;
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Record:
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(RSExportPrimitiveType::GetRSObjectType(T) != RSExportPrimitiveType::DataTypeUnknown)
169462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return T; /* RS object type, no further checks are needed */
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Check internal struct */
172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RecordDecl* RD = T->getAsStructureType()->getDecl();
173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(RD != NULL)
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                RD = RD->getDefinition();
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Fast check */
1771f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            if(RD->hasFlexibleArrayMember() || RD->hasObjectMember())
178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return NULL;
1791f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Insert myself into checking set */
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            SPS.insert(T);
182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Check all element */
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            for(RecordDecl::field_iterator F = RD->field_begin();
185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                F != RD->field_end();
186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                F++)
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            {
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                const Type* FT = GetTypeOfDecl(*F);
189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                FT = GET_CANONICAL_TYPE(FT);
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1911f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao                if(!TypeExportable(FT, SPS))
192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /*  TODO: warning: unsupported field type */
193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    return NULL;
194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return T;
197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Pointer:
201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const PointerType* PT = UNSAFE_CAST_TYPE(PointerType, T);
203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const Type* PointeeType = GET_POINTEE_TYPE(PT);
204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if((PointeeType->getTypeClass() != Type::Pointer) && (TypeExportable(PointeeType, SPS) == NULL) )
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return NULL;
207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return T;
208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
210462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
211f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        case Type::ConstantArray:
212f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        {
213f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            const ConstantArrayType* ECT = UNSAFE_CAST_TYPE(ConstantArrayType, T);
214f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            /* Check element numbers */
215f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            //            if (ECT->getNumElements() != 4 && ECT->getNumElements() != 9 && ECT->getNumElements() != 16) { /* only support 2x2, 3x3, 4x4 arrays */
216f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            //                return NULL;
217f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
218f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            /* Check base element type */
219f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            const Type* ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(ECT);
220f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
221f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            if((ElementType->getTypeClass() != Type::Builtin) || (TypeExportable(ElementType, SPS) == NULL))
222f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                return NULL;
223f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            return T;
224f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        }
225f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        break;
226f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::ExtVector:
228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const ExtVectorType* EVT = UNSAFE_CAST_TYPE(ExtVectorType, T);
230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Check element numbers */
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(EVT->getNumElements() < 2 || EVT->getNumElements() > 4)  /* only support vector with size 2, 3 and 4 */
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return NULL;
233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Check base element type */
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const Type* ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if((ElementType->getTypeClass() != Type::Builtin) || (TypeExportable(ElementType, SPS) == NULL))
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return NULL;
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return T;
240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return NULL;
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportType* RSExportType::Create(RSContext* Context, const Type* T, const llvm::StringRef& TypeName) {
2501f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    /*
2511f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao     * Lookup the context to see whether the type was processed before.
2521f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao     *  Newly create RSExportType will insert into context in RSExportType::RSExportType()
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao     */
254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSContext::export_type_iterator ETI = Context->findExportType(TypeName);
255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2561f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    if(ETI != Context->export_types_end())
257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return ETI->second;
258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSExportType* ET = NULL;
260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(T->getTypeClass()) {
261f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        case Type::Record: {
262f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            RSExportPrimitiveType::DataType dt = RSExportPrimitiveType::GetRSObjectType(TypeName);
263f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            switch (dt) {
264f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              case RSExportPrimitiveType::DataTypeUnknown:    // User-defined types
265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ET = RSExportRecordType::Create(Context, T->getAsStructureType(), TypeName);
266f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                break;
267f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              case RSExportPrimitiveType::DataTypeRSMatrix2x2:
268f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              case RSExportPrimitiveType::DataTypeRSMatrix3x3:
269f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              case RSExportPrimitiveType::DataTypeRSMatrix4x4: {
270f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                const clang::RecordType* RT = static_cast<const RecordType*> (T);
271f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                const RecordDecl* RD = RT->getDecl();
272f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                RD = RD->getDefinition();
273f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                RecordDecl::field_iterator fit = RD->field_begin();
274f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                FieldDecl* FD = *fit;
275f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                const Type* FT = RSExportType::GetTypeOfDecl(FD);
276f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                ET = RSExportConstantArrayType::Create(Context, static_cast<const ConstantArrayType*> (FT), TypeName);
277f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                break;
278f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              }
279f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao              default:
280f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                ET = RSExportPrimitiveType::Create(Context, T, TypeName);
281f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao                break;
282f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            }
283f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
284f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        }
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Builtin:
286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ET = RSExportPrimitiveType::Create(Context, T, TypeName);
287f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Pointer:
290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ET = RSExportPointerType::Create(Context, UNSAFE_CAST_TYPE(PointerType, T), TypeName);
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* free the name (allocated in RSExportType::GetTypeName) */
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            delete [] TypeName.data();
293f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
294f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
295f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao        case Type::ConstantArray:
296f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            ET = RSExportConstantArrayType::Create(Context, UNSAFE_CAST_TYPE(ConstantArrayType, T), TypeName);
297f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::ExtVector:
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ET = RSExportVectorType::Create(Context, UNSAFE_CAST_TYPE(ExtVectorType, T), TypeName);
301f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* TODO: warning: type is not exportable */
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            printf("RSExportType::Create : type '%s' is not exportable\n", T->getTypeClassName());
306f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao            break;
307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return ET;
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
3111f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportType* RSExportType::Create(RSContext* Context, const Type* T) {
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::StringRef TypeName;
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(NormalizeType(T, TypeName))
315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return Create(Context, T, TypeName);
316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
319462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportType* RSExportType::CreateFromDecl(RSContext* Context, const VarDecl* VD) {
321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return RSExportType::Create(Context, GetTypeOfDecl(VD));
322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType* ET) {
325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return ET->getRSContext()->getTargetData()->getTypeStoreSize(ET->getLLVMType());
326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType* ET) {
3290a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao    if(ET->getClass() == RSExportType::ExportClassRecord)
3300a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao        return static_cast<const RSExportRecordType*>(ET)->getAllocSize();
3310a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao    else
3320a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao        return ET->getRSContext()->getTargetData()->getTypeAllocSize(ET->getLLVMType());
333462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3351f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei LiaoRSExportType::RSExportType(RSContext* Context, const llvm::StringRef& Name) :
3361f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    mContext(Context),
3371f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    mName(Name.data(), Name.size()), /* make a copy on Name since data of @Name which is stored in ASTContext will be destroyed later */
338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mLLVMType(NULL)
3391f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao{
340462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* TODO: need to check whether the insertion is successful or not */
341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Context->insertExportType(Name, this);
3421f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    return;
343462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
344462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportPrimitiveType ******************************/
346462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType::RSObjectTypeMapTy* RSExportPrimitiveType::RSObjectTypeMap = NULL;
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaollvm::Type* RSExportPrimitiveType::RSObjectLLVMType = NULL;
348462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
349462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const Type* T) {
350462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((T != NULL) && (T->getTypeClass() == Type::Builtin))
351462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return true;
352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
353462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
354462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
355462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
356462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType::DataType RSExportPrimitiveType::GetRSObjectType(const llvm::StringRef& TypeName) {
357462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(TypeName.empty())
358462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return DataTypeUnknown;
359462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(RSObjectTypeMap == NULL) {
361462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        RSObjectTypeMap = new RSObjectTypeMapTy(16);
362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
363462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define USE_ELEMENT_DATA_TYPE
364462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define DEF_RS_OBJECT_TYPE(type, name)  \
365462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        RSObjectTypeMap->GetOrCreateValue(name, GET_ELEMENT_DATA_TYPE(type));
366462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_element_support.inc"
367462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
368462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
369462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSObjectTypeMapTy::const_iterator I = RSObjectTypeMap->find(TypeName);
370462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(I == RSObjectTypeMap->end())
371462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return DataTypeUnknown;
372462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
373462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return I->getValue();
374462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
375462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
376462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType::DataType RSExportPrimitiveType::GetRSObjectType(const Type* T) {
377462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    T = GET_CANONICAL_TYPE(T);
378462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((T == NULL) || (T->getTypeClass() != Type::Record))
379462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return DataTypeUnknown;
380462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
381462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return GetRSObjectType( RSExportType::GetTypeName(T) );
382462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
383462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3841f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liaoconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[RSExportPrimitiveType::DataTypeMax + 1] = {
385462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    0,
3861f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeFloat16 */
3871f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeFloat32 */
3881f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    64, /* DataTypeFloat64 */
3891f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    8, /* DataTypeSigned8 */
3901f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeSigned16 */
3911f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeSigned32 */
3921f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    64, /* DataTypeSigned64 */
3931f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    8, /* DataTypeUnsigned8 */
3941f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeUnsigned16 */
3951f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeUnsigned32 */
3961f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    64, /* DataTypeUnSigned64 */
3971f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
3981f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeUnsigned565 */
3991f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeUnsigned5551 */
4001f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    16, /* DataTypeUnsigned4444 */
4011f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
4021f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    1, /* DataTypeBool */
4031f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
4041f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSElement */
4051f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSType */
4061f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSAllocation */
4071f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSSampler */
4081f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSScript */
4091f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSMesh */
4101f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSProgramFragment */
4111f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSProgramVertex */
4121f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSProgramRaster */
4131f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSProgramStore */
4141f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    32, /* DataTypeRSFont */
415116d3d2fcbde4970b07263deeeabc341ff8d76e9Shih-wei Liao    128, /* DataTypeRSMatrix2x2 */
416116d3d2fcbde4970b07263deeeabc341ff8d76e9Shih-wei Liao    288, /* DataTypeRSMatrix3x3 */
417116d3d2fcbde4970b07263deeeabc341ff8d76e9Shih-wei Liao    512, /* DataTypeRSMatrix4x4 */
418462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    0
419462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao};
420462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4211f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType* EPT) {
4221f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    assert(((EPT->getType() >= DataTypeFloat32) && (EPT->getType() < DataTypeMax)) && "RSExportPrimitiveType::GetSizeInBits : unknown data type");
4231f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ];
424462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
425462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
426462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType::DataType RSExportPrimitiveType::GetDataType(const Type* T) {
427462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(T == NULL)
428462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return DataTypeUnknown;
429462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
430462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(T->getTypeClass()) {
431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Builtin:
432462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
433462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const BuiltinType* BT = UNSAFE_CAST_TYPE(BuiltinType, T);
434462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            switch(BT->getKind()) {
435462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
436462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                case builtin_type:  \
437462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    return type;  \
438462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                break;
439462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type_support.inc"
440462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
441462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                /* The size of types Long, ULong and WChar depend on platform so we abandon the support to them */
442462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                /* Type of its size exceeds 32 bits (e.g. int64_t, double, etc.) does not support */
443462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
444462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                default:
445462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* TODO: warning the user: unsupported type */
446462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    printf("RSExportPrimitiveType::GetDataType : built-in type has no corresponding data type for built-in type");
447462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                break;
448462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
449462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
450462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
451462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
452462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case Type::Record:
453462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* must be RS object type */
454462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return RSExportPrimitiveType::GetRSObjectType(T);
455462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
456462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
457462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
458462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            printf("RSExportPrimitiveType::GetDataType : type '%s' is not supported primitive type", T->getTypeClassName());
459462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
460462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
461462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
462462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return DataTypeUnknown;
463462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
464462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
465462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType* RSExportPrimitiveType::Create(RSContext* Context, const Type* T, const llvm::StringRef& TypeName, DataKind DK, bool Normalized) {
466462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    DataType DT = GetDataType(T);
467462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
468462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((DT == DataTypeUnknown) || TypeName.empty())
469462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
470462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
471462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return new RSExportPrimitiveType(Context, TypeName, DT, DK, Normalized);
472462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
473462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
474462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPrimitiveType* RSExportPrimitiveType::Create(RSContext* Context, const Type* T, DataKind DK) {
475462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::StringRef TypeName;
476462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(RSExportType::NormalizeType(T, TypeName) && IsPrimitiveType(T))
477462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return Create(Context, T, TypeName, DK);
478462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
479462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
480462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
481462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4821f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei LiaoRSExportType::ExportClass RSExportPrimitiveType::getClass() const {
4831f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    return RSExportType::ExportClassPrimitive;
484462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
485462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
486462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst llvm::Type* RSExportPrimitiveType::convertToLLVMType() const {
487462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::LLVMContext& C = getRSContext()->getLLVMContext();
488462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
489462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(isRSObjectType()) {
490462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* struct { int* p; } __attribute__((packed, aligned(pointer_size))) which is <{ [1 x i32] }> in LLVM */
491462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(RSObjectLLVMType == NULL) {
492462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            std::vector<const llvm::Type*> Elements;
493462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            Elements.push_back( llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1) );
494462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            RSObjectLLVMType = llvm::StructType::get(C, Elements, true);
495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
496462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return RSObjectLLVMType;
497462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
498462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
499462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(mType) {
5001f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao        case DataTypeFloat32:
5011f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            return llvm::Type::getFloatTy(C);
502462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
503462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
50470842c7439bd523611f3ed232ecc6de844932145Stephen Hines        case DataTypeFloat64:
50570842c7439bd523611f3ed232ecc6de844932145Stephen Hines            return llvm::Type::getDoubleTy(C);
50670842c7439bd523611f3ed232ecc6de844932145Stephen Hines        break;
50770842c7439bd523611f3ed232ecc6de844932145Stephen Hines
508462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeSigned8:
509462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned8:
5101f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            return llvm::Type::getInt8Ty(C);
511462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
512462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
513462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeSigned16:
514462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned16:
515462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned565:
516462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned5551:
517462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned4444:
5181f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            return llvm::Type::getInt16Ty(C);
519462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
520462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
521462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeSigned32:
522462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case DataTypeUnsigned32:
5231f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            return llvm::Type::getInt32Ty(C);
5241f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao        break;
5251f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
5268d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines        case DataTypeSigned64:
5278d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines        // case DataTypeUnsigned64:
5288d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines            return llvm::Type::getInt64Ty(C);
5298d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines        break;
5308d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines
5311f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao        case DataTypeBool:
5321f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            return llvm::Type::getInt1Ty(C);
533462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
534462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
535462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
536462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            assert(false && "Unknown data type");
537462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
538462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
539462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
540462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return NULL;
541462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
542462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
543462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportPointerType ******************************/
544462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
545462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst Type* RSExportPointerType::IntegerType = NULL;
546462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
547462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportPointerType* RSExportPointerType::Create(RSContext* Context, const PointerType* PT, const llvm::StringRef& TypeName) {
548462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const Type* PointeeType = GET_POINTEE_TYPE(PT);
549462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const RSExportType* PointeeET;
550462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
551462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(PointeeType->getTypeClass() != Type::Pointer) {
552462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        PointeeET = RSExportType::Create(Context, PointeeType);
553462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    } else {
554462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* Double or higher dimension of pointer, export as int* */
555462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        assert(IntegerType != NULL && "Built-in integer type is not set");
556462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        PointeeET = RSExportPrimitiveType::Create(Context, IntegerType);
557462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
558462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
559462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(PointeeET == NULL) {
560462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        printf("Failed to create type for pointee");
561462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
562462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
563462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
564462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return new RSExportPointerType(Context, TypeName, PointeeET);
565462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
566462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5671f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei LiaoRSExportType::ExportClass RSExportPointerType::getClass() const {
568462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return RSExportType::ExportClassPointer;
569462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
570462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
571462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst llvm::Type* RSExportPointerType::convertToLLVMType() const {
572462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const llvm::Type* PointeeType = mPointeeType->getLLVMType();
573462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return llvm::PointerType::getUnqual(PointeeType);
574462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
575462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
576f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao/****************************** RSExportConstantArrayType ******************************/
577f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liaollvm::StringRef RSExportConstantArrayType::GetTypeName(const ConstantArrayType* CT) {
578f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  llvm::APInt i = CT->getSize();
579f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  if (i == 4) {
580f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    return llvm::StringRef("rs_matrix2x2");
581f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  } else if (i == 9) {
582f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    return llvm::StringRef("rs_matrix3x3");
583f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  } else if (i == 16) {
584f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao      return llvm::StringRef("rs_matrix4x4");
585f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  }
586f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  return llvm::StringRef();
587f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao}
588f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
589f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei LiaoRSExportConstantArrayType* RSExportConstantArrayType::Create(RSContext* Context, const ConstantArrayType* CT, const llvm::StringRef& TypeName, DataKind DK, bool Normalized) {
590f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    assert(CT != NULL && CT->getTypeClass() == Type::ConstantArray);
591f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
592cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    int64_t Size = CT->getSize().getSExtValue();
593f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    RSExportPrimitiveType::DataType DT;
594cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    if (Size == 4) {
595f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao      DT = RSExportPrimitiveType::DataTypeRSMatrix2x2;
596cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    } else if (Size == 9) {
597f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao      DT = RSExportPrimitiveType::DataTypeRSMatrix3x3;
598cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    } else if (Size == 16) {
599f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao      DT = RSExportPrimitiveType::DataTypeRSMatrix4x4;
600f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    } else {
601f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao      printf("RSExportConstantArrayType::Create : unsupported base element type\n");
602f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    }
603f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
604cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    return new RSExportConstantArrayType(Context, TypeName, DT, DK, Normalized, Size);
605f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao}
606f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
607f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei LiaoRSExportType::ExportClass RSExportConstantArrayType::getClass() const {
608f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    return RSExportType::ExportClassConstantArray;
609f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao}
610f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
611f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liaoconst llvm::Type* RSExportConstantArrayType::convertToLLVMType() const {
612f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao  llvm::LLVMContext& C = getRSContext()->getLLVMContext();
6131ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao  const llvm::Type *typ;
6141ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao  switch (getType()) {
6151ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeFloat32:
6161ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeRSMatrix2x2:
6171ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeRSMatrix3x3:
6181ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeRSMatrix4x4:
6191ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      typ = llvm::Type::getFloatTy(C);
6201ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6211ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
62270842c7439bd523611f3ed232ecc6de844932145Stephen Hines    case DataTypeFloat64:
62370842c7439bd523611f3ed232ecc6de844932145Stephen Hines      typ = llvm::Type::getDoubleTy(C);
62470842c7439bd523611f3ed232ecc6de844932145Stephen Hines      break;
62570842c7439bd523611f3ed232ecc6de844932145Stephen Hines
6261ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeSigned8:
6271ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned8:
6281ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      typ = llvm::Type::getInt8Ty(C);
6291ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6301ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
6311ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeSigned16:
6321ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned16:
6331ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned565:
6341ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned5551:
6351ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned4444:
6361ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      typ = llvm::Type::getInt16Ty(C);
6371ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6381ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
6391ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeSigned32:
6401ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeUnsigned32:
6411ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      typ = llvm::Type::getInt32Ty(C);
6421ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6431ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
6448d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines    case DataTypeSigned64:
6458d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines    //case DataTypeUnsigned64:
6468d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines      typ = llvm::Type::getInt64Ty(C);
6478d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines      break;
6488d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines
6491ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    case DataTypeBool:
6501ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      typ = llvm::Type::getInt1Ty(C);
6511ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6521ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
6531ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    default:
6541ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      assert(false && "Unknown data type");
6551ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao      break;
6561ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao  }
6571ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao  return llvm::ArrayType::get(typ, mNumElement);
658f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao}
659f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao
660462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportVectorType ******************************/
6611f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liaoconst char* RSExportVectorType::VectorTypeNameStore[][3] = {
662462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 0 */ { "char2",      "char3",    "char4" },
663462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 1 */ { "uchar2",     "uchar3",   "uchar4" },
664462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 2 */ { "short2",     "short3",   "short4" },
665462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 3 */ { "ushort2",    "ushort3",  "ushort4" },
666462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 4 */ { "int2",       "int3",     "int4" },
667462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 5 */ { "uint2",      "uint3",    "uint4" },
668462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* 6 */ { "float2",     "float3",   "float4" },
66970842c7439bd523611f3ed232ecc6de844932145Stephen Hines    /* 7 */ { "double2",    "double3",  "double4" },
6708d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines    /* 8 */ { "long2",      "long3",    "long4" },
6711f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao};
672462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
673462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaollvm::StringRef RSExportVectorType::GetTypeName(const ExtVectorType* EVT) {
674462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const Type* ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
675462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
676462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((ElementType->getTypeClass() != Type::Builtin))
677462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return llvm::StringRef();
678462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
679462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const BuiltinType* BT = UNSAFE_CAST_TYPE(BuiltinType, ElementType);
680462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const char** BaseElement = NULL;
681462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
682462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(BT->getKind()) {
683462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
684462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case builtin_type:  \
685462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* Compiler is smart enough to optimize following *big if branches* since they all become "constant comparison" after macro expansion */  \
686462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(type == RSExportPrimitiveType::DataTypeSigned8) BaseElement = VectorTypeNameStore[0];    \
687462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeUnsigned8) BaseElement = VectorTypeNameStore[1]; \
688462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeSigned16) BaseElement = VectorTypeNameStore[2];  \
689462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeUnsigned16) BaseElement = VectorTypeNameStore[3];    \
690462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeSigned32) BaseElement = VectorTypeNameStore[4];  \
691462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeUnsigned32) BaseElement = VectorTypeNameStore[5];    \
692462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeFloat32) BaseElement = VectorTypeNameStore[6];   \
69370842c7439bd523611f3ed232ecc6de844932145Stephen Hines            else if(type == RSExportPrimitiveType::DataTypeFloat64) BaseElement = VectorTypeNameStore[7];   \
6948d75dc46a30e8617bd29dfe00492c5aab02dacf5Stephen Hines            else if(type == RSExportPrimitiveType::DataTypeSigned64) BaseElement = VectorTypeNameStore[8];   \
6951f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao            else if(type == RSExportPrimitiveType::DataTypeBool) BaseElement = VectorTypeNameStore[0];   \
696462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
697462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type_support.inc"
698462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
699462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default: return llvm::StringRef(); break;
700462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
701462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
702462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((BaseElement != NULL) && (EVT->getNumElements() > 1) && (EVT->getNumElements() <= 4))
703462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return BaseElement[EVT->getNumElements() - 2];
704462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
705462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return llvm::StringRef();
706462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
707462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
708462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportVectorType* RSExportVectorType::Create(RSContext* Context, const ExtVectorType* EVT, const llvm::StringRef& TypeName, DataKind DK, bool Normalized) {
709462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    assert(EVT != NULL && EVT->getTypeClass() == Type::ExtVector);
710462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
711462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const Type* ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
712462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSExportPrimitiveType::DataType DT = RSExportPrimitiveType::GetDataType(ElementType);
713462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7141f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    if(DT != RSExportPrimitiveType::DataTypeUnknown)
715462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return new RSExportVectorType(Context, TypeName, DT, DK, Normalized, EVT->getNumElements());
716462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
717462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        printf("RSExportVectorType::Create : unsupported base element type\n");
718cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    return NULL;
719462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
720462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7211f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei LiaoRSExportType::ExportClass RSExportVectorType::getClass() const {
7221f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao    return RSExportType::ExportClassVector;
723462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
724462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
725462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst llvm::Type* RSExportVectorType::convertToLLVMType() const {
726462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const llvm::Type* ElementType = RSExportPrimitiveType::convertToLLVMType();
727462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return llvm::VectorType::get(ElementType, getNumElement());
728462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
729462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
730462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportRecordType ******************************/
731462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportRecordType* RSExportRecordType::Create(RSContext* Context, const RecordType* RT, const llvm::StringRef& TypeName, bool mIsArtificial) {
732462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    assert(RT != NULL && RT->getTypeClass() == Type::Record);
733462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
734462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const RecordDecl* RD = RT->getDecl();
735462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    assert(RD->isStruct());
736462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
737462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RD = RD->getDefinition();
738462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(RD == NULL) {
739462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* TODO: warning: actual struct definition isn't declared in this moudle */
740462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        printf("RSExportRecordType::Create : this struct is not defined in this module.");
741462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return NULL;
742462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
743462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
744462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSExportRecordType* ERT = new RSExportRecordType(Context, TypeName, RD->hasAttr<PackedAttr>(), mIsArtificial);
745462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    unsigned int Index = 0;
746462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
747462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    for(RecordDecl::field_iterator fit = RD->field_begin();
748462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        fit != RD->field_end();
749462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        fit++, Index++)
750462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    {
751462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define FAILED_CREATE_FIELD(err)    do {    \
752462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                        if(*err) \
753462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                            printf("RSExportRecordType::Create : failed to create field (%s)\n", err);   \
754462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                        delete ERT;  \
755462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                        return NULL;    \
756462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                    } while(false)
757462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* FIXME: All fields should be primitive type */
758462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        assert((*fit)->getKind() == Decl::Field);
759462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        FieldDecl* FD = *fit;
760462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
761462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* We don't support bit field TODO: allow bitfield with size 8, 16, 32 */
762462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(FD->isBitField())
763462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            FAILED_CREATE_FIELD("bit field is not supported");
764462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
765462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* Type */
766462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        RSExportType* ET = RSExportElement::CreateFromDecl(Context, FD);
767462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
768462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(ET != NULL)
769462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ERT->mFields.push_back( new Field(ET, FD->getName(), ERT, Index) );
770462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        else
771462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            FAILED_CREATE_FIELD(FD->getName().str().c_str());
772462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#undef FAILED_CREATE_FIELD
773462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
774462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7750a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao
7760a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao    const ASTRecordLayout &ASTRL = Context->getASTContext()->getASTRecordLayout(RD);
7770a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao    ERT->AllocSize = (ASTRL.getSize() > ASTRL.getDataSize()) ? (ASTRL.getSize() >> 3) : (ASTRL.getDataSize() >> 3);
7780a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao
779462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return ERT;
780462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
781462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
782462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportType::ExportClass RSExportRecordType::getClass() const {
783462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return RSExportType::ExportClassRecord;
784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
785462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
786462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst llvm::Type* RSExportRecordType::convertToLLVMType() const {
787462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    std::vector<const llvm::Type*> FieldTypes;
788462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
789462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    for(const_field_iterator FI = fields_begin();
790462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        FI != fields_end();
791462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        FI++)
792462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    {
793462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        const Field* F = *FI;
794462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        const RSExportType* FET = F->getType();
7951f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao
796462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        FieldTypes.push_back(FET->getLLVMType());
797462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
798462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
799462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return llvm::StructType::get(getRSContext()->getLLVMContext(), FieldTypes, mIsPacked);
800462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
801462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
802462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/****************************** RSExportRecordType::Field ******************************/
803462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaosize_t RSExportRecordType::Field::getOffsetInParent() const {
804462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Struct layout obtains below will be cached by LLVM */
805462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const llvm::StructLayout* SL = mParent->getRSContext()->getTargetData()->getStructLayout(static_cast<const llvm::StructType*>(mParent->getLLVMType()));
806462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return SL->getElementOffset(mIndex);
807462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
808462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
809462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}   /* namespace slang */
810