slang_rs_export_type.h revision a6b54146b93eec68f6daa4b1877639cdc34801dc
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/*
2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright 2010-2012, The Android Open Source Project
3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License.
6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at
7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and
14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License.
15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */
16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_  // NOLINT
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <list>
21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <set>
223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include <string>
236a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include <sstream>
2485f12e9b9062402d6110df3f7099707912040edbAndreas Huber
25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "clang/AST/Decl.h"
263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include "clang/AST/Type.h"
273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2885f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "llvm/ADT/SmallPtrSet.h"
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "llvm/ADT/StringMap.h"
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "llvm/ADT/StringRef.h"
31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "llvm/Support/ManagedStatic.h"
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "slang_rs_exportable.h"
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber#define GET_CANONICAL_TYPE(T) \
3732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    (((T) == NULL) ? NULL : (T)->getCanonicalTypeInternal().getTypePtr())
38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define UNSAFE_CAST_TYPE(TT, T) \
399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    static_cast<TT*>(T->getCanonicalTypeInternal().getTypePtr())
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define GET_EXT_VECTOR_ELEMENT_TYPE(T) \
41b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    (((T) == NULL) ? NULL : \
42b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                     GET_CANONICAL_TYPE((T)->getElementType().getTypePtr()))
43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define GET_POINTEE_TYPE(T) \
443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    (((T) == NULL) ? NULL : \
453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                     GET_CANONICAL_TYPE((T)->getPointeeType().getTypePtr()))
46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define GET_CONSTANT_ARRAY_ELEMENT_TYPE(T)  \
476e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    (((T) == NULL) ? NULL : \
486e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber                     GET_CANONICAL_TYPE((T)->getElementType().getTypePtr()))
493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block#define DUMMY_RS_TYPE_NAME_PREFIX   "<"
506e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define DUMMY_RS_TYPE_NAME_POSTFIX  ">"
51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE  \
52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DUMMY_RS_TYPE_NAME_PREFIX"ConstantArray"DUMMY_RS_TYPE_NAME_POSTFIX
53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
54d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangunion RSType;
55d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace llvm {
578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  class Type;
588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}   // namespace llvm
598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
60540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimnamespace slang {
61540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
62540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  class RSContext;
63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
6487f2a558dd12043631e12c361abef301bf603140Andreas Hubertypedef struct {
6587f2a558dd12043631e12c361abef301bf603140Andreas Huber    const char * rs_type;
663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    const char * rs_short_type;
673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t size_in_bits;
68540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    const char * c_name;
69cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    const char * java_name;
7032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    const char * rs_c_vector_prefix;
7132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    const char * rs_java_vector_prefix;
7232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    bool java_promotion;
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} RSReflectionType;
742a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
76bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihtypedef struct RSReflectionTypeData_rec {
77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    const RSReflectionType *type;
78bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    uint32_t vecSize;
79bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool isPointer;
8043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    uint32_t arraySize;
8143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
8243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    // Subelements
8343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    //std::vector<const struct RSReflectionTypeData_rec *> fields;
84386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    //std::vector< std::string > fieldNames;
85386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    //std::vector< uint32_t> fieldOffsetBytes;
86386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} RSReflectionTypeData;
87386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
88386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
89386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberclass RSExportType : public RSExportable {
908dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  friend class RSExportElement;
918dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber public:
928dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  typedef enum {
938dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    ExportClassPrimitive,
9487f2a558dd12043631e12c361abef301bf603140Andreas Huber    ExportClassPointer,
9587f2a558dd12043631e12c361abef301bf603140Andreas Huber    ExportClassVector,
9687f2a558dd12043631e12c361abef301bf603140Andreas Huber    ExportClassMatrix,
9787f2a558dd12043631e12c361abef301bf603140Andreas Huber    ExportClassConstantArray,
983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ExportClassRecord
993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  } ExportClass;
1003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  void convertToRTD(RSReflectionTypeData *rtd) const;
10282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
10382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih private:
10482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih  ExportClass mClass;
10582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih  std::string mName;
1063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // Cache the result after calling convertToLLVMType() at the first time
108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  mutable llvm::Type *mLLVMType;
1099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  // Cache the result after calling convertToSpecType() at the first time
1109bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  mutable union RSType *mSpecType;
1119bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
1123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang protected:
1139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  RSExportType(RSContext *Context,
1149bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang               ExportClass Class,
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber               const llvm::StringRef &Name);
116386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // Let's make it private since there're some prerequisites to call this
118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // function.
119bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber  //
120bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber  // @T was normalized by calling RSExportType::NormalizeType().
121799c9682b3776a55d234396aee4a302437150c26Chong Zhang  // @TypeName was retrieve from RSExportType::GetTypeName() before calling
122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  //           this.
12306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  //
124799c9682b3776a55d234396aee4a302437150c26Chong Zhang  static RSExportType *Create(RSContext *Context,
1253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                              const clang::Type *T,
1263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                              const llvm::StringRef &TypeName);
1279bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static llvm::StringRef GetTypeName(const clang::Type *T);
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // This function convert the RSExportType to LLVM type. Actually, it should be
131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // "convert Clang type to LLVM type." However, clang doesn't make this API
132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // (lib/CodeGen/CodeGenTypes.h) public, we need to do by ourselves.
13387f2a558dd12043631e12c361abef301bf603140Andreas Huber  //
13487f2a558dd12043631e12c361abef301bf603140Andreas Huber  // Once we can get LLVM type, we can use LLVM to get alignment information,
13587f2a558dd12043631e12c361abef301bf603140Andreas Huber  // allocation size of a given type and structure layout that LLVM used
1363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // (all of these information are target dependent) without dealing with these
1373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // by ourselves.
138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  virtual llvm::Type *convertToLLVMType() const = 0;
139bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  // Record type may recursively reference its type definition. We need a
140bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  // temporary type setup before the type construction gets done.
141bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  inline void setAbstractLLVMType(llvm::Type *LLVMType) const {
142bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    mLLVMType = LLVMType;
1433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  }
1443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  virtual union RSType *convertToSpecType() const = 0;
1463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  inline void setSpecTypeTemporarily(union RSType *SpecType) const {
147540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mSpecType = SpecType;
1489558f6dd733dc450270f38b9a139d384d273ce0aWei Jia  }
149540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
1505403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber  virtual ~RSExportType();
15187f2a558dd12043631e12c361abef301bf603140Andreas Huber
152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber public:
1533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // This function additionally verifies that the Type T is exportable.
1543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // If it is not, this function returns false. Otherwise it returns true.
155540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  static bool NormalizeType(const clang::Type *&T,
156540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                            llvm::StringRef &TypeName,
157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                            clang::DiagnosticsEngine *Diags,
15832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                            const clang::VarDecl *VD);
15932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
16032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber  // This function ensures that the VarDecl can be properly handled by RS.
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  // If it cannot, this function returns false. Otherwise it returns true.
1622a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber  static bool ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI);
16382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // @T may not be normalized
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static RSExportType *Create(RSContext *Context, const clang::Type *T);
166bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih  static RSExportType *CreateFromDecl(RSContext *Context,
167bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih                                      const clang::VarDecl *VD);
1680852843d304006e3ab333081fddda13b07193de8Robert Shih
169bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih  static const clang::Type *GetTypeOfDecl(const clang::DeclaratorDecl *DD);
170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  inline ExportClass getClass() const { return mClass; }
172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  inline llvm::Type *getLLVMType() const {
1743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mLLVMType == NULL)
1753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mLLVMType = convertToLLVMType();
1763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return mLLVMType;
1773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  }
1783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
179bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber  inline const union RSType *getSpecType() const {
180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (mSpecType == NULL)
181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mSpecType = convertToSpecType();
18287f2a558dd12043631e12c361abef301bf603140Andreas Huber    return mSpecType;
18387f2a558dd12043631e12c361abef301bf603140Andreas Huber  }
184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // Return the number of bits necessary to hold the specified RSExportType
186cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static size_t GetTypeStoreSize(const RSExportType *ET);
187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
188be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen  // The size of allocation of specified RSExportType (alignment considered)
189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static size_t GetTypeAllocSize(const RSExportType *ET);
19090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
1919558f6dd733dc450270f38b9a139d384d273ce0aWei Jia  inline const std::string &getName() const { return mName; }
19290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
193386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber  virtual std::string getElementName() const {
1946a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    // Base case is actually an invalid C/Java identifier.
1953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return "@@INVALID@@";
1963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  }
1973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  virtual bool keep();
1993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  virtual bool equals(const RSExportable *E) const;
2003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang};  // RSExportType
2013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
202540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim// Primitive types
203540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimclass RSExportPrimitiveType : public RSExportType {
204540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  friend class RSExportType;
205540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  friend class RSExportElement;
2063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang public:
2073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // From graphics/java/android/renderscript/Element.java: Element.DataType
2083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  typedef enum {
2093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    DataTypeIsStruct = -2,
2103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    DataTypeUnknown = -1,
2113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#define ENUM_PRIMITIVE_DATA_TYPE_RANGE(begin_type, end_type)  \
2133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    FirstPrimitiveType = DataType ## begin_type,  \
2143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    LastPrimitiveType = DataType ## end_type,
215540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
216540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim#define ENUM_RS_MATRIX_DATA_TYPE_RANGE(begin_type, end_type)  \
217540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    FirstRSMatrixType = DataType ## begin_type,  \
218540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    LastRSMatrixType = DataType ## end_type,
219540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
220540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim#define ENUM_RS_OBJECT_DATA_TYPE_RANGE(begin_type, end_type)  \
221540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    FirstRSObjectType = DataType ## begin_type,  \
222cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    LastRSObjectType = DataType ## end_type,
223cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#define ENUM_RS_DATA_TYPE(type, cname, bits)  \
2253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    DataType ## type,
2263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include "RSDataTypeEnums.inc"
2283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    DataTypeMax
2303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  } DataType;
23182f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
232cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber private:
233cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // NOTE: There's no any instance of RSExportPrimitiveType which mType
234cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // is of the value DataTypeRSMatrix*. DataTypeRSMatrix* enumeration here is
2358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // only for RSExportPrimitiveType::GetRSObjectType to *recognize* the struct
2368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // rs_matrix{2x2, 3x3, 4x4}. These matrix type are represented as
2378dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // RSExportMatrixType.
2388dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  DataType mType;
2399ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim  bool mNormalized;
2408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2418dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  typedef llvm::StringMap<DataType> RSSpecificTypeMapTy;
2428dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  static llvm::ManagedStatic<RSSpecificTypeMapTy> RSSpecificTypeMap;
2438dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2449ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim  static llvm::Type *RSObjectLLVMType;
2458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2468dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  static const size_t SizeOfDataTypeInBits[];
2478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // @T was normalized by calling RSExportType::NormalizeType() before calling
2488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // this.
2498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // @TypeName was retrieved from RSExportType::GetTypeName() before calling
2508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // this
2518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  static RSExportPrimitiveType *Create(RSContext *Context,
2528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                                       const clang::Type *T,
2538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                                       const llvm::StringRef &TypeName,
2549ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim                                       bool Normalized = false);
2559ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
2568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber protected:
2578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  RSExportPrimitiveType(RSContext *Context,
2588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                        // for derived class to set their type class
2598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                        ExportClass Class,
260540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                        const llvm::StringRef &Name,
2619558f6dd733dc450270f38b9a139d384d273ce0aWei Jia                        DataType DT,
262540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                        bool Normalized)
263540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim      : RSExportType(Context, Class, Name),
26482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        mType(DT),
2659558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        mNormalized(Normalized) {
266540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    return;
267540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  }
268540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
26982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih  virtual llvm::Type *convertToLLVMType() const;
270540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim  virtual union RSType *convertToSpecType() const;
271540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
2729558f6dd733dc450270f38b9a139d384d273ce0aWei Jia  static DataType GetDataType(RSContext *Context, const clang::Type *T);
2739558f6dd733dc450270f38b9a139d384d273ce0aWei Jia
2749558f6dd733dc450270f38b9a139d384d273ce0aWei Jia public:
275cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // T is normalized by calling RSExportType::NormalizeType() before
276cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // calling this
277386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber  static bool IsPrimitiveType(const clang::Type *T);
278d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
279d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang  // @T may not be normalized
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  static RSExportPrimitiveType *Create(RSContext *Context,
281386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                                       const clang::Type *T);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber  static DataType GetRSSpecificType(const llvm::StringRef &TypeName);
284799c9682b3776a55d234396aee4a302437150c26Chong Zhang  static DataType GetRSSpecificType(const clang::Type *T);
285d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
2863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  static bool IsRSMatrixType(DataType DT);
287cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static bool IsRSObjectType(DataType DT);
288cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static bool IsRSObjectType(const clang::Type *T) {
2898dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return IsRSObjectType(GetRSSpecificType(T));
2908dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  }
29106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
29206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  // Determines whether T is [an array of] struct that contains at least one
2938dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  // RS object type within it.
2948dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  static bool IsStructureTypeWithRSObject(const clang::Type *T);
2958dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
296cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  static size_t GetSizeInBits(const RSExportPrimitiveType *EPT);
2978dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
29806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  inline DataType getType() const { return mType; }
2998dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  inline bool isRSObjectType() const {
3008dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return ((mType >= FirstRSObjectType) && (mType <= LastRSObjectType));
3018dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber  }
3028dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
30387f2a558dd12043631e12c361abef301bf603140Andreas Huber  virtual bool equals(const RSExportable *E) const;
30487f2a558dd12043631e12c361abef301bf603140Andreas Huber
3053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  static RSReflectionType *getRSReflectionType(DataType DT);
3063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  static RSReflectionType *getRSReflectionType(
307540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim      const RSExportPrimitiveType *EPT) {
3088dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return getRSReflectionType(EPT->getType());
309cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  }
310cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
311cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  std::string getElementName() const {
312cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return getRSReflectionType(this)->rs_short_type;
313cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  }
314cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};  // RSExportPrimitiveType
3155403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
3163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
3173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangclass RSExportPointerType : public RSExportType {
3183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  friend class RSExportType;
3193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  friend class RSExportFunc;
3203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang private:
321cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  const RSExportType *mPointeeType;
322cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
323cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  RSExportPointerType(RSContext *Context,
324cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                      const llvm::StringRef &Name,
32532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber                      const RSExportType *PointeeType)
32632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber      : RSExportType(Context, ExportClassPointer, Name),
327b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        mPointeeType(PointeeType) {
328b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    return;
329b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber  }
330b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
331b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber  // @PT was normalized by calling RSExportType::NormalizeType() before calling
332b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber  // this.
333b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber  static RSExportPointerType *Create(RSContext *Context,
334b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                                     const clang::PointerType *PT,
3352a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber                                     const llvm::StringRef &TypeName);
33632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  virtual llvm::Type *convertToLLVMType() const;
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  virtual union RSType *convertToSpecType() const;
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  virtual bool keep();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3432a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber  inline const RSExportType *getPointeeType() const { return mPointeeType; }
3442a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
3452a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber  virtual bool equals(const RSExportable *E) const;
3469bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang};  // RSExportPointerType
3479bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3489bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3499bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhangclass RSExportVectorType : public RSExportPrimitiveType {
3509bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  friend class RSExportType;
3519bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  friend class RSExportElement;
3529bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang private:
3539bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  unsigned mNumElement;   // number of element
3549bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3559bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  RSExportVectorType(RSContext *Context,
3569bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     const llvm::StringRef &Name,
3579bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     DataType DT,
3589bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     bool Normalized,
3599bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     unsigned NumElement)
3609bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang      : RSExportPrimitiveType(Context, ExportClassVector, Name,
3619bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                              DT, Normalized),
3629bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        mNumElement(NumElement) {
3639bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return;
3649bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  }
3659bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3669bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  // @EVT was normalized by calling RSExportType::NormalizeType() before
3679bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  // calling this.
3689bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  static RSExportVectorType *Create(RSContext *Context,
3699bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                                    const clang::ExtVectorType *EVT,
3709bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                                    const llvm::StringRef &TypeName,
3719bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                                    bool Normalized = false);
3729bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3739bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  virtual llvm::Type *convertToLLVMType() const;
3749bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  virtual union RSType *convertToSpecType() const;
3759bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3769bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang public:
3779bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  static llvm::StringRef GetTypeName(const clang::ExtVectorType *EVT);
3789bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3799bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  inline unsigned getNumElement() const { return mNumElement; }
3809bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3819bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  std::string getElementName() const {
3829bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    std::stringstream Name;
3839bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    Name << RSExportPrimitiveType::getRSReflectionType(this)->rs_short_type
3849bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang         << "_" << getNumElement();
3859bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return Name.str();
3869bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  }
3879bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3889bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  virtual bool equals(const RSExportable *E) const;
3899bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang};
3909bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3919bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang// Only *square* *float* matrix is supported by now.
3929bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang//
393e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim// struct rs_matrix{2x2,3x3,4x4, ..., NxN} should be defined as the following
394e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim// form *exactly*:
395e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim//  typedef struct {
3969bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang//    float m[{NxN}];
397e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim//  } rs_matrixNxN;
398e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim//
399e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim//  where mDim will be N.
4009bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhangclass RSExportMatrixType : public RSExportType {
4019bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  friend class RSExportType;
4029bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang private:
4039bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  unsigned mDim;  // dimension
4049bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4059bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  RSExportMatrixType(RSContext *Context,
4069bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     const llvm::StringRef &Name,
4079bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     unsigned Dim)
4089bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    : RSExportType(Context, ExportClassMatrix, Name),
4099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang      mDim(Dim) {
4109bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return;
4119bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  }
4129bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  virtual llvm::Type *convertToLLVMType() const;
4149bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang  virtual union RSType *convertToSpecType() const;
415bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
4163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang public:
4173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // @RT was normalized by calling RSExportType::NormalizeType() before
4183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // calling this.
4193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  static RSExportMatrixType *Create(RSContext *Context,
4203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                                    const clang::RecordType *RT,
4213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                                    const llvm::StringRef &TypeName,
4223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                                    unsigned Dim);
4233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  inline unsigned getDim() const { return mDim; }
4253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  virtual bool equals(const RSExportable *E) const;
4273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang};
4283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangclass RSExportConstantArrayType : public RSExportType {
4303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  friend class RSExportType;
4313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang private:
4323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  const RSExportType *mElementType;  // Array element type
4333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  unsigned mSize;  // Array size
4343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  RSExportConstantArrayType(RSContext *Context,
4363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                            const RSExportType *ElementType,
4373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                            unsigned Size)
4383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    : RSExportType(Context,
4393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                   ExportClassConstantArray,
4403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                   DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE),
4413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mElementType(ElementType),
4423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mSize(Size) {
4433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return;
4443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  }
4453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // @CAT was normalized by calling RSExportType::NormalizeType() before
4473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  // calling this.
44806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  static RSExportConstantArrayType *Create(RSContext *Context,
449cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                                           const clang::ConstantArrayType *CAT);
4503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
4516456ae745e919085c5024f784aaa2703f9695f98David Yeh  virtual llvm::Type *convertToLLVMType() const;
4526456ae745e919085c5024f784aaa2703f9695f98David Yeh  virtual union RSType *convertToSpecType() const;
4536456ae745e919085c5024f784aaa2703f9695f98David Yeh
4546456ae745e919085c5024f784aaa2703f9695f98David Yeh public:
4556e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber  inline unsigned getSize() const { return mSize; }
4563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline const RSExportType *getElementType() const { return mElementType; }
4576456ae745e919085c5024f784aaa2703f9695f98David Yeh
4586456ae745e919085c5024f784aaa2703f9695f98David Yeh  std::string getElementName() const {
4596456ae745e919085c5024f784aaa2703f9695f98David Yeh    return mElementType->getElementName();
4606456ae745e919085c5024f784aaa2703f9695f98David Yeh  }
461cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
462e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim  virtual bool keep();
4636e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber  virtual bool equals(const RSExportable *E) const;
464cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
465cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
4663856b090cd04ba5dd4a59a12430ed724d5995909Steve Blockclass RSExportRecordType : public RSExportType {
467cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  friend class RSExportType;
4686e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber public:
4696e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber  class Field {
4706e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber   private:
4716e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    const RSExportType *mType;
4726e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    // Field name
4736e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    std::string mName;
4746e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    // Link to the struct that contain this field
47587f2a558dd12043631e12c361abef301bf603140Andreas Huber    const RSExportRecordType *mParent;
47687f2a558dd12043631e12c361abef301bf603140Andreas Huber    // Offset in the container
47787f2a558dd12043631e12c361abef301bf603140Andreas Huber    size_t mOffset;
47887f2a558dd12043631e12c361abef301bf603140Andreas Huber
4796e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber   public:
480cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    Field(const RSExportType *T,
481cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber          const llvm::StringRef &Name,
4823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block          const RSExportRecordType *Parent,
483cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber          size_t Offset)
4843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        : mType(T),
4853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang          mName(Name.data(), Name.size()),
4863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang          mParent(Parent),
4873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang          mOffset(Offset) {
4883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      return;
4893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
4903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
491cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    inline const RSExportRecordType *getParent() const { return mParent; }
492bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    inline const RSExportType *getType() const { return mType; }
493bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    inline const std::string &getName() const { return mName; }
494cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    inline size_t getOffsetInParent() const { return mOffset; }
495cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  };
496cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
497cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  typedef std::list<const Field*>::const_iterator const_field_iterator;
498cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
499e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim  inline const_field_iterator fields_begin() const {
500cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return this->mFields.begin();
501cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  }
5023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  inline const_field_iterator fields_end() const {
503cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return this->mFields.end();
5046e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber  }
505cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
506cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber private:
5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  std::list<const Field*> mFields;
508cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  bool mIsPacked;
5096e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber  // Artificial export struct type is not exported by user (and thus it won't
510cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // get reflected)
511cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  bool mIsArtificial;
5123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block  size_t mAllocSize;
513cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  RSExportRecordType(RSContext *Context,
5153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                     const llvm::StringRef &Name,
5163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                     bool IsPacked,
5173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                     bool IsArtificial,
5183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                     size_t AllocSize)
519cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      : RSExportType(Context, ExportClassRecord, Name),
520bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        mIsPacked(IsPacked),
521bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        mIsArtificial(IsArtificial),
522bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        mAllocSize(AllocSize) {
5233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return;
5243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang  }
525bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
526cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // @RT was normalized by calling RSExportType::NormalizeType() before calling
527cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // this.
528cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // @TypeName was retrieved from RSExportType::GetTypeName() before calling
529cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber  // this.
530e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim  static RSExportRecordType *Create(RSContext *Context,
531e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                                    const clang::RecordType *RT,
532e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                                    const llvm::StringRef &TypeName,
5336e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber                                    bool mIsArtificial = false);
534bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
535bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  virtual llvm::Type *convertToLLVMType() const;
536bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  virtual union RSType *convertToSpecType() const;
537bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
538bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber public:
539bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  inline const std::list<const Field*>& getFields() const { return mFields; }
540bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  inline bool isPacked() const { return mIsPacked; }
541bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  inline bool isArtificial() const { return mIsArtificial; }
542df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block  inline size_t getAllocSize() const { return mAllocSize; }
543bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
544bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  virtual std::string getElementName() const {
545bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    return "ScriptField_" + getName();
546bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  }
547bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
548bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber  virtual bool keep();
54906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  virtual bool equals(const RSExportable *E) const;
550df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block
55106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  ~RSExportRecordType() {
55206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    for (std::list<const Field*>::iterator I = mFields.begin(),
55306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber             E = mFields.end();
554df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block         I != E;
55506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber         I++)
55606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber      if (*I != NULL)
557df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        delete *I;
55806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return;
55906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber  }
56006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber};  // RSExportRecordType
561df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block
56206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber}   // namespace slang
56306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
56406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_TYPE_H_  NOLINT
5659bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang