blob: e9af953857d5c0ab047371e57107588046d294d1 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hinesd5a84f62012-04-04 17:44:38 -07002 * Copyright 2010-2012, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Stephen Hinese639eb52010-11-08 19:27:20 -080017#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_
Shih-wei Liao462aefd2010-06-04 15:32:04 -070019
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070020#include <list>
Stephen Hinese639eb52010-11-08 19:27:20 -080021#include <set>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022#include <string>
Stephen Hinesa6b54142012-04-09 18:25:08 -070023#include <sstream>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070024
zonr6315f762010-10-05 15:35:14 +080025#include "clang/AST/Decl.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080026#include "clang/AST/Type.h"
27
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringMap.h"
30#include "llvm/ADT/StringRef.h"
31
32#include "llvm/Support/ManagedStatic.h"
zonr6315f762010-10-05 15:35:14 +080033
Zonr Changa41ce1d2010-10-06 02:23:12 +080034#include "slang_rs_exportable.h"
35
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070036#define GET_CANONICAL_TYPE(T) \
Zonr Chang2e1dba62010-10-05 22:20:11 +080037 (((T) == NULL) ? NULL : (T)->getCanonicalTypeInternal().getTypePtr())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038#define UNSAFE_CAST_TYPE(TT, T) \
Zonr Chang2e1dba62010-10-05 22:20:11 +080039 static_cast<TT*>(T->getCanonicalTypeInternal().getTypePtr())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070040#define GET_EXT_VECTOR_ELEMENT_TYPE(T) \
Zonr Chang2e1dba62010-10-05 22:20:11 +080041 (((T) == NULL) ? NULL : \
42 GET_CANONICAL_TYPE((T)->getElementType().getTypePtr()))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043#define GET_POINTEE_TYPE(T) \
Zonr Chang2e1dba62010-10-05 22:20:11 +080044 (((T) == NULL) ? NULL : \
45 GET_CANONICAL_TYPE((T)->getPointeeType().getTypePtr()))
46#define GET_CONSTANT_ARRAY_ELEMENT_TYPE(T) \
47 (((T) == NULL) ? NULL : \
48 GET_CANONICAL_TYPE((T)->getElementType().getTypePtr()))
Zonr Chang0da0a7d2010-10-05 21:26:37 +080049#define DUMMY_RS_TYPE_NAME_PREFIX "<"
50#define DUMMY_RS_TYPE_NAME_POSTFIX ">"
Zonr Chang2e1dba62010-10-05 22:20:11 +080051#define DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE \
52 DUMMY_RS_TYPE_NAME_PREFIX"ConstantArray"DUMMY_RS_TYPE_NAME_POSTFIX
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Zonr Changa7a828d2010-10-22 03:44:27 +080054union RSType;
55
Shih-wei Liao462aefd2010-06-04 15:32:04 -070056namespace llvm {
zonr6315f762010-10-05 15:35:14 +080057 class Type;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070058} // namespace llvm
Shih-wei Liao462aefd2010-06-04 15:32:04 -070059
60namespace slang {
61
zonr6315f762010-10-05 15:35:14 +080062 class RSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070063
Stephen Hinesfdd1ba12012-03-08 17:26:32 -080064typedef struct {
65 const char * rs_type;
66 const char * rs_short_type;
67 uint32_t size_in_bits;
68 const char * c_name;
69 const char * java_name;
70 const char * rs_c_vector_prefix;
71 const char * rs_java_vector_prefix;
72 bool java_promotion;
73} RSReflectionType;
74
Jason Sams1b6a0882012-03-12 15:07:58 -070075
76typedef struct RSReflectionTypeData_rec {
77 const RSReflectionType *type;
78 uint32_t vecSize;
79 bool isPointer;
80 uint32_t arraySize;
81
82 // Subelements
83 //std::vector<const struct RSReflectionTypeData_rec *> fields;
84 //std::vector< std::string > fieldNames;
85 //std::vector< uint32_t> fieldOffsetBytes;
86} RSReflectionTypeData;
87
88
Zonr Changa41ce1d2010-10-06 02:23:12 +080089class RSExportType : public RSExportable {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070090 friend class RSExportElement;
91 public:
92 typedef enum {
93 ExportClassPrimitive,
94 ExportClassPointer,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070095 ExportClassVector,
Zonr Chang92b344a2010-10-05 20:39:03 +080096 ExportClassMatrix,
Zonr Chang2e1dba62010-10-05 22:20:11 +080097 ExportClassConstantArray,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070098 ExportClassRecord
99 } ExportClass;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700100
Jason Sams1b6a0882012-03-12 15:07:58 -0700101 void convertToRTD(RSReflectionTypeData *rtd) const;
102
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700103 private:
Zonr Chang6b6320a2010-10-05 22:42:01 +0800104 ExportClass mClass;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 std::string mName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700106
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700107 // Cache the result after calling convertToLLVMType() at the first time
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700108 mutable llvm::Type *mLLVMType;
Zonr Changa7a828d2010-10-22 03:44:27 +0800109 // Cache the result after calling convertToSpecType() at the first time
110 mutable union RSType *mSpecType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700111
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700112 protected:
Zonr Chang6b6320a2010-10-05 22:42:01 +0800113 RSExportType(RSContext *Context,
114 ExportClass Class,
115 const llvm::StringRef &Name);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700116
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700117 // Let's make it private since there're some prerequisites to call this
118 // function.
119 //
Stephen Hinese5e64432010-12-02 18:48:20 -0800120 // @T was normalized by calling RSExportType::NormalizeType().
zonr6315f762010-10-05 15:35:14 +0800121 // @TypeName was retrieve from RSExportType::GetTypeName() before calling
122 // this.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700123 //
124 static RSExportType *Create(RSContext *Context,
125 const clang::Type *T,
zonr6315f762010-10-05 15:35:14 +0800126 const llvm::StringRef &TypeName);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700127
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700128 static llvm::StringRef GetTypeName(const clang::Type *T);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700129
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130 // This function convert the RSExportType to LLVM type. Actually, it should be
131 // "convert Clang type to LLVM type." However, clang doesn't make this API
132 // (lib/CodeGen/CodeGenTypes.h) public, we need to do by ourselves.
133 //
134 // Once we can get LLVM type, we can use LLVM to get alignment information,
135 // allocation size of a given type and structure layout that LLVM used
136 // (all of these information are target dependent) without dealing with these
137 // by ourselves.
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700138 virtual llvm::Type *convertToLLVMType() const = 0;
Stephen Hinese639eb52010-11-08 19:27:20 -0800139 // Record type may recursively reference its type definition. We need a
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800140 // temporary type setup before the type construction gets done.
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700141 inline void setAbstractLLVMType(llvm::Type *LLVMType) const {
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800142 mLLVMType = LLVMType;
143 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700144
Zonr Changa7a828d2010-10-22 03:44:27 +0800145 virtual union RSType *convertToSpecType() const = 0;
146 inline void setSpecTypeTemporarily(union RSType *SpecType) const {
147 mSpecType = SpecType;
148 }
149
150 virtual ~RSExportType();
Stephen Hinesecddee32011-07-20 18:30:09 -0700151
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700152 public:
Stephen Hinese5e64432010-12-02 18:48:20 -0800153 // This function additionally verifies that the Type T is exportable.
154 // If it is not, this function returns false. Otherwise it returns true.
155 static bool NormalizeType(const clang::Type *&T,
156 llvm::StringRef &TypeName,
Logan Chien9207a2e2011-10-21 15:39:28 +0800157 clang::DiagnosticsEngine *Diags,
Stephen Hines5bfec8d2012-04-04 08:18:57 -0700158 const clang::VarDecl *VD);
Stephen Hines78e69cb2011-04-22 15:03:19 -0700159
Stephen Hines11274a72012-09-26 19:14:20 -0700160 // This function checks whether the specified type can be handled by RS/FS.
161 // If it cannot, this function returns false. Otherwise it returns true.
162 // Filterscript has additional restrictions on supported types.
163 static bool ValidateType(clang::ASTContext &C, clang::QualType QT,
164 clang::NamedDecl *ND, clang::SourceLocation Loc,
165 unsigned int TargetAPI, bool IsFilterscript);
166
Stephen Hines78e69cb2011-04-22 15:03:19 -0700167 // This function ensures that the VarDecl can be properly handled by RS.
168 // If it cannot, this function returns false. Otherwise it returns true.
Stephen Hines11274a72012-09-26 19:14:20 -0700169 // Filterscript has additional restrictions on supported types.
170 static bool ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI,
171 bool IsFilterscript);
Stephen Hines78e69cb2011-04-22 15:03:19 -0700172
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173 // @T may not be normalized
174 static RSExportType *Create(RSContext *Context, const clang::Type *T);
175 static RSExportType *CreateFromDecl(RSContext *Context,
176 const clang::VarDecl *VD);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700177
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700178 static const clang::Type *GetTypeOfDecl(const clang::DeclaratorDecl *DD);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700179
Zonr Chang6b6320a2010-10-05 22:42:01 +0800180 inline ExportClass getClass() const { return mClass; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700181
Stephen Hines0d26cef2012-05-01 19:23:01 -0700182 virtual unsigned getSize() const { return 1; }
183
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700184 inline llvm::Type *getLLVMType() const {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185 if (mLLVMType == NULL)
186 mLLVMType = convertToLLVMType();
187 return mLLVMType;
188 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700189
Zonr Changa7a828d2010-10-22 03:44:27 +0800190 inline const union RSType *getSpecType() const {
191 if (mSpecType == NULL)
192 mSpecType = convertToSpecType();
193 return mSpecType;
194 }
195
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700196 // Return the number of bits necessary to hold the specified RSExportType
197 static size_t GetTypeStoreSize(const RSExportType *ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700198
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700199 // The size of allocation of specified RSExportType (alignment considered)
200 static size_t GetTypeAllocSize(const RSExportType *ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700201
Zonr Chang641558f2010-10-12 21:07:06 +0800202 inline const std::string &getName() const { return mName; }
203
Stephen Hinesa6b54142012-04-09 18:25:08 -0700204 virtual std::string getElementName() const {
205 // Base case is actually an invalid C/Java identifier.
206 return "@@INVALID@@";
207 }
208
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800209 virtual bool keep();
Zonr Chang641558f2010-10-12 21:07:06 +0800210 virtual bool equals(const RSExportable *E) const;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700211}; // RSExportType
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700212
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700213// Primitive types
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700214class RSExportPrimitiveType : public RSExportType {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700215 friend class RSExportType;
216 friend class RSExportElement;
217 public:
218 // From graphics/java/android/renderscript/Element.java: Element.DataType
219 typedef enum {
Stephen Hinesfeaca062011-02-04 14:08:13 -0800220 DataTypeIsStruct = -2,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700221 DataTypeUnknown = -1,
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700222
Zonr Changb1771ef2010-10-22 18:03:46 +0800223#define ENUM_PRIMITIVE_DATA_TYPE_RANGE(begin_type, end_type) \
224 FirstPrimitiveType = DataType ## begin_type, \
225 LastPrimitiveType = DataType ## end_type,
226
227#define ENUM_RS_MATRIX_DATA_TYPE_RANGE(begin_type, end_type) \
228 FirstRSMatrixType = DataType ## begin_type, \
229 LastRSMatrixType = DataType ## end_type,
230
231#define ENUM_RS_OBJECT_DATA_TYPE_RANGE(begin_type, end_type) \
232 FirstRSObjectType = DataType ## begin_type, \
233 LastRSObjectType = DataType ## end_type,
234
Zonr Changa65ec162010-10-17 01:53:05 +0800235#define ENUM_RS_DATA_TYPE(type, cname, bits) \
236 DataType ## type,
Zonr Changb1771ef2010-10-22 18:03:46 +0800237
Zonr Changa65ec162010-10-17 01:53:05 +0800238#include "RSDataTypeEnums.inc"
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700239
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700240 DataTypeMax
241 } DataType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700242
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700243 private:
Zonr Changa65ec162010-10-17 01:53:05 +0800244 // NOTE: There's no any instance of RSExportPrimitiveType which mType
245 // is of the value DataTypeRSMatrix*. DataTypeRSMatrix* enumeration here is
246 // only for RSExportPrimitiveType::GetRSObjectType to *recognize* the struct
247 // rs_matrix{2x2, 3x3, 4x4}. These matrix type are represented as
248 // RSExportMatrixType.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700249 DataType mType;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700250 bool mNormalized;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700251
Zonr Changb1771ef2010-10-22 18:03:46 +0800252 typedef llvm::StringMap<DataType> RSSpecificTypeMapTy;
253 static llvm::ManagedStatic<RSSpecificTypeMapTy> RSSpecificTypeMap;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700254
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700255 static llvm::Type *RSObjectLLVMType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700256
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700257 static const size_t SizeOfDataTypeInBits[];
Stephen Hinese5e64432010-12-02 18:48:20 -0800258 // @T was normalized by calling RSExportType::NormalizeType() before calling
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700259 // this.
260 // @TypeName was retrieved from RSExportType::GetTypeName() before calling
261 // this
262 static RSExportPrimitiveType *Create(RSContext *Context,
263 const clang::Type *T,
264 const llvm::StringRef &TypeName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700265 bool Normalized = false);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700266
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700267 protected:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700268 RSExportPrimitiveType(RSContext *Context,
Zonr Chang6b6320a2010-10-05 22:42:01 +0800269 // for derived class to set their type class
270 ExportClass Class,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700271 const llvm::StringRef &Name,
272 DataType DT,
zonr6315f762010-10-05 15:35:14 +0800273 bool Normalized)
Zonr Chang6b6320a2010-10-05 22:42:01 +0800274 : RSExportType(Context, Class, Name),
zonr6315f762010-10-05 15:35:14 +0800275 mType(DT),
zonr6315f762010-10-05 15:35:14 +0800276 mNormalized(Normalized) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 return;
278 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700279
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700280 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800281 virtual union RSType *convertToSpecType() const;
Stephen Hines2ef9bc02010-12-13 18:33:23 -0800282
283 static DataType GetDataType(RSContext *Context, const clang::Type *T);
284
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700285 public:
Stephen Hinesdd6206b2010-12-09 19:39:22 -0800286 // T is normalized by calling RSExportType::NormalizeType() before
287 // calling this
288 static bool IsPrimitiveType(const clang::Type *T);
289
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700290 // @T may not be normalized
291 static RSExportPrimitiveType *Create(RSContext *Context,
Stephen Hines2b8fb642012-03-09 00:12:47 -0800292 const clang::Type *T);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700293
Zonr Changb1771ef2010-10-22 18:03:46 +0800294 static DataType GetRSSpecificType(const llvm::StringRef &TypeName);
295 static DataType GetRSSpecificType(const clang::Type *T);
296
297 static bool IsRSMatrixType(DataType DT);
298 static bool IsRSObjectType(DataType DT);
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800299 static bool IsRSObjectType(const clang::Type *T) {
300 return IsRSObjectType(GetRSSpecificType(T));
301 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700302
Stephen Hinesfeaca062011-02-04 14:08:13 -0800303 // Determines whether T is [an array of] struct that contains at least one
304 // RS object type within it.
305 static bool IsStructureTypeWithRSObject(const clang::Type *T);
306
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700307 static size_t GetSizeInBits(const RSExportPrimitiveType *EPT);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700308
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700309 inline DataType getType() const { return mType; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700310 inline bool isRSObjectType() const {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800311 return ((mType >= FirstRSObjectType) && (mType <= LastRSObjectType));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700312 }
Zonr Chang641558f2010-10-12 21:07:06 +0800313
314 virtual bool equals(const RSExportable *E) const;
Stephen Hinesfdd1ba12012-03-08 17:26:32 -0800315
316 static RSReflectionType *getRSReflectionType(DataType DT);
317 static RSReflectionType *getRSReflectionType(
318 const RSExportPrimitiveType *EPT) {
319 return getRSReflectionType(EPT->getType());
320 }
Stephen Hinesa6b54142012-04-09 18:25:08 -0700321
Stephen Hines1f6c3312012-07-03 17:23:33 -0700322 virtual unsigned getSize() const { return (GetSizeInBits(this) >> 3); }
323
Stephen Hinesa6b54142012-04-09 18:25:08 -0700324 std::string getElementName() const {
325 return getRSReflectionType(this)->rs_short_type;
326 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700327}; // RSExportPrimitiveType
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700328
329
330class RSExportPointerType : public RSExportType {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700331 friend class RSExportType;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700332 friend class RSExportFunc;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700333 private:
334 const RSExportType *mPointeeType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700335
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700336 RSExportPointerType(RSContext *Context,
337 const llvm::StringRef &Name,
zonr6315f762010-10-05 15:35:14 +0800338 const RSExportType *PointeeType)
Zonr Chang6b6320a2010-10-05 22:42:01 +0800339 : RSExportType(Context, ExportClassPointer, Name),
zonr6315f762010-10-05 15:35:14 +0800340 mPointeeType(PointeeType) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700341 return;
342 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700343
Stephen Hinese5e64432010-12-02 18:48:20 -0800344 // @PT was normalized by calling RSExportType::NormalizeType() before calling
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700345 // this.
346 static RSExportPointerType *Create(RSContext *Context,
347 const clang::PointerType *PT,
348 const llvm::StringRef &TypeName);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700349
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700350 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800351 virtual union RSType *convertToSpecType() const;
Stephen Hinesecddee32011-07-20 18:30:09 -0700352
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700353 public:
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800354 virtual bool keep();
Zonr Chang641558f2010-10-12 21:07:06 +0800355
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 inline const RSExportType *getPointeeType() const { return mPointeeType; }
Zonr Chang641558f2010-10-12 21:07:06 +0800357
358 virtual bool equals(const RSExportable *E) const;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700359}; // RSExportPointerType
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700360
361
362class RSExportVectorType : public RSExportPrimitiveType {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700363 friend class RSExportType;
364 friend class RSExportElement;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700365 private:
Zonr Chang92b344a2010-10-05 20:39:03 +0800366 unsigned mNumElement; // number of element
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700367
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700368 RSExportVectorType(RSContext *Context,
369 const llvm::StringRef &Name,
370 DataType DT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700371 bool Normalized,
Zonr Chang92b344a2010-10-05 20:39:03 +0800372 unsigned NumElement)
Zonr Chang6b6320a2010-10-05 22:42:01 +0800373 : RSExportPrimitiveType(Context, ExportClassVector, Name,
Stephen Hines2b8fb642012-03-09 00:12:47 -0800374 DT, Normalized),
zonr6315f762010-10-05 15:35:14 +0800375 mNumElement(NumElement) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700376 return;
377 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700378
Stephen Hinese5e64432010-12-02 18:48:20 -0800379 // @EVT was normalized by calling RSExportType::NormalizeType() before
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700380 // calling this.
381 static RSExportVectorType *Create(RSContext *Context,
382 const clang::ExtVectorType *EVT,
383 const llvm::StringRef &TypeName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700384 bool Normalized = false);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700385
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700386 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800387 virtual union RSType *convertToSpecType() const;
Stephen Hinesecddee32011-07-20 18:30:09 -0700388
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700389 public:
390 static llvm::StringRef GetTypeName(const clang::ExtVectorType *EVT);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700391
Zonr Chang92b344a2010-10-05 20:39:03 +0800392 inline unsigned getNumElement() const { return mNumElement; }
Zonr Chang641558f2010-10-12 21:07:06 +0800393
Stephen Hinesa6b54142012-04-09 18:25:08 -0700394 std::string getElementName() const {
395 std::stringstream Name;
396 Name << RSExportPrimitiveType::getRSReflectionType(this)->rs_short_type
397 << "_" << getNumElement();
398 return Name.str();
399 }
400
Zonr Chang641558f2010-10-12 21:07:06 +0800401 virtual bool equals(const RSExportable *E) const;
Zonr Chang92b344a2010-10-05 20:39:03 +0800402};
403
404// Only *square* *float* matrix is supported by now.
405//
406// struct rs_matrix{2x2,3x3,4x4, ..., NxN} should be defined as the following
407// form *exactly*:
408// typedef struct {
409// float m[{NxN}];
410// } rs_matrixNxN;
411//
412// where mDim will be N.
413class RSExportMatrixType : public RSExportType {
414 friend class RSExportType;
415 private:
Zonr Chang2e1dba62010-10-05 22:20:11 +0800416 unsigned mDim; // dimension
Zonr Chang92b344a2010-10-05 20:39:03 +0800417
418 RSExportMatrixType(RSContext *Context,
419 const llvm::StringRef &Name,
420 unsigned Dim)
Zonr Chang6b6320a2010-10-05 22:42:01 +0800421 : RSExportType(Context, ExportClassMatrix, Name),
Zonr Chang92b344a2010-10-05 20:39:03 +0800422 mDim(Dim) {
423 return;
424 }
425
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700426 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800427 virtual union RSType *convertToSpecType() const;
Stephen Hinesecddee32011-07-20 18:30:09 -0700428
Zonr Chang92b344a2010-10-05 20:39:03 +0800429 public:
Stephen Hinese5e64432010-12-02 18:48:20 -0800430 // @RT was normalized by calling RSExportType::NormalizeType() before
Zonr Chang92b344a2010-10-05 20:39:03 +0800431 // calling this.
432 static RSExportMatrixType *Create(RSContext *Context,
433 const clang::RecordType *RT,
434 const llvm::StringRef &TypeName,
435 unsigned Dim);
436
437 inline unsigned getDim() const { return mDim; }
Zonr Chang641558f2010-10-12 21:07:06 +0800438
439 virtual bool equals(const RSExportable *E) const;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700440};
441
Zonr Chang2e1dba62010-10-05 22:20:11 +0800442class RSExportConstantArrayType : public RSExportType {
443 friend class RSExportType;
444 private:
445 const RSExportType *mElementType; // Array element type
446 unsigned mSize; // Array size
447
448 RSExportConstantArrayType(RSContext *Context,
449 const RSExportType *ElementType,
450 unsigned Size)
451 : RSExportType(Context,
Zonr Chang6b6320a2010-10-05 22:42:01 +0800452 ExportClassConstantArray,
Zonr Chang2e1dba62010-10-05 22:20:11 +0800453 DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE),
454 mElementType(ElementType),
455 mSize(Size) {
456 return;
457 }
458
Stephen Hinese5e64432010-12-02 18:48:20 -0800459 // @CAT was normalized by calling RSExportType::NormalizeType() before
Zonr Chang2e1dba62010-10-05 22:20:11 +0800460 // calling this.
461 static RSExportConstantArrayType *Create(RSContext *Context,
462 const clang::ConstantArrayType *CAT);
463
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700464 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800465 virtual union RSType *convertToSpecType() const;
Stephen Hinesecddee32011-07-20 18:30:09 -0700466
Zonr Chang2e1dba62010-10-05 22:20:11 +0800467 public:
Stephen Hines0d26cef2012-05-01 19:23:01 -0700468 virtual unsigned getSize() const { return mSize; }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800469 inline const RSExportType *getElementType() const { return mElementType; }
Zonr Chang641558f2010-10-12 21:07:06 +0800470
Stephen Hinesa6b54142012-04-09 18:25:08 -0700471 std::string getElementName() const {
472 return mElementType->getElementName();
473 }
474
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800475 virtual bool keep();
Zonr Chang641558f2010-10-12 21:07:06 +0800476 virtual bool equals(const RSExportable *E) const;
Zonr Chang2e1dba62010-10-05 22:20:11 +0800477};
478
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700479class RSExportRecordType : public RSExportType {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700480 friend class RSExportType;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700481 public:
482 class Field {
483 private:
484 const RSExportType *mType;
485 // Field name
486 std::string mName;
487 // Link to the struct that contain this field
488 const RSExportRecordType *mParent;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800489 // Offset in the container
490 size_t mOffset;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700491
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700492 public:
493 Field(const RSExportType *T,
494 const llvm::StringRef &Name,
495 const RSExportRecordType *Parent,
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800496 size_t Offset)
zonr6315f762010-10-05 15:35:14 +0800497 : mType(T),
498 mName(Name.data(), Name.size()),
499 mParent(Parent),
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800500 mOffset(Offset) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700501 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700502 }
503
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700504 inline const RSExportRecordType *getParent() const { return mParent; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700505 inline const RSExportType *getType() const { return mType; }
506 inline const std::string &getName() const { return mName; }
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800507 inline size_t getOffsetInParent() const { return mOffset; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700508 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700509
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700510 typedef std::list<const Field*>::const_iterator const_field_iterator;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700511
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700512 inline const_field_iterator fields_begin() const {
513 return this->mFields.begin();
514 }
515 inline const_field_iterator fields_end() const {
516 return this->mFields.end();
517 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700518
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700519 private:
520 std::list<const Field*> mFields;
521 bool mIsPacked;
522 // Artificial export struct type is not exported by user (and thus it won't
523 // get reflected)
524 bool mIsArtificial;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800525 size_t mAllocSize;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700526
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700527 RSExportRecordType(RSContext *Context,
528 const llvm::StringRef &Name,
529 bool IsPacked,
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800530 bool IsArtificial,
531 size_t AllocSize)
Zonr Chang6b6320a2010-10-05 22:42:01 +0800532 : RSExportType(Context, ExportClassRecord, Name),
zonr6315f762010-10-05 15:35:14 +0800533 mIsPacked(IsPacked),
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800534 mIsArtificial(IsArtificial),
535 mAllocSize(AllocSize) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700536 return;
537 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700538
Stephen Hinese5e64432010-12-02 18:48:20 -0800539 // @RT was normalized by calling RSExportType::NormalizeType() before calling
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700540 // this.
541 // @TypeName was retrieved from RSExportType::GetTypeName() before calling
542 // this.
543 static RSExportRecordType *Create(RSContext *Context,
544 const clang::RecordType *RT,
545 const llvm::StringRef &TypeName,
546 bool mIsArtificial = false);
547
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700548 virtual llvm::Type *convertToLLVMType() const;
Zonr Changa7a828d2010-10-22 03:44:27 +0800549 virtual union RSType *convertToSpecType() const;
Stephen Hinesecddee32011-07-20 18:30:09 -0700550
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700551 public:
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800552 inline const std::list<const Field*>& getFields() const { return mFields; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700553 inline bool isPacked() const { return mIsPacked; }
554 inline bool isArtificial() const { return mIsArtificial; }
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800555 inline size_t getAllocSize() const { return mAllocSize; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700556
Stephen Hinesa6b54142012-04-09 18:25:08 -0700557 virtual std::string getElementName() const {
558 return "ScriptField_" + getName();
559 }
560
Zonr Chang3cd3dd32010-10-22 02:11:35 +0800561 virtual bool keep();
Zonr Chang641558f2010-10-12 21:07:06 +0800562 virtual bool equals(const RSExportable *E) const;
563
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700564 ~RSExportRecordType() {
565 for (std::list<const Field*>::iterator I = mFields.begin(),
566 E = mFields.end();
567 I != E;
568 I++)
569 if (*I != NULL)
570 delete *I;
571 return;
572 }
573}; // RSExportRecordType
574
575} // namespace slang
576
Stephen Hinese639eb52010-11-08 19:27:20 -0800577#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_ NOLINT