Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010-2011, The Android Open Source Project
      3  *
      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 
     17 #include "slang_rs_reflection.h"
     18 
     19 #include <sys/stat.h>
     20 
     21 #include <cstdarg>
     22 #include <cctype>
     23 
     24 #include <algorithm>
     25 #include <string>
     26 #include <utility>
     27 
     28 #include "llvm/ADT/APFloat.h"
     29 #include "llvm/ADT/StringExtras.h"
     30 
     31 #include "os_sep.h"
     32 #include "slang_rs_context.h"
     33 #include "slang_rs_export_var.h"
     34 #include "slang_rs_export_foreach.h"
     35 #include "slang_rs_export_func.h"
     36 #include "slang_rs_reflect_utils.h"
     37 #include "slang_version.h"
     38 #include "slang_utils.h"
     39 
     40 #define RS_SCRIPT_CLASS_NAME_PREFIX      "ScriptC_"
     41 #define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
     42 
     43 #define RS_TYPE_CLASS_NAME_PREFIX        "ScriptField_"
     44 #define RS_TYPE_CLASS_SUPER_CLASS_NAME   "android.renderscript.Script.FieldBase"
     45 
     46 #define RS_TYPE_ITEM_CLASS_NAME          "Item"
     47 
     48 #define RS_TYPE_ITEM_BUFFER_NAME         "mItemArray"
     49 #define RS_TYPE_ITEM_BUFFER_PACKER_NAME  "mIOBuffer"
     50 
     51 #define RS_EXPORT_VAR_INDEX_PREFIX       "mExportVarIdx_"
     52 #define RS_EXPORT_VAR_PREFIX             "mExportVar_"
     53 
     54 #define RS_EXPORT_FUNC_INDEX_PREFIX      "mExportFuncIdx_"
     55 #define RS_EXPORT_FOREACH_INDEX_PREFIX   "mExportForEachIdx_"
     56 
     57 #define RS_EXPORT_VAR_ALLOCATION_PREFIX  "mAlloction_"
     58 #define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
     59 
     60 namespace slang {
     61 
     62 // Some utility function using internal in RSReflection
     63 static bool GetClassNameFromFileName(const std::string &FileName,
     64                                      std::string &ClassName) {
     65   ClassName.clear();
     66 
     67   if (FileName.empty() || (FileName == "-"))
     68     return true;
     69 
     70   ClassName =
     71       RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str());
     72 
     73   return true;
     74 }
     75 
     76 static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) {
     77   static const char *PrimitiveTypeJavaNameMap[] = {
     78     "",         // RSExportPrimitiveType::DataTypeFloat16
     79     "float",    // RSExportPrimitiveType::DataTypeFloat32
     80     "double",   // RSExportPrimitiveType::DataTypeFloat64
     81     "byte",     // RSExportPrimitiveType::DataTypeSigned8
     82     "short",    // RSExportPrimitiveType::DataTypeSigned16
     83     "int",      // RSExportPrimitiveType::DataTypeSigned32
     84     "long",     // RSExportPrimitiveType::DataTypeSigned64
     85     "short",    // RSExportPrimitiveType::DataTypeUnsigned8
     86     "int",      // RSExportPrimitiveType::DataTypeUnsigned16
     87     "long",     // RSExportPrimitiveType::DataTypeUnsigned32
     88     "long",     // RSExportPrimitiveType::DataTypeUnsigned64
     89     "boolean",  // RSExportPrimitiveType::DataTypeBoolean
     90 
     91     "int",      // RSExportPrimitiveType::DataTypeUnsigned565
     92     "int",      // RSExportPrimitiveType::DataTypeUnsigned5551
     93     "int",      // RSExportPrimitiveType::DataTypeUnsigned4444
     94 
     95     "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
     96     "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
     97     "",     // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
     98 
     99     "Element",      // RSExportPrimitiveType::DataTypeRSElement
    100     "Type",         // RSExportPrimitiveType::DataTypeRSType
    101     "Allocation",   // RSExportPrimitiveType::DataTypeRSAllocation
    102     "Sampler",      // RSExportPrimitiveType::DataTypeRSSampler
    103     "Script",       // RSExportPrimitiveType::DataTypeRSScript
    104     "Mesh",         // RSExportPrimitiveType::DataTypeRSMesh
    105     "ProgramFragment",  // RSExportPrimitiveType::DataTypeRSProgramFragment
    106     "ProgramVertex",    // RSExportPrimitiveType::DataTypeRSProgramVertex
    107     "ProgramRaster",    // RSExportPrimitiveType::DataTypeRSProgramRaster
    108     "ProgramStore",     // RSExportPrimitiveType::DataTypeRSProgramStore
    109     "Font",     // RSExportPrimitiveType::DataTypeRSFont
    110   };
    111   unsigned TypeId = EPT->getType();
    112 
    113   if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) {
    114     return PrimitiveTypeJavaNameMap[ EPT->getType() ];
    115   }
    116 
    117   slangAssert(false && "GetPrimitiveTypeName : Unknown primitive data type");
    118   return NULL;
    119 }
    120 
    121 static const char *GetVectorTypeName(const RSExportVectorType *EVT) {
    122   static const char *VectorTypeJavaNameMap[][3] = {
    123     /* 0 */ { "Byte2",    "Byte3",    "Byte4" },
    124     /* 1 */ { "Short2",   "Short3",   "Short4" },
    125     /* 2 */ { "Int2",     "Int3",     "Int4" },
    126     /* 3 */ { "Long2",    "Long3",    "Long4" },
    127     /* 4 */ { "Float2",   "Float3",   "Float4" },
    128     /* 5 */ { "Double2",  "Double3",  "Double4" }
    129   };
    130 
    131   const char **BaseElement = NULL;
    132 
    133   switch (EVT->getType()) {
    134     case RSExportPrimitiveType::DataTypeSigned8: {
    135       BaseElement = VectorTypeJavaNameMap[0];
    136       break;
    137     }
    138     case RSExportPrimitiveType::DataTypeSigned16:
    139     case RSExportPrimitiveType::DataTypeUnsigned8: {
    140       BaseElement = VectorTypeJavaNameMap[1];
    141       break;
    142     }
    143     case RSExportPrimitiveType::DataTypeSigned32:
    144     case RSExportPrimitiveType::DataTypeUnsigned16: {
    145       BaseElement = VectorTypeJavaNameMap[2];
    146       break;
    147     }
    148     case RSExportPrimitiveType::DataTypeSigned64:
    149     case RSExportPrimitiveType::DataTypeUnsigned64:
    150     case RSExportPrimitiveType::DataTypeUnsigned32: {
    151       BaseElement = VectorTypeJavaNameMap[3];
    152       break;
    153     }
    154     case RSExportPrimitiveType::DataTypeFloat32: {
    155       BaseElement = VectorTypeJavaNameMap[4];
    156       break;
    157     }
    158     case RSExportPrimitiveType::DataTypeFloat64: {
    159       BaseElement = VectorTypeJavaNameMap[5];
    160       break;
    161     }
    162     default: {
    163       slangAssert(false && "RSReflection::GetVectorTypeName : Unsupported "
    164                            "vector element data type");
    165       break;
    166     }
    167   }
    168 
    169   slangAssert((EVT->getNumElement() > 1) &&
    170               (EVT->getNumElement() <= 4) &&
    171               "Number of elements in vector type is invalid");
    172 
    173   return BaseElement[EVT->getNumElement() - 2];
    174 }
    175 
    176 static const char *GetVectorElementName(const RSExportVectorType *EVT) {
    177   static const char *VectorElementNameMap[][3] = {
    178     /* 0 */ { "U8_2",   "U8_3",   "U8_4" },
    179     /* 1 */ { "I8_2",   "I8_3",   "I8_4" },
    180     /* 2 */ { "U16_2",  "U16_3",  "U16_4" },
    181     /* 3 */ { "I16_2",  "I16_3",  "I16_4" },
    182     /* 4 */ { "U32_2",  "U32_3",  "U32_4" },
    183     /* 5 */ { "I32_2",  "I32_3",  "I32_4" },
    184     /* 6 */ { "U64_2",  "U64_3",  "U64_4" },
    185     /* 7 */ { "I64_2",  "I64_3",  "I64_4" },
    186     /* 8 */ { "F32_2",  "F32_3",  "F32_4" },
    187     /* 9 */ { "F64_2",  "F64_3",  "F64_4" },
    188   };
    189 
    190   const char **BaseElement = NULL;
    191 
    192   switch (EVT->getType()) {
    193     case RSExportPrimitiveType::DataTypeUnsigned8: {
    194       BaseElement = VectorElementNameMap[0];
    195       break;
    196     }
    197     case RSExportPrimitiveType::DataTypeSigned8: {
    198       BaseElement = VectorElementNameMap[1];
    199       break;
    200     }
    201     case RSExportPrimitiveType::DataTypeUnsigned16: {
    202       BaseElement = VectorElementNameMap[2];
    203       break;
    204     }
    205     case RSExportPrimitiveType::DataTypeSigned16: {
    206       BaseElement = VectorElementNameMap[3];
    207       break;
    208     }
    209     case RSExportPrimitiveType::DataTypeUnsigned32: {
    210       BaseElement = VectorElementNameMap[4];
    211       break;
    212     }
    213     case RSExportPrimitiveType::DataTypeSigned32: {
    214       BaseElement = VectorElementNameMap[5];
    215       break;
    216     }
    217     case RSExportPrimitiveType::DataTypeUnsigned64: {
    218       BaseElement = VectorElementNameMap[6];
    219       break;
    220     }
    221     case RSExportPrimitiveType::DataTypeSigned64: {
    222       BaseElement = VectorElementNameMap[7];
    223       break;
    224     }
    225     case RSExportPrimitiveType::DataTypeFloat32: {
    226       BaseElement = VectorElementNameMap[8];
    227       break;
    228     }
    229     case RSExportPrimitiveType::DataTypeFloat64: {
    230       BaseElement = VectorElementNameMap[9];
    231       break;
    232     }
    233     default: {
    234       slangAssert(false && "RSReflection::GetVectorElementName : Unsupported "
    235                            "vector element data type");
    236       break;
    237     }
    238   }
    239 
    240   slangAssert((EVT->getNumElement() > 1) &&
    241               (EVT->getNumElement() <= 4) &&
    242               "Number of elements in vector type is invalid");
    243 
    244   return BaseElement[EVT->getNumElement() - 2];
    245 }
    246 
    247 static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
    248   static const char *MatrixTypeJavaNameMap[] = {
    249     /* 2x2 */ "Matrix2f",
    250     /* 3x3 */ "Matrix3f",
    251     /* 4x4 */ "Matrix4f",
    252   };
    253   unsigned Dim = EMT->getDim();
    254 
    255   if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*)))
    256     return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ];
    257 
    258   slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
    259   return NULL;
    260 }
    261 
    262 static const char *GetVectorAccessor(unsigned Index) {
    263   static const char *VectorAccessorMap[] = {
    264     /* 0 */ "x",
    265     /* 1 */ "y",
    266     /* 2 */ "z",
    267     /* 3 */ "w",
    268   };
    269 
    270   slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
    271               "Out-of-bound index to access vector member");
    272 
    273   return VectorAccessorMap[Index];
    274 }
    275 
    276 static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
    277   static const char *PrimitiveTypePackerAPINameMap[] = {
    278     "",         // RSExportPrimitiveType::DataTypeFloat16
    279     "addF32",   // RSExportPrimitiveType::DataTypeFloat32
    280     "addF64",   // RSExportPrimitiveType::DataTypeFloat64
    281     "addI8",    // RSExportPrimitiveType::DataTypeSigned8
    282     "addI16",   // RSExportPrimitiveType::DataTypeSigned16
    283     "addI32",   // RSExportPrimitiveType::DataTypeSigned32
    284     "addI64",   // RSExportPrimitiveType::DataTypeSigned64
    285     "addU8",    // RSExportPrimitiveType::DataTypeUnsigned8
    286     "addU16",   // RSExportPrimitiveType::DataTypeUnsigned16
    287     "addU32",   // RSExportPrimitiveType::DataTypeUnsigned32
    288     "addU64",   // RSExportPrimitiveType::DataTypeUnsigned64
    289     "addBoolean",  // RSExportPrimitiveType::DataTypeBoolean
    290 
    291     "addU16",   // RSExportPrimitiveType::DataTypeUnsigned565
    292     "addU16",   // RSExportPrimitiveType::DataTypeUnsigned5551
    293     "addU16",   // RSExportPrimitiveType::DataTypeUnsigned4444
    294 
    295     "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix2x2
    296     "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix3x3
    297     "addMatrix",   // RSExportPrimitiveType::DataTypeRSMatrix4x4
    298 
    299     "addObj",   // RSExportPrimitiveType::DataTypeRSElement
    300     "addObj",   // RSExportPrimitiveType::DataTypeRSType
    301     "addObj",   // RSExportPrimitiveType::DataTypeRSAllocation
    302     "addObj",   // RSExportPrimitiveType::DataTypeRSSampler
    303     "addObj",   // RSExportPrimitiveType::DataTypeRSScript
    304     "addObj",   // RSExportPrimitiveType::DataTypeRSMesh
    305     "addObj",   // RSExportPrimitiveType::DataTypeRSProgramFragment
    306     "addObj",   // RSExportPrimitiveType::DataTypeRSProgramVertex
    307     "addObj",   // RSExportPrimitiveType::DataTypeRSProgramRaster
    308     "addObj",   // RSExportPrimitiveType::DataTypeRSProgramStore
    309     "addObj",   // RSExportPrimitiveType::DataTypeRSFont
    310   };
    311   unsigned TypeId = EPT->getType();
    312 
    313   if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))
    314     return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
    315 
    316   slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
    317   return NULL;
    318 }
    319 
    320 static std::string GetTypeName(const RSExportType *ET) {
    321   switch (ET->getClass()) {
    322     case RSExportType::ExportClassPrimitive: {
    323       return GetPrimitiveTypeName(
    324                 static_cast<const RSExportPrimitiveType*>(ET));
    325     }
    326     case RSExportType::ExportClassPointer: {
    327       const RSExportType *PointeeType =
    328           static_cast<const RSExportPointerType*>(ET)->getPointeeType();
    329 
    330       if (PointeeType->getClass() != RSExportType::ExportClassRecord)
    331         return "Allocation";
    332       else
    333         return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
    334     }
    335     case RSExportType::ExportClassVector: {
    336       return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
    337     }
    338     case RSExportType::ExportClassMatrix: {
    339       return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
    340     }
    341     case RSExportType::ExportClassConstantArray: {
    342       const RSExportConstantArrayType* CAT =
    343           static_cast<const RSExportConstantArrayType*>(ET);
    344       std::string ElementTypeName = GetTypeName(CAT->getElementType());
    345       ElementTypeName.append("[]");
    346       return ElementTypeName;
    347     }
    348     case RSExportType::ExportClassRecord: {
    349       return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() +
    350                  "."RS_TYPE_ITEM_CLASS_NAME;
    351     }
    352     default: {
    353       slangAssert(false && "Unknown class of type");
    354     }
    355   }
    356 
    357   return "";
    358 }
    359 
    360 static const char *GetTypeNullValue(const RSExportType *ET) {
    361   switch (ET->getClass()) {
    362     case RSExportType::ExportClassPrimitive: {
    363       const RSExportPrimitiveType *EPT =
    364           static_cast<const RSExportPrimitiveType*>(ET);
    365       if (EPT->isRSObjectType())
    366         return "null";
    367       else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean)
    368         return "false";
    369       else
    370         return "0";
    371       break;
    372     }
    373     case RSExportType::ExportClassPointer:
    374     case RSExportType::ExportClassVector:
    375     case RSExportType::ExportClassMatrix:
    376     case RSExportType::ExportClassConstantArray:
    377     case RSExportType::ExportClassRecord: {
    378       return "null";
    379       break;
    380     }
    381     default: {
    382       slangAssert(false && "Unknown class of type");
    383     }
    384   }
    385   return "";
    386 }
    387 
    388 static const char *GetBuiltinElementConstruct(const RSExportType *ET) {
    389   if (ET->getClass() == RSExportType::ExportClassPrimitive) {
    390     const RSExportPrimitiveType *EPT =
    391         static_cast<const RSExportPrimitiveType*>(ET);
    392     if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
    393       static const char *PrimitiveBuiltinElementConstructMap[] = {
    394         NULL,               // RSExportPrimitiveType::DataTypeFloat16
    395         "Element.F32",      // RSExportPrimitiveType::DataTypeFloat32
    396         "Element.F64",      // RSExportPrimitiveType::DataTypeFloat64
    397         "Element.I8",       // RSExportPrimitiveType::DataTypeSigned8
    398         "Element.I16",      // RSExportPrimitiveType::DataTypeSigned16
    399         "Element.I32",      // RSExportPrimitiveType::DataTypeSigned32
    400         "Element.I64",      // RSExportPrimitiveType::DataTypeSigned64
    401         "Element.U8",       // RSExportPrimitiveType::DataTypeUnsigned8
    402         "Element.U16",      // RSExportPrimitiveType::DataTypeUnsigned16
    403         "Element.U32",      // RSExportPrimitiveType::DataTypeUnsigned32
    404         "Element.U64",      // RSExportPrimitiveType::DataTypeUnsigned64
    405         "Element.BOOLEAN",  // RSExportPrimitiveType::DataTypeBoolean
    406 
    407         NULL,   // RSExportPrimitiveType::DataTypeUnsigned565
    408         NULL,   // RSExportPrimitiveType::DataTypeUnsigned5551
    409         NULL,   // RSExportPrimitiveType::DataTypeUnsigned4444
    410 
    411         NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
    412         NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
    413         NULL,   // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
    414 
    415         "Element.ELEMENT",      // RSExportPrimitiveType::DataTypeRSElement
    416         "Element.TYPE",         // RSExportPrimitiveType::DataTypeRSType
    417         "Element.ALLOCATION",   // RSExportPrimitiveType::DataTypeRSAllocation
    418         "Element.SAMPLER",      // RSExportPrimitiveType::DataTypeRSSampler
    419         "Element.SCRIPT",       // RSExportPrimitiveType::DataTypeRSScript
    420         "Element.MESH",         // RSExportPrimitiveType::DataTypeRSMesh
    421         "Element.PROGRAM_FRAGMENT",
    422           // RSExportPrimitiveType::DataTypeRSProgramFragment
    423         "Element.PROGRAM_VERTEX",
    424           // RSExportPrimitiveType::DataTypeRSProgramVertex
    425         "Element.PROGRAM_RASTER",
    426           // RSExportPrimitiveType::DataTypeRSProgramRaster
    427         "Element.PROGRAM_STORE",
    428           // RSExportPrimitiveType::DataTypeRSProgramStore
    429         "Element.FONT",
    430           // RSExportPrimitiveType::DataTypeRSFont
    431       };
    432       unsigned TypeId = EPT->getType();
    433 
    434       if (TypeId <
    435           (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))
    436         return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
    437     } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
    438       if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
    439         return "Element.A_8";
    440     } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
    441       if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
    442         return "Element.RGB_565";
    443       else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
    444         return "Element.RGB_888";
    445     } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
    446       if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
    447         return "Element.RGBA_5551";
    448       else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
    449         return "Element.RGBA_4444";
    450       else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
    451         return "Element.RGBA_8888";
    452     }
    453   } else if (ET->getClass() == RSExportType::ExportClassVector) {
    454     const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
    455     if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) {
    456       if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
    457         if (EVT->getNumElement() == 2)
    458           return "Element.F32_2";
    459         else if (EVT->getNumElement() == 3)
    460           return "Element.F32_3";
    461         else if (EVT->getNumElement() == 4)
    462           return "Element.F32_4";
    463       } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
    464         if (EVT->getNumElement() == 4)
    465           return "Element.U8_4";
    466       }
    467     }
    468   } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
    469     const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
    470     switch (EMT->getDim()) {
    471       case 2: return "Element.MATRIX_2X2";
    472       case 3: return "Element.MATRIX_3X3";
    473       case 4: return "Element.MATRIX_4X4";
    474       default: slangAssert(false && "Unsupported dimension of matrix");
    475     }
    476   } else if (ET->getClass() == RSExportType::ExportClassPointer) {
    477     // Treat pointer type variable as unsigned int
    478     // TODO(zonr): this is target dependent
    479     return "Element.USER_I32";
    480   }
    481 
    482   return NULL;
    483 }
    484 
    485 static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
    486   static const char *ElementDataKindNameMap[] = {
    487     "Element.DataKind.USER",        // RSExportPrimitiveType::DataKindUser
    488     "Element.DataKind.PIXEL_L",     // RSExportPrimitiveType::DataKindPixelL
    489     "Element.DataKind.PIXEL_A",     // RSExportPrimitiveType::DataKindPixelA
    490     "Element.DataKind.PIXEL_LA",    // RSExportPrimitiveType::DataKindPixelLA
    491     "Element.DataKind.PIXEL_RGB",   // RSExportPrimitiveType::DataKindPixelRGB
    492     "Element.DataKind.PIXEL_RGBA",  // RSExportPrimitiveType::DataKindPixelRGBA
    493   };
    494 
    495   if (static_cast<unsigned>(DK) <
    496       (sizeof(ElementDataKindNameMap) / sizeof(const char*)))
    497     return ElementDataKindNameMap[ DK ];
    498   else
    499     return NULL;
    500 }
    501 
    502 static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
    503   static const char *ElementDataTypeNameMap[] = {
    504     NULL,                            // RSExportPrimitiveType::DataTypeFloat16
    505     "Element.DataType.FLOAT_32",     // RSExportPrimitiveType::DataTypeFloat32
    506     "Element.DataType.FLOAT_64",     // RSExportPrimitiveType::DataTypeFloat64
    507     "Element.DataType.SIGNED_8",     // RSExportPrimitiveType::DataTypeSigned8
    508     "Element.DataType.SIGNED_16",    // RSExportPrimitiveType::DataTypeSigned16
    509     "Element.DataType.SIGNED_32",    // RSExportPrimitiveType::DataTypeSigned32
    510     "Element.DataType.SIGNED_64",    // RSExportPrimitiveType::DataTypeSigned64
    511     "Element.DataType.UNSIGNED_8",   // RSExportPrimitiveType::DataTypeUnsigned8
    512     "Element.DataType.UNSIGNED_16",
    513       // RSExportPrimitiveType::DataTypeUnsigned16
    514     "Element.DataType.UNSIGNED_32",
    515       // RSExportPrimitiveType::DataTypeUnsigned32
    516     "Element.DataType.UNSIGNED_64",
    517       // RSExportPrimitiveType::DataTypeUnsigned64
    518     "Element.DataType.BOOLEAN",
    519       // RSExportPrimitiveType::DataTypeBoolean
    520 
    521     // RSExportPrimitiveType::DataTypeUnsigned565
    522     "Element.DataType.UNSIGNED_5_6_5",
    523     // RSExportPrimitiveType::DataTypeUnsigned5551
    524     "Element.DataType.UNSIGNED_5_5_5_1",
    525     // RSExportPrimitiveType::DataTypeUnsigned4444
    526     "Element.DataType.UNSIGNED_4_4_4_4",
    527 
    528     // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
    529     NULL,  // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
    530     NULL,  // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
    531     NULL,  // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
    532 
    533     "Element.DataType.RS_ELEMENT",  // RSExportPrimitiveType::DataTypeRSElement
    534     "Element.DataType.RS_TYPE",     // RSExportPrimitiveType::DataTypeRSType
    535       // RSExportPrimitiveType::DataTypeRSAllocation
    536     "Element.DataType.RS_ALLOCATION",
    537       // RSExportPrimitiveType::DataTypeRSSampler
    538     "Element.DataType.RS_SAMPLER",
    539       // RSExportPrimitiveType::DataTypeRSScript
    540     "Element.DataType.RS_SCRIPT",
    541       // RSExportPrimitiveType::DataTypeRSMesh
    542     "Element.DataType.RS_MESH",
    543       // RSExportPrimitiveType::DataTypeRSProgramFragment
    544     "Element.DataType.RS_PROGRAM_FRAGMENT",
    545       // RSExportPrimitiveType::DataTypeRSProgramVertex
    546     "Element.DataType.RS_PROGRAM_VERTEX",
    547       // RSExportPrimitiveType::DataTypeRSProgramRaster
    548     "Element.DataType.RS_PROGRAM_RASTER",
    549       // RSExportPrimitiveType::DataTypeRSProgramStore
    550     "Element.DataType.RS_PROGRAM_STORE",
    551       // RSExportPrimitiveType::DataTypeRSFont
    552     "Element.DataType.RS_FONT",
    553   };
    554 
    555   if (static_cast<unsigned>(DT) <
    556       (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))
    557     return ElementDataTypeNameMap[ DT ];
    558   else
    559     return NULL;
    560 }
    561 
    562 static const char *GetElementJavaTypeName(RSExportPrimitiveType::DataType DT) {
    563   static const char *ElementJavaTypeNameMap[] = {
    564     NULL,                 // RSExportPrimitiveType::DataTypeFloat16
    565     "F32",                // RSExportPrimitiveType::DataTypeFloat32
    566     "F64",                // RSExportPrimitiveType::DataTypeFloat64
    567     "I8",                 // RSExportPrimitiveType::DataTypeSigned8
    568     "I16",                // RSExportPrimitiveType::DataTypeSigned16
    569     "I32",                // RSExportPrimitiveType::DataTypeSigned32
    570     "I64",                // RSExportPrimitiveType::DataTypeSigned64
    571     "U8",                 // RSExportPrimitiveType::DataTypeUnsigned8
    572     "U16",                // RSExportPrimitiveType::DataTypeUnsigned16
    573     "U32",                // RSExportPrimitiveType::DataTypeUnsigned32
    574     "U64",                // RSExportPrimitiveType::DataTypeUnsigned64
    575     "BOOLEAN",            // RSExportPrimitiveType::DataTypeBoolean
    576 
    577     "RGB_565",            // RSExportPrimitiveType::DataTypeUnsigned565
    578     "RGBA_5551",          // RSExportPrimitiveType::DataTypeUnsigned5551
    579     "RGBA_4444",          // RSExportPrimitiveType::DataTypeUnsigned4444
    580 
    581     // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
    582     NULL,                 // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
    583     NULL,                 // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
    584     NULL,                 // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
    585 
    586     "ELEMENT",            // RSExportPrimitiveType::DataTypeRSElement
    587     "TYPE",               // RSExportPrimitiveType::DataTypeRSType
    588     "ALLOCATION",         // RSExportPrimitiveType::DataTypeRSAllocation
    589     "SAMPLER",            // RSExportPrimitiveType::DataTypeRSSampler
    590     "SCRIPT",             // RSExportPrimitiveType::DataTypeRSScript
    591     "MESH",               // RSExportPrimitiveType::DataTypeRSMesh
    592     "PROGRAM_FRAGMENT",   // RSExportPrimitiveType::DataTypeRSProgramFragment
    593     "PROGRAM_VERTEX",     // RSExportPrimitiveType::DataTypeRSProgramVertex
    594     "PROGRAM_RASTER",     // RSExportPrimitiveType::DataTypeRSProgramRaster
    595     "PROGRAM_STORE",      // RSExportPrimitiveType::DataTypeRSProgramStore
    596     "FONT",               // RSExportPrimitiveType::DataTypeRSFont
    597   };
    598 
    599   if (static_cast<unsigned>(DT) <
    600       (sizeof(ElementJavaTypeNameMap) / sizeof(const char*)))
    601     return ElementJavaTypeNameMap[DT];
    602   else
    603     return NULL;
    604 }
    605 
    606 
    607 /********************** Methods to generate script class **********************/
    608 bool RSReflection::genScriptClass(Context &C,
    609                                   const std::string &ClassName,
    610                                   std::string &ErrorMsg) {
    611   if (!C.startClass(Context::AM_Public,
    612                     false,
    613                     ClassName,
    614                     RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
    615                     ErrorMsg))
    616     return false;
    617 
    618   genScriptClassConstructor(C);
    619 
    620   // Reflect export variable
    621   for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
    622            E = mRSContext->export_vars_end();
    623        I != E;
    624        I++)
    625     genExportVariable(C, *I);
    626 
    627   // Reflect export for each functions (only available on ICS+)
    628   if (mRSContext->getTargetAPI() >= SLANG_ICS_TARGET_API) {
    629     for (RSContext::const_export_foreach_iterator
    630              I = mRSContext->export_foreach_begin(),
    631              E = mRSContext->export_foreach_end();
    632          I != E; I++)
    633       genExportForEach(C, *I);
    634   }
    635 
    636   // Reflect export function
    637   for (RSContext::const_export_func_iterator
    638            I = mRSContext->export_funcs_begin(),
    639            E = mRSContext->export_funcs_end();
    640        I != E; I++)
    641     genExportFunction(C, *I);
    642 
    643   C.endClass();
    644 
    645   return true;
    646 }
    647 
    648 void RSReflection::genScriptClassConstructor(Context &C) {
    649   C.indent() << "// Constructor" << std::endl;
    650   C.startFunction(Context::AM_Public,
    651                   false,
    652                   NULL,
    653                   C.getClassName(),
    654                   3,
    655                   "RenderScript", "rs",
    656                   "Resources", "resources",
    657                   "int", "id");
    658   // Call constructor of super class
    659   C.indent() << "super(rs, resources, id);" << std::endl;
    660 
    661   // If an exported variable has initial value, reflect it
    662 
    663   for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
    664            E = mRSContext->export_vars_end();
    665        I != E;
    666        I++) {
    667     const RSExportVar *EV = *I;
    668     if (!EV->getInit().isUninit())
    669       genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
    670   }
    671 
    672   for (RSContext::const_export_foreach_iterator
    673            I = mRSContext->export_foreach_begin(),
    674            E = mRSContext->export_foreach_end();
    675        I != E;
    676        I++) {
    677     const RSExportForEach *EF = *I;
    678 
    679     const RSExportType *IET = EF->getInType();
    680     if (IET) {
    681       genTypeInstance(C, IET);
    682     }
    683     const RSExportType *OET = EF->getOutType();
    684     if (OET) {
    685       genTypeInstance(C, OET);
    686     }
    687   }
    688 
    689   C.endFunction();
    690 
    691   for (std::set<std::string>::iterator I = C.mTypesToCheck.begin(),
    692                                        E = C.mTypesToCheck.end();
    693        I != E;
    694        I++) {
    695     C.indent() << "private Element __" << *I << ";" << std::endl;
    696   }
    697 
    698   return;
    699 }
    700 
    701 void RSReflection::genInitBoolExportVariable(Context &C,
    702                                              const std::string &VarName,
    703                                              const clang::APValue &Val) {
    704   slangAssert(!Val.isUninit() && "Not a valid initializer");
    705 
    706   C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
    707   slangAssert((Val.getKind() == clang::APValue::Int) &&
    708               "Bool type has wrong initial APValue");
    709 
    710   C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
    711           << ";" << std::endl;
    712 
    713   return;
    714 }
    715 
    716 void RSReflection::genInitPrimitiveExportVariable(
    717       Context &C,
    718       const std::string &VarName,
    719       const clang::APValue &Val) {
    720   slangAssert(!Val.isUninit() && "Not a valid initializer");
    721 
    722   C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
    723   switch (Val.getKind()) {
    724     case clang::APValue::Int: {
    725       llvm::APInt api = Val.getInt();
    726       C.out() << api.getSExtValue();
    727       if (api.getBitWidth() > 32) {
    728         C.out() << "L";
    729       }
    730       break;
    731     }
    732     case clang::APValue::Float: {
    733       llvm::APFloat apf = Val.getFloat();
    734       if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
    735         C.out() << apf.convertToFloat() << "f";
    736       } else {
    737         C.out() << apf.convertToDouble();
    738       }
    739       break;
    740     }
    741 
    742     case clang::APValue::ComplexInt:
    743     case clang::APValue::ComplexFloat:
    744     case clang::APValue::LValue:
    745     case clang::APValue::Vector: {
    746       slangAssert(false &&
    747                   "Primitive type cannot have such kind of initializer");
    748       break;
    749     }
    750     default: {
    751       slangAssert(false && "Unknown kind of initializer");
    752     }
    753   }
    754   C.out() << ";" << std::endl;
    755 
    756   return;
    757 }
    758 
    759 void RSReflection::genInitExportVariable(Context &C,
    760                                          const RSExportType *ET,
    761                                          const std::string &VarName,
    762                                          const clang::APValue &Val) {
    763   slangAssert(!Val.isUninit() && "Not a valid initializer");
    764 
    765   switch (ET->getClass()) {
    766     case RSExportType::ExportClassPrimitive: {
    767       const RSExportPrimitiveType *EPT =
    768           static_cast<const RSExportPrimitiveType*>(ET);
    769       if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
    770         genInitBoolExportVariable(C, VarName, Val);
    771       } else {
    772         genInitPrimitiveExportVariable(C, VarName, Val);
    773       }
    774       break;
    775     }
    776     case RSExportType::ExportClassPointer: {
    777       if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
    778         std::cout << "Initializer which is non-NULL to pointer type variable "
    779                      "will be ignored" << std::endl;
    780       break;
    781     }
    782     case RSExportType::ExportClassVector: {
    783       const RSExportVectorType *EVT =
    784           static_cast<const RSExportVectorType*>(ET);
    785       switch (Val.getKind()) {
    786         case clang::APValue::Int:
    787         case clang::APValue::Float: {
    788           for (unsigned i = 0; i < EVT->getNumElement(); i++) {
    789             std::string Name =  VarName + "." + GetVectorAccessor(i);
    790             genInitPrimitiveExportVariable(C, Name, Val);
    791           }
    792           break;
    793         }
    794         case clang::APValue::Vector: {
    795           C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
    796                      << GetVectorTypeName(EVT) << "();" << std::endl;
    797 
    798           unsigned NumElements =
    799               std::min(static_cast<unsigned>(EVT->getNumElement()),
    800                        Val.getVectorLength());
    801           for (unsigned i = 0; i < NumElements; i++) {
    802             const clang::APValue &ElementVal = Val.getVectorElt(i);
    803             std::string Name = VarName + "." + GetVectorAccessor(i);
    804             genInitPrimitiveExportVariable(C, Name, ElementVal);
    805           }
    806           break;
    807         }
    808         case clang::APValue::Uninitialized:
    809         case clang::APValue::ComplexInt:
    810         case clang::APValue::ComplexFloat:
    811         case clang::APValue::LValue: {
    812           slangAssert(false && "Unexpected type of value of initializer.");
    813         }
    814       }
    815       break;
    816     }
    817     // TODO(zonr): Resolving initializer of a record (and matrix) type variable
    818     // is complex. It cannot obtain by just simply evaluating the initializer
    819     // expression.
    820     case RSExportType::ExportClassMatrix:
    821     case RSExportType::ExportClassConstantArray:
    822     case RSExportType::ExportClassRecord: {
    823 #if 0
    824       unsigned InitIndex = 0;
    825       const RSExportRecordType *ERT =
    826           static_cast<const RSExportRecordType*>(ET);
    827 
    828       slangAssert((Val.getKind() == clang::APValue::Vector) &&
    829           "Unexpected type of initializer for record type variable");
    830 
    831       C.indent() << RS_EXPORT_VAR_PREFIX << VarName
    832                  << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName()
    833                  <<  "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
    834 
    835       for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
    836                E = ERT->fields_end();
    837            I != E;
    838            I++) {
    839         const RSExportRecordType::Field *F = *I;
    840         std::string FieldName = VarName + "." + F->getName();
    841 
    842         if (InitIndex > Val.getVectorLength())
    843           break;
    844 
    845         genInitPrimitiveExportVariable(C,
    846                                        FieldName,
    847                                        Val.getVectorElt(InitIndex++));
    848       }
    849 #endif
    850       slangAssert(false && "Unsupported initializer for record/matrix/constant "
    851                            "array type variable currently");
    852       break;
    853     }
    854     default: {
    855       slangAssert(false && "Unknown class of type");
    856     }
    857   }
    858   return;
    859 }
    860 
    861 void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) {
    862   const RSExportType *ET = EV->getType();
    863 
    864   C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX
    865              << EV->getName() << " = " << C.getNextExportVarSlot() << ";"
    866              << std::endl;
    867 
    868   switch (ET->getClass()) {
    869     case RSExportType::ExportClassPrimitive: {
    870       genPrimitiveTypeExportVariable(C, EV);
    871       break;
    872     }
    873     case RSExportType::ExportClassPointer: {
    874       genPointerTypeExportVariable(C, EV);
    875       break;
    876     }
    877     case RSExportType::ExportClassVector: {
    878       genVectorTypeExportVariable(C, EV);
    879       break;
    880     }
    881     case RSExportType::ExportClassMatrix: {
    882       genMatrixTypeExportVariable(C, EV);
    883       break;
    884     }
    885     case RSExportType::ExportClassConstantArray: {
    886       genConstantArrayTypeExportVariable(C, EV);
    887       break;
    888     }
    889     case RSExportType::ExportClassRecord: {
    890       genRecordTypeExportVariable(C, EV);
    891       break;
    892     }
    893     default: {
    894       slangAssert(false && "Unknown class of type");
    895     }
    896   }
    897 
    898   return;
    899 }
    900 
    901 void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) {
    902   C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX
    903              << EF->getName() << " = " << C.getNextExportFuncSlot() << ";"
    904              << std::endl;
    905 
    906   // invoke_*()
    907   Context::ArgTy Args;
    908 
    909   if (EF->hasParam()) {
    910     for (RSExportFunc::const_param_iterator I = EF->params_begin(),
    911              E = EF->params_end();
    912          I != E;
    913          I++) {
    914       Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
    915                                     (*I)->getName()));
    916     }
    917   }
    918 
    919   C.startFunction(Context::AM_Public,
    920                   false,
    921                   "void",
    922                   "invoke_" + EF->getName(/*Mangle=*/ false),
    923                       // We are using un-mangled name since Java
    924                       // supports method overloading.
    925                   Args);
    926 
    927   if (!EF->hasParam()) {
    928     C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");"
    929                << std::endl;
    930   } else {
    931     const RSExportRecordType *ERT = EF->getParamPacketType();
    932     std::string FieldPackerName = EF->getName() + "_fp";
    933 
    934     if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
    935       genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
    936 
    937     C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", "
    938                << FieldPackerName << ");" << std::endl;
    939   }
    940 
    941   C.endFunction();
    942   return;
    943 }
    944 
    945 void RSReflection::genExportForEach(Context &C, const RSExportForEach *EF) {
    946   C.indent() << "private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX
    947              << EF->getName() << " = " << C.getNextExportForEachSlot() << ";"
    948              << std::endl;
    949 
    950   // forEach_*()
    951   Context::ArgTy Args;
    952 
    953   slangAssert(EF->getNumParameters() > 0);
    954 
    955   if (EF->hasIn())
    956     Args.push_back(std::make_pair("Allocation", "ain"));
    957   if (EF->hasOut())
    958     Args.push_back(std::make_pair("Allocation", "aout"));
    959 
    960   const RSExportRecordType *ERT = EF->getParamPacketType();
    961   if (ERT) {
    962     for (RSExportForEach::const_param_iterator I = EF->params_begin(),
    963              E = EF->params_end();
    964          I != E;
    965          I++) {
    966       Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
    967                                     (*I)->getName()));
    968     }
    969   }
    970 
    971   C.startFunction(Context::AM_Public,
    972                   false,
    973                   "void",
    974                   "forEach_" + EF->getName(),
    975                   Args);
    976 
    977   const RSExportType *IET = EF->getInType();
    978   if (IET) {
    979     genTypeCheck(C, IET, "ain");
    980   }
    981 
    982   const RSExportType *OET = EF->getOutType();
    983   if (OET) {
    984     genTypeCheck(C, OET, "aout");
    985   }
    986 
    987   if (EF->hasIn() && EF->hasOut()) {
    988     C.indent() << "// Verify dimensions" << std::endl;
    989     C.indent() << "Type tIn = ain.getType();" << std::endl;
    990     C.indent() << "Type tOut = aout.getType();" << std::endl;
    991     C.indent() << "if ((tIn.getCount() != tOut.getCount()) ||" << std::endl;
    992     C.indent() << "    (tIn.getX() != tOut.getX()) ||" << std::endl;
    993     C.indent() << "    (tIn.getY() != tOut.getY()) ||" << std::endl;
    994     C.indent() << "    (tIn.getZ() != tOut.getZ()) ||" << std::endl;
    995     C.indent() << "    (tIn.hasFaces() != tOut.hasFaces()) ||" << std::endl;
    996     C.indent() << "    (tIn.hasMipmaps() != tOut.hasMipmaps())) {" << std::endl;
    997     C.indent() << "    throw new RSRuntimeException(\"Dimension mismatch "
    998                << "between input and output parameters!\");";
    999     C.out()    << std::endl;
   1000     C.indent() << "}" << std::endl;
   1001   }
   1002 
   1003   std::string FieldPackerName = EF->getName() + "_fp";
   1004   if (ERT) {
   1005     if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) {
   1006       genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
   1007     }
   1008   }
   1009   C.indent() << "forEach("RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName();
   1010 
   1011   if (EF->hasIn())
   1012     C.out() << ", ain";
   1013   else
   1014     C.out() << ", null";
   1015 
   1016   if (EF->hasOut())
   1017     C.out() << ", aout";
   1018   else
   1019     C.out() << ", null";
   1020 
   1021   if (EF->hasUsrData())
   1022     C.out() << ", " << FieldPackerName;
   1023   else
   1024     C.out() << ", null";
   1025 
   1026   C.out() << ");" << std::endl;
   1027 
   1028   C.endFunction();
   1029   return;
   1030 }
   1031 
   1032 void RSReflection::genTypeInstance(Context &C,
   1033                                    const RSExportType *ET) {
   1034   if (ET->getClass() == RSExportType::ExportClassPointer) {
   1035     const RSExportPointerType *EPT =
   1036         static_cast<const RSExportPointerType*>(ET);
   1037     ET = EPT->getPointeeType();
   1038     switch (ET->getClass()) {
   1039       case RSExportType::ExportClassPrimitive: {
   1040         const RSExportPrimitiveType *EPT =
   1041             static_cast<const RSExportPrimitiveType*>(ET);
   1042         slangAssert(EPT);
   1043 
   1044         switch (EPT->getKind()) {
   1045           case RSExportPrimitiveType::DataKindPixelL:
   1046           case RSExportPrimitiveType::DataKindPixelA:
   1047           case RSExportPrimitiveType::DataKindPixelLA:
   1048           case RSExportPrimitiveType::DataKindPixelRGB:
   1049           case RSExportPrimitiveType::DataKindPixelRGBA: {
   1050             break;
   1051           }
   1052 
   1053           case RSExportPrimitiveType::DataKindUser:
   1054           default: {
   1055             std::string TypeName = GetElementJavaTypeName(EPT->getType());
   1056             if (C.mTypesToCheck.find(TypeName) == C.mTypesToCheck.end()) {
   1057               C.indent() << "__" << TypeName << " = Element." << TypeName
   1058                          << "(rs);" << std::endl;
   1059               C.mTypesToCheck.insert(TypeName);
   1060             }
   1061             break;
   1062           }
   1063         }
   1064         break;
   1065       }
   1066 
   1067       case RSExportType::ExportClassVector: {
   1068         const RSExportVectorType *EVT =
   1069             static_cast<const RSExportVectorType*>(ET);
   1070         slangAssert(EVT);
   1071 
   1072         const char *TypeName = GetVectorElementName(EVT);
   1073         if (C.mTypesToCheck.find(TypeName) == C.mTypesToCheck.end()) {
   1074           C.indent() << "__" << TypeName << " = Element." << TypeName
   1075                      << "(rs);" << std::endl;
   1076           C.mTypesToCheck.insert(TypeName);
   1077         }
   1078         break;
   1079       }
   1080 
   1081       case RSExportType::ExportClassRecord: {
   1082         const RSExportRecordType *ERT =
   1083             static_cast<const RSExportRecordType*>(ET);
   1084         slangAssert(ERT);
   1085 
   1086         std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
   1087         if (C.mTypesToCheck.find(ClassName) == C.mTypesToCheck.end()) {
   1088           C.indent() << "__" << ClassName << " = " << ClassName <<
   1089                         ".createElement(rs);" << std::endl;
   1090           C.mTypesToCheck.insert(ClassName);
   1091         }
   1092         break;
   1093       }
   1094 
   1095       default:
   1096         break;
   1097     }
   1098   }
   1099 }
   1100 
   1101 void RSReflection::genTypeCheck(Context &C,
   1102                                 const RSExportType *ET,
   1103                                 const char *VarName) {
   1104   C.indent() << "// check " << VarName << std::endl;
   1105 
   1106   if (ET->getClass() == RSExportType::ExportClassPointer) {
   1107     const RSExportPointerType *EPT =
   1108         static_cast<const RSExportPointerType*>(ET);
   1109     ET = EPT->getPointeeType();
   1110   }
   1111 
   1112   std::string TypeName;
   1113 
   1114   switch (ET->getClass()) {
   1115     case RSExportType::ExportClassPrimitive: {
   1116       const RSExportPrimitiveType *EPT =
   1117           static_cast<const RSExportPrimitiveType*>(ET);
   1118       slangAssert(EPT);
   1119 
   1120       if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
   1121         TypeName = GetElementJavaTypeName(EPT->getType());
   1122       }
   1123       break;
   1124     }
   1125 
   1126     case RSExportType::ExportClassVector: {
   1127       const RSExportVectorType *EVT =
   1128           static_cast<const RSExportVectorType*>(ET);
   1129       slangAssert(EVT);
   1130       TypeName = GetVectorElementName(EVT);
   1131       break;
   1132     }
   1133 
   1134     case RSExportType::ExportClassRecord: {
   1135       const RSExportRecordType *ERT =
   1136           static_cast<const RSExportRecordType*>(ET);
   1137       slangAssert(ERT);
   1138       TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
   1139       break;
   1140     }
   1141 
   1142     default:
   1143       break;
   1144   }
   1145 
   1146   if (!TypeName.empty()) {
   1147     C.indent() << "if (!" << VarName
   1148                << ".getType().getElement().isCompatible(__"
   1149                << TypeName << ")) {" << std::endl;
   1150     C.indent() << "    throw new RSRuntimeException(\"Type mismatch with "
   1151                << TypeName << "!\");" << std::endl;
   1152     C.indent() << "}" << std::endl;
   1153   }
   1154 
   1155   return;
   1156 }
   1157 
   1158 
   1159 void RSReflection::genPrimitiveTypeExportVariable(
   1160     Context &C,
   1161     const RSExportVar *EV) {
   1162   slangAssert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive)
   1163               && "Variable should be type of primitive here");
   1164 
   1165   const RSExportPrimitiveType *EPT =
   1166       static_cast<const RSExportPrimitiveType*>(EV->getType());
   1167   const char *TypeName = GetPrimitiveTypeName(EPT);
   1168 
   1169   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1170              << EV->getName() << ";" << std::endl;
   1171 
   1172   // set_*()
   1173   if (!EV->isConst()) {
   1174     C.startFunction(Context::AM_Public,
   1175                     false,
   1176                     "void",
   1177                     "set_" + EV->getName(),
   1178                     1,
   1179                     TypeName, "v");
   1180     C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1181 
   1182     C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
   1183                << ", v);" << std::endl;
   1184 
   1185     C.endFunction();
   1186   }
   1187 
   1188   genGetExportVariable(C, TypeName, EV->getName());
   1189 
   1190   return;
   1191 }
   1192 
   1193 void RSReflection::genPointerTypeExportVariable(Context &C,
   1194                                                 const RSExportVar *EV) {
   1195   const RSExportType *ET = EV->getType();
   1196   const RSExportType *PointeeType;
   1197   std::string TypeName;
   1198 
   1199   slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
   1200               "Variable should be type of pointer here");
   1201 
   1202   PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
   1203   TypeName = GetTypeName(ET);
   1204 
   1205   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1206              << EV->getName() << ";" << std::endl;
   1207 
   1208   // bind_*()
   1209   C.startFunction(Context::AM_Public,
   1210                   false,
   1211                   "void",
   1212                   "bind_" + EV->getName(),
   1213                   1,
   1214                   TypeName.c_str(), "v");
   1215 
   1216   C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1217   C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX
   1218              << EV->getName() << ");" << std::endl;
   1219 
   1220   if (PointeeType->getClass() == RSExportType::ExportClassRecord)
   1221     C.indent() << "else bindAllocation(v.getAllocation(), "
   1222         RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");"
   1223                << std::endl;
   1224   else
   1225     C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX
   1226                << EV->getName() << ");" << std::endl;
   1227 
   1228   C.endFunction();
   1229 
   1230   genGetExportVariable(C, TypeName, EV->getName());
   1231 
   1232   return;
   1233 }
   1234 
   1235 void RSReflection::genVectorTypeExportVariable(Context &C,
   1236                                                const RSExportVar *EV) {
   1237   slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
   1238               "Variable should be type of vector here");
   1239 
   1240   const RSExportVectorType *EVT =
   1241       static_cast<const RSExportVectorType*>(EV->getType());
   1242   const char *TypeName = GetVectorTypeName(EVT);
   1243   const char *FieldPackerName = "fp";
   1244 
   1245   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1246              << EV->getName() << ";" << std::endl;
   1247 
   1248   // set_*()
   1249   if (!EV->isConst()) {
   1250     C.startFunction(Context::AM_Public,
   1251                     false,
   1252                     "void",
   1253                     "set_" + EV->getName(),
   1254                     1,
   1255                     TypeName, "v");
   1256     C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1257 
   1258     if (genCreateFieldPacker(C, EVT, FieldPackerName))
   1259       genPackVarOfType(C, EVT, "v", FieldPackerName);
   1260     C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
   1261                << FieldPackerName << ");" << std::endl;
   1262 
   1263     C.endFunction();
   1264   }
   1265 
   1266   genGetExportVariable(C, TypeName, EV->getName());
   1267   return;
   1268 }
   1269 
   1270 void RSReflection::genMatrixTypeExportVariable(Context &C,
   1271                                                const RSExportVar *EV) {
   1272   slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
   1273               "Variable should be type of matrix here");
   1274 
   1275   const RSExportMatrixType *EMT =
   1276       static_cast<const RSExportMatrixType*>(EV->getType());
   1277   const char *TypeName = GetMatrixTypeName(EMT);
   1278   const char *FieldPackerName = "fp";
   1279 
   1280   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1281              << EV->getName() << ";" << std::endl;
   1282 
   1283   // set_*()
   1284   if (!EV->isConst()) {
   1285     C.startFunction(Context::AM_Public,
   1286                     false,
   1287                     "void",
   1288                     "set_" + EV->getName(),
   1289                     1,
   1290                     TypeName, "v");
   1291     C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1292 
   1293     if (genCreateFieldPacker(C, EMT, FieldPackerName))
   1294       genPackVarOfType(C, EMT, "v", FieldPackerName);
   1295     C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
   1296                << FieldPackerName << ");" << std::endl;
   1297 
   1298     C.endFunction();
   1299   }
   1300 
   1301   genGetExportVariable(C, TypeName, EV->getName());
   1302   return;
   1303 }
   1304 
   1305 void RSReflection::genConstantArrayTypeExportVariable(
   1306     Context &C,
   1307     const RSExportVar *EV) {
   1308   slangAssert((EV->getType()->getClass() ==
   1309                RSExportType::ExportClassConstantArray) &&
   1310               "Variable should be type of constant array here");
   1311 
   1312   const RSExportConstantArrayType *ECAT =
   1313       static_cast<const RSExportConstantArrayType*>(EV->getType());
   1314   std::string TypeName = GetTypeName(ECAT);
   1315   const char *FieldPackerName = "fp";
   1316 
   1317   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1318              << EV->getName() << ";" << std::endl;
   1319 
   1320   // set_*()
   1321   if (!EV->isConst()) {
   1322     C.startFunction(Context::AM_Public,
   1323                     false,
   1324                     "void",
   1325                     "set_" + EV->getName(),
   1326                     1,
   1327                     TypeName.c_str(), "v");
   1328     C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1329 
   1330     if (genCreateFieldPacker(C, ECAT, FieldPackerName))
   1331       genPackVarOfType(C, ECAT, "v", FieldPackerName);
   1332     C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
   1333                << FieldPackerName << ");" << std::endl;
   1334 
   1335     C.endFunction();
   1336   }
   1337 
   1338   genGetExportVariable(C, TypeName, EV->getName());
   1339   return;
   1340 }
   1341 
   1342 void RSReflection::genRecordTypeExportVariable(Context &C,
   1343                                                const RSExportVar *EV) {
   1344   slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
   1345               "Variable should be type of struct here");
   1346 
   1347   const RSExportRecordType *ERT =
   1348       static_cast<const RSExportRecordType*>(EV->getType());
   1349   std::string TypeName =
   1350       RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
   1351   const char *FieldPackerName = "fp";
   1352 
   1353   C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
   1354              << EV->getName() << ";" << std::endl;
   1355 
   1356   // set_*()
   1357   if (!EV->isConst()) {
   1358     C.startFunction(Context::AM_Public,
   1359                     false,
   1360                     "void",
   1361                     "set_" + EV->getName(),
   1362                     1,
   1363                     TypeName.c_str(), "v");
   1364     C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
   1365 
   1366     if (genCreateFieldPacker(C, ERT, FieldPackerName))
   1367       genPackVarOfType(C, ERT, "v", FieldPackerName);
   1368     C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
   1369                << ", " << FieldPackerName << ");" << std::endl;
   1370 
   1371     C.endFunction();
   1372   }
   1373 
   1374   genGetExportVariable(C, TypeName.c_str(), EV->getName());
   1375   return;
   1376 }
   1377 
   1378 void RSReflection::genGetExportVariable(Context &C,
   1379                                         const std::string &TypeName,
   1380                                         const std::string &VarName) {
   1381   C.startFunction(Context::AM_Public,
   1382                   false,
   1383                   TypeName.c_str(),
   1384                   "get_" + VarName,
   1385                   0);
   1386 
   1387   C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl;
   1388 
   1389   C.endFunction();
   1390   return;
   1391 }
   1392 
   1393 /******************* Methods to generate script class /end *******************/
   1394 
   1395 bool RSReflection::genCreateFieldPacker(Context &C,
   1396                                         const RSExportType *ET,
   1397                                         const char *FieldPackerName) {
   1398   size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
   1399   if (AllocSize > 0)
   1400     C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
   1401                << AllocSize << ");" << std::endl;
   1402   else
   1403     return false;
   1404   return true;
   1405 }
   1406 
   1407 void RSReflection::genPackVarOfType(Context &C,
   1408                                     const RSExportType *ET,
   1409                                     const char *VarName,
   1410                                     const char *FieldPackerName) {
   1411   switch (ET->getClass()) {
   1412     case RSExportType::ExportClassPrimitive:
   1413     case RSExportType::ExportClassVector: {
   1414       C.indent() << FieldPackerName << "."
   1415                  << GetPackerAPIName(
   1416                      static_cast<const RSExportPrimitiveType*>(ET))
   1417                  << "(" << VarName << ");" << std::endl;
   1418       break;
   1419     }
   1420     case RSExportType::ExportClassPointer: {
   1421       // Must reflect as type Allocation in Java
   1422       const RSExportType *PointeeType =
   1423           static_cast<const RSExportPointerType*>(ET)->getPointeeType();
   1424 
   1425       if (PointeeType->getClass() != RSExportType::ExportClassRecord)
   1426         C.indent() << FieldPackerName << ".addI32(" << VarName
   1427                    << ".getPtr());" << std::endl;
   1428       else
   1429         C.indent() << FieldPackerName << ".addI32(" << VarName
   1430                    << ".getAllocation().getPtr());" << std::endl;
   1431       break;
   1432     }
   1433     case RSExportType::ExportClassMatrix: {
   1434       C.indent() << FieldPackerName << ".addMatrix(" << VarName << ");"
   1435                  << std::endl;
   1436       break;
   1437     }
   1438     case RSExportType::ExportClassConstantArray: {
   1439       const RSExportConstantArrayType *ECAT =
   1440           static_cast<const RSExportConstantArrayType *>(ET);
   1441 
   1442       // TODO(zonr): more elegant way. Currently, we obtain the unique index
   1443       //             variable (this method involves recursive call which means
   1444       //             we may have more than one level loop, therefore we can't
   1445       //             always use the same index variable name here) name given
   1446       //             in the for-loop from counting the '.' in @VarName.
   1447       unsigned Level = 0;
   1448       size_t LastDotPos = 0;
   1449       std::string ElementVarName(VarName);
   1450 
   1451       while (LastDotPos != std::string::npos) {
   1452         LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
   1453         Level++;
   1454       }
   1455       std::string IndexVarName("ct");
   1456       IndexVarName.append(llvm::utostr_32(Level));
   1457 
   1458       C.indent() << "for (int " << IndexVarName << " = 0; " <<
   1459                           IndexVarName << " < " << ECAT->getSize() << "; " <<
   1460                           IndexVarName << "++)";
   1461       C.startBlock();
   1462 
   1463       ElementVarName.append("[" + IndexVarName + "]");
   1464       genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
   1465                        FieldPackerName);
   1466 
   1467       C.endBlock();
   1468       break;
   1469     }
   1470     case RSExportType::ExportClassRecord: {
   1471       const RSExportRecordType *ERT =
   1472           static_cast<const RSExportRecordType*>(ET);
   1473       // Relative pos from now on in field packer
   1474       unsigned Pos = 0;
   1475 
   1476       for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
   1477                E = ERT->fields_end();
   1478            I != E;
   1479            I++) {
   1480         const RSExportRecordType::Field *F = *I;
   1481         std::string FieldName;
   1482         size_t FieldOffset = F->getOffsetInParent();
   1483         size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
   1484         size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
   1485 
   1486         if (VarName != NULL)
   1487           FieldName = VarName + ("." + F->getName());
   1488         else
   1489           FieldName = F->getName();
   1490 
   1491         if (FieldOffset > Pos)
   1492           C.indent() << FieldPackerName << ".skip("
   1493                      << (FieldOffset - Pos) << ");" << std::endl;
   1494 
   1495         genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
   1496 
   1497         // There is padding in the field type
   1498         if (FieldAllocSize > FieldStoreSize)
   1499             C.indent() << FieldPackerName << ".skip("
   1500                        << (FieldAllocSize - FieldStoreSize)
   1501                        << ");" << std::endl;
   1502 
   1503           Pos = FieldOffset + FieldAllocSize;
   1504       }
   1505 
   1506       // There maybe some padding after the struct
   1507       if (RSExportType::GetTypeAllocSize(ERT) > Pos)
   1508         C.indent() << FieldPackerName << ".skip("
   1509                    << RSExportType::GetTypeAllocSize(ERT) - Pos << ");"
   1510                    << std::endl;
   1511       break;
   1512     }
   1513     default: {
   1514       slangAssert(false && "Unknown class of type");
   1515     }
   1516   }
   1517 
   1518   return;
   1519 }
   1520 
   1521 void RSReflection::genAllocateVarOfType(Context &C,
   1522                                         const RSExportType *T,
   1523                                         const std::string &VarName) {
   1524   switch (T->getClass()) {
   1525     case RSExportType::ExportClassPrimitive: {
   1526       // Primitive type like int in Java has its own storage once it's declared.
   1527       //
   1528       // FIXME: Should we allocate storage for RS object?
   1529       // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
   1530       //  C.indent() << VarName << " = new " << GetTypeName(T) << "();"
   1531       //             << std::endl;
   1532       break;
   1533     }
   1534     case RSExportType::ExportClassPointer: {
   1535       // Pointer type is an instance of Allocation or a TypeClass whose value is
   1536       // expected to be assigned by programmer later in Java program. Therefore
   1537       // we don't reflect things like [VarName] = new Allocation();
   1538       C.indent() << VarName << " = null;" << std::endl;
   1539       break;
   1540     }
   1541     case RSExportType::ExportClassConstantArray: {
   1542       const RSExportConstantArrayType *ECAT =
   1543           static_cast<const RSExportConstantArrayType *>(T);
   1544       const RSExportType *ElementType = ECAT->getElementType();
   1545 
   1546       C.indent() << VarName << " = new " << GetTypeName(ElementType)
   1547                  << "[" << ECAT->getSize() << "];" << std::endl;
   1548 
   1549       // Primitive type element doesn't need allocation code.
   1550       if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
   1551         C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; "
   1552                             "$ct++)";
   1553         C.startBlock();
   1554 
   1555         std::string ElementVarName(VarName);
   1556         ElementVarName.append("[$ct]");
   1557         genAllocateVarOfType(C, ElementType, ElementVarName);
   1558 
   1559         C.endBlock();
   1560       }
   1561       break;
   1562     }
   1563     case RSExportType::ExportClassVector:
   1564     case RSExportType::ExportClassMatrix:
   1565     case RSExportType::ExportClassRecord: {
   1566       C.indent() << VarName << " = new " << GetTypeName(T) << "();"
   1567                  << std::endl;
   1568       break;
   1569     }
   1570   }
   1571   return;
   1572 }
   1573 
   1574 void RSReflection::genNewItemBufferIfNull(Context &C,
   1575                                           const char *Index) {
   1576   C.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME " == null) "
   1577                   RS_TYPE_ITEM_BUFFER_NAME " = "
   1578                     "new " RS_TYPE_ITEM_CLASS_NAME
   1579                       "[getType().getX() /* count */];"
   1580              << std::endl;
   1581   if (Index != NULL)
   1582     C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) "
   1583                     RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = "
   1584                       "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
   1585   return;
   1586 }
   1587 
   1588 void RSReflection::genNewItemBufferPackerIfNull(Context &C) {
   1589   C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " == null) "
   1590                   RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
   1591                     "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
   1592                       ".sizeof * getType().getX()/* count */"
   1593                         ");" << std::endl;
   1594   return;
   1595 }
   1596 
   1597 /********************** Methods to generate type class  **********************/
   1598 bool RSReflection::genTypeClass(Context &C,
   1599                                 const RSExportRecordType *ERT,
   1600                                 std::string &ErrorMsg) {
   1601   std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
   1602 
   1603   if (!C.startClass(Context::AM_Public,
   1604                     false,
   1605                     ClassName,
   1606                     RS_TYPE_CLASS_SUPER_CLASS_NAME,
   1607                     ErrorMsg))
   1608     return false;
   1609 
   1610   mGeneratedFileNames->push_back(ClassName);
   1611 
   1612   genTypeItemClass(C, ERT);
   1613 
   1614   // Declare item buffer and item buffer packer
   1615   C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]"
   1616       ";" << std::endl;
   1617   C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";"
   1618              << std::endl;
   1619 
   1620   genTypeClassConstructor(C, ERT);
   1621   genTypeClassCopyToArrayLocal(C, ERT);
   1622   genTypeClassCopyToArray(C, ERT);
   1623   genTypeClassItemSetter(C, ERT);
   1624   genTypeClassItemGetter(C, ERT);
   1625   genTypeClassComponentSetter(C, ERT);
   1626   genTypeClassComponentGetter(C, ERT);
   1627   genTypeClassCopyAll(C, ERT);
   1628   genTypeClassResize(C);
   1629 
   1630   C.endClass();
   1631 
   1632   C.resetFieldIndex();
   1633   C.clearFieldIndexMap();
   1634 
   1635   return true;
   1636 }
   1637 
   1638 void RSReflection::genTypeItemClass(Context &C,
   1639                                     const RSExportRecordType *ERT) {
   1640   C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
   1641   C.startBlock();
   1642 
   1643   C.indent() << "public static final int sizeof = "
   1644              << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl;
   1645 
   1646   // Member elements
   1647   C.out() << std::endl;
   1648   for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
   1649            FE = ERT->fields_end();
   1650        FI != FE;
   1651        FI++) {
   1652     C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
   1653                << ";" << std::endl;
   1654   }
   1655 
   1656   // Constructor
   1657   C.out() << std::endl;
   1658   C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
   1659   C.startBlock();
   1660 
   1661   for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
   1662            FE = ERT->fields_end();
   1663        FI != FE;
   1664        FI++) {
   1665     const RSExportRecordType::Field *F = *FI;
   1666     genAllocateVarOfType(C, F->getType(), F->getName());
   1667   }
   1668 
   1669   // end Constructor
   1670   C.endBlock();
   1671 
   1672   // end Item class
   1673   C.endBlock();
   1674 
   1675   return;
   1676 }
   1677 
   1678 void RSReflection::genTypeClassConstructor(Context &C,
   1679                                            const RSExportRecordType *ERT) {
   1680   const char *RenderScriptVar = "rs";
   1681 
   1682   C.startFunction(Context::AM_Public,
   1683                   true,
   1684                   "Element",
   1685                   "createElement",
   1686                   1,
   1687                   "RenderScript", RenderScriptVar);
   1688   genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */false);
   1689   C.endFunction();
   1690 
   1691   C.startFunction(Context::AM_Public,
   1692                   false,
   1693                   NULL,
   1694                   C.getClassName(),
   1695                   2,
   1696                   "RenderScript", RenderScriptVar,
   1697                   "int", "count");
   1698 
   1699   C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
   1700   C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
   1701   C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
   1702              << std::endl;
   1703   // Call init() in super class
   1704   C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl;
   1705   C.endFunction();
   1706 
   1707   C.startFunction(Context::AM_Public,
   1708                   false,
   1709                   NULL,
   1710                   C.getClassName(),
   1711                   3,
   1712                   "RenderScript", RenderScriptVar,
   1713                   "int", "count",
   1714                   "int", "usages");
   1715 
   1716   C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
   1717   C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
   1718   C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
   1719              << std::endl;
   1720   // Call init() in super class
   1721   C.indent() << "init(" << RenderScriptVar << ", count, usages);" << std::endl;
   1722   C.endFunction();
   1723 
   1724   return;
   1725 }
   1726 
   1727 void RSReflection::genTypeClassCopyToArray(Context &C,
   1728                                            const RSExportRecordType *ERT) {
   1729   C.startFunction(Context::AM_Private,
   1730                   false,
   1731                   "void",
   1732                   "copyToArray",
   1733                   2,
   1734                   RS_TYPE_ITEM_CLASS_NAME, "i",
   1735                   "int", "index");
   1736 
   1737   genNewItemBufferPackerIfNull(C);
   1738   C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
   1739                 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
   1740              << std::endl;
   1741 
   1742   C.indent() << "copyToArrayLocal(i, " RS_TYPE_ITEM_BUFFER_PACKER_NAME
   1743                 ");" << std::endl;
   1744 
   1745   C.endFunction();
   1746   return;
   1747 }
   1748 
   1749 void RSReflection::genTypeClassCopyToArrayLocal(Context &C,
   1750                                                 const RSExportRecordType *ERT) {
   1751   C.startFunction(Context::AM_Private,
   1752                   false,
   1753                   "void",
   1754                   "copyToArrayLocal",
   1755                   2,
   1756                   RS_TYPE_ITEM_CLASS_NAME, "i",
   1757                   "FieldPacker", "fp");
   1758 
   1759   genPackVarOfType(C, ERT, "i", "fp");
   1760 
   1761   C.endFunction();
   1762   return;
   1763 }
   1764 
   1765 void RSReflection::genTypeClassItemSetter(Context &C,
   1766                                           const RSExportRecordType *ERT) {
   1767   C.startFunction(Context::AM_PublicSynchronized,
   1768                   false,
   1769                   "void",
   1770                   "set",
   1771                   3,
   1772                   RS_TYPE_ITEM_CLASS_NAME, "i",
   1773                   "int", "index",
   1774                   "boolean", "copyNow");
   1775   genNewItemBufferIfNull(C, NULL);
   1776   C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl;
   1777 
   1778   C.indent() << "if (copyNow) ";
   1779   C.startBlock();
   1780 
   1781   C.indent() << "copyToArray(i, index);" << std::endl;
   1782   C.indent() << "FieldPacker fp = new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
   1783                 ".sizeof);" << std::endl;
   1784   C.indent() << "copyToArrayLocal(i, fp);" << std::endl;
   1785   C.indent() << "mAllocation.setFromFieldPacker(index, fp);" << std::endl;
   1786 
   1787   // End of if (copyNow)
   1788   C.endBlock();
   1789 
   1790   C.endFunction();
   1791   return;
   1792 }
   1793 
   1794 void RSReflection::genTypeClassItemGetter(Context &C,
   1795                                           const RSExportRecordType *ERT) {
   1796   C.startFunction(Context::AM_PublicSynchronized,
   1797                   false,
   1798                   RS_TYPE_ITEM_CLASS_NAME,
   1799                   "get",
   1800                   1,
   1801                   "int", "index");
   1802   C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;"
   1803              << std::endl;
   1804   C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl;
   1805   C.endFunction();
   1806   return;
   1807 }
   1808 
   1809 void RSReflection::genTypeClassComponentSetter(Context &C,
   1810                                                const RSExportRecordType *ERT) {
   1811   for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
   1812            FE = ERT->fields_end();
   1813        FI != FE;
   1814        FI++) {
   1815     const RSExportRecordType::Field *F = *FI;
   1816     size_t FieldOffset = F->getOffsetInParent();
   1817     size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
   1818     unsigned FieldIndex = C.getFieldIndex(F);
   1819 
   1820     C.startFunction(Context::AM_PublicSynchronized,
   1821                     false,
   1822                     "void",
   1823                     "set_" + F->getName(), 3,
   1824                     "int", "index",
   1825                     GetTypeName(F->getType()).c_str(), "v",
   1826                     "boolean", "copyNow");
   1827     genNewItemBufferPackerIfNull(C);
   1828     genNewItemBufferIfNull(C, "index");
   1829     C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
   1830                << " = v;" << std::endl;
   1831 
   1832     C.indent() << "if (copyNow) ";
   1833     C.startBlock();
   1834 
   1835     if (FieldOffset > 0)
   1836       C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
   1837                     ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + "
   1838                  << FieldOffset << ");" << std::endl;
   1839     else
   1840       C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
   1841                     ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
   1842                  << std::endl;
   1843     genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
   1844 
   1845     C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");"
   1846                << std::endl;
   1847     genPackVarOfType(C, F->getType(), "v", "fp");
   1848     C.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex
   1849                << ", fp);"
   1850                << std::endl;
   1851 
   1852     // End of if (copyNow)
   1853     C.endBlock();
   1854 
   1855     C.endFunction();
   1856   }
   1857   return;
   1858 }
   1859 
   1860 void RSReflection::genTypeClassComponentGetter(Context &C,
   1861                                                const RSExportRecordType *ERT) {
   1862   for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
   1863            FE = ERT->fields_end();
   1864        FI != FE;
   1865        FI++) {
   1866     const RSExportRecordType::Field *F = *FI;
   1867     C.startFunction(Context::AM_PublicSynchronized,
   1868                     false,
   1869                     GetTypeName(F->getType()).c_str(),
   1870                     "get_" + F->getName(),
   1871                     1,
   1872                     "int", "index");
   1873     C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return "
   1874                << GetTypeNullValue(F->getType()) << ";" << std::endl;
   1875     C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
   1876                << ";" << std::endl;
   1877     C.endFunction();
   1878   }
   1879   return;
   1880 }
   1881 
   1882 void RSReflection::genTypeClassCopyAll(Context &C,
   1883                                        const RSExportRecordType *ERT) {
   1884   C.startFunction(Context::AM_PublicSynchronized, false, "void", "copyAll", 0);
   1885 
   1886   C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)"
   1887                   " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);"
   1888              << std::endl;
   1889   C.indent() << "mAllocation.setFromFieldPacker(0, "
   1890                   RS_TYPE_ITEM_BUFFER_PACKER_NAME");"
   1891              << std::endl;
   1892 
   1893   C.endFunction();
   1894   return;
   1895 }
   1896 
   1897 void RSReflection::genTypeClassResize(Context &C) {
   1898   C.startFunction(Context::AM_PublicSynchronized,
   1899                   false,
   1900                   "void",
   1901                   "resize",
   1902                   1,
   1903                   "int", "newSize");
   1904 
   1905   C.indent() << "if (mItemArray != null) ";
   1906   C.startBlock();
   1907   C.indent() << "int oldSize = mItemArray.length;" << std::endl;
   1908   C.indent() << "int copySize = Math.min(oldSize, newSize);" << std::endl;
   1909   C.indent() << "if (newSize == oldSize) return;" << std::endl;
   1910   C.indent() << "Item ni[] = new Item[newSize];" << std::endl;
   1911   C.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);"
   1912              << std::endl;
   1913   C.indent() << "mItemArray = ni;" << std::endl;
   1914   C.endBlock();
   1915   C.indent() << "mAllocation.resize(newSize);" << std::endl;
   1916 
   1917   C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " != null) "
   1918                   RS_TYPE_ITEM_BUFFER_PACKER_NAME " = "
   1919                     "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME
   1920                       ".sizeof * getType().getX()/* count */"
   1921                         ");" << std::endl;
   1922 
   1923   C.endFunction();
   1924   return;
   1925 }
   1926 
   1927 /******************** Methods to generate type class /end ********************/
   1928 
   1929 /********** Methods to create Element in Java of given record type ***********/
   1930 void RSReflection::genBuildElement(Context &C,
   1931                                    const char *ElementBuilderName,
   1932                                    const RSExportRecordType *ERT,
   1933                                    const char *RenderScriptVar,
   1934                                    bool IsInline) {
   1935   C.indent() << "Element.Builder " << ElementBuilderName << " = "
   1936       "new Element.Builder(" << RenderScriptVar << ");" << std::endl;
   1937 
   1938   // eb.add(...)
   1939   genAddElementToElementBuilder(C,
   1940                                 ERT,
   1941                                 "",
   1942                                 ElementBuilderName,
   1943                                 RenderScriptVar,
   1944                                 /* ArraySize = */0);
   1945 
   1946   if (!IsInline)
   1947     C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
   1948   return;
   1949 }
   1950 
   1951 #define EB_ADD(x) do {                                              \
   1952   C.indent() << ElementBuilderName                                  \
   1953              << ".add(" << x << ", \"" << VarName << "\"";  \
   1954   if (ArraySize > 0)                                                \
   1955     C.out() << ", " << ArraySize;                                   \
   1956   C.out() << ");" << std::endl;                                     \
   1957   C.incFieldIndex();                                                \
   1958 } while (false)
   1959 
   1960 void RSReflection::genAddElementToElementBuilder(Context &C,
   1961                                                  const RSExportType *ET,
   1962                                                  const std::string &VarName,
   1963                                                  const char *ElementBuilderName,
   1964                                                  const char *RenderScriptVar,
   1965                                                  unsigned ArraySize) {
   1966   const char *ElementConstruct = GetBuiltinElementConstruct(ET);
   1967 
   1968   if (ElementConstruct != NULL) {
   1969     EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
   1970   } else {
   1971     if ((ET->getClass() == RSExportType::ExportClassPrimitive) ||
   1972         (ET->getClass() == RSExportType::ExportClassVector)) {
   1973       const RSExportPrimitiveType *EPT =
   1974           static_cast<const RSExportPrimitiveType*>(ET);
   1975       const char *DataKindName = GetElementDataKindName(EPT->getKind());
   1976       const char *DataTypeName = GetElementDataTypeName(EPT->getType());
   1977       int Size = (ET->getClass() == RSExportType::ExportClassVector) ?
   1978           static_cast<const RSExportVectorType*>(ET)->getNumElement() :
   1979           1;
   1980 
   1981       switch (EPT->getKind()) {
   1982         case RSExportPrimitiveType::DataKindPixelL:
   1983         case RSExportPrimitiveType::DataKindPixelA:
   1984         case RSExportPrimitiveType::DataKindPixelLA:
   1985         case RSExportPrimitiveType::DataKindPixelRGB:
   1986         case RSExportPrimitiveType::DataKindPixelRGBA: {
   1987           // Element.createPixel()
   1988           EB_ADD("Element.createPixel(" << RenderScriptVar << ", "
   1989                                         << DataTypeName << ", "
   1990                                         << DataKindName << ")");
   1991           break;
   1992         }
   1993         case RSExportPrimitiveType::DataKindUser:
   1994         default: {
   1995           if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
   1996             // Element.createUser()
   1997             EB_ADD("Element.createUser(" << RenderScriptVar << ", "
   1998                                          << DataTypeName << ")");
   1999           } else {
   2000             slangAssert((ET->getClass() == RSExportType::ExportClassVector) &&
   2001                         "Unexpected type.");
   2002             EB_ADD("Element.createVector(" << RenderScriptVar << ", "
   2003                                            << DataTypeName << ", "
   2004                                            << Size << ")");
   2005           }
   2006           break;
   2007         }
   2008       }
   2009 #ifndef NDEBUG
   2010     } else if (ET->getClass() == RSExportType::ExportClassPointer) {
   2011       // Pointer type variable should be resolved in
   2012       // GetBuiltinElementConstruct()
   2013       slangAssert(false && "??");
   2014     } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
   2015       // Matrix type variable should be resolved
   2016       // in GetBuiltinElementConstruct()
   2017       slangAssert(false && "??");
   2018 #endif
   2019     } else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
   2020       const RSExportConstantArrayType *ECAT =
   2021           static_cast<const RSExportConstantArrayType *>(ET);
   2022 
   2023       const RSExportType *ElementType = ECAT->getElementType();
   2024       if (ElementType->getClass() != RSExportType::ExportClassRecord) {
   2025         genAddElementToElementBuilder(C,
   2026                                       ECAT->getElementType(),
   2027                                       VarName,
   2028                                       ElementBuilderName,
   2029                                       RenderScriptVar,
   2030                                       ECAT->getSize());
   2031       } else {
   2032         std::string NewElementBuilderName(ElementBuilderName);
   2033         NewElementBuilderName.append(1, '_');
   2034 
   2035         genBuildElement(C,
   2036                         NewElementBuilderName.c_str(),
   2037                         static_cast<const RSExportRecordType*>(ElementType),
   2038                         RenderScriptVar,
   2039                         /* IsInline = */true);
   2040         ArraySize = ECAT->getSize();
   2041         EB_ADD(NewElementBuilderName << ".create()");
   2042       }
   2043     } else if (ET->getClass() == RSExportType::ExportClassRecord) {
   2044       // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
   2045       //
   2046       // TODO(zonr): Generalize these two function such that there's no
   2047       //             duplicated codes.
   2048       const RSExportRecordType *ERT =
   2049           static_cast<const RSExportRecordType*>(ET);
   2050       int Pos = 0;    // relative pos from now on
   2051 
   2052       for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
   2053                E = ERT->fields_end();
   2054            I != E;
   2055            I++) {
   2056         const RSExportRecordType::Field *F = *I;
   2057         std::string FieldName;
   2058         int FieldOffset = F->getOffsetInParent();
   2059         int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
   2060         int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
   2061 
   2062         if (!VarName.empty())
   2063           FieldName = VarName + "." + F->getName();
   2064         else
   2065           FieldName = F->getName();
   2066 
   2067         // Alignment
   2068         genAddPaddingToElementBuiler(C,
   2069                                      (FieldOffset - Pos),
   2070                                      ElementBuilderName,
   2071                                      RenderScriptVar);
   2072 
   2073         // eb.add(...)
   2074         C.addFieldIndexMapping(F);
   2075         if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
   2076           genAddElementToElementBuilder(C,
   2077                                         F->getType(),
   2078                                         FieldName,
   2079                                         ElementBuilderName,
   2080                                         RenderScriptVar,
   2081                                         0);
   2082         } else {
   2083           std::string NewElementBuilderName(ElementBuilderName);
   2084           NewElementBuilderName.append(1, '_');
   2085 
   2086           genBuildElement(C,
   2087                           NewElementBuilderName.c_str(),
   2088                           static_cast<const RSExportRecordType*>(F->getType()),
   2089                           RenderScriptVar,
   2090                           /* IsInline = */true);
   2091 
   2092           const std::string &VarName = FieldName;  // Hack for EB_ADD macro
   2093           EB_ADD(NewElementBuilderName << ".create()");
   2094         }
   2095 
   2096         // There is padding within the field type
   2097         genAddPaddingToElementBuiler(C,
   2098                                      (FieldAllocSize - FieldStoreSize),
   2099                                      ElementBuilderName,
   2100                                      RenderScriptVar);
   2101 
   2102         Pos = FieldOffset + FieldAllocSize;
   2103       }
   2104 
   2105       // There maybe some padding after the struct
   2106       size_t RecordAllocSize = RSExportType::GetTypeAllocSize(ERT);
   2107 
   2108       genAddPaddingToElementBuiler(C,
   2109                                    RecordAllocSize - Pos,
   2110                                    ElementBuilderName,
   2111                                    RenderScriptVar);
   2112     } else {
   2113       slangAssert(false && "Unknown class of type");
   2114     }
   2115   }
   2116 }
   2117 
   2118 void RSReflection::genAddPaddingToElementBuiler(Context &C,
   2119                                                 int PaddingSize,
   2120                                                 const char *ElementBuilderName,
   2121                                                 const char *RenderScriptVar) {
   2122   unsigned ArraySize = 0;   // Hack the EB_ADD macro
   2123   while (PaddingSize > 0) {
   2124     const std::string &VarName = C.createPaddingField();
   2125     if (PaddingSize >= 4) {
   2126       EB_ADD("Element.U32(" << RenderScriptVar << ")");
   2127       PaddingSize -= 4;
   2128     } else if (PaddingSize >= 2) {
   2129       EB_ADD("Element.U16(" << RenderScriptVar << ")");
   2130       PaddingSize -= 2;
   2131     } else if (PaddingSize >= 1) {
   2132       EB_ADD("Element.U8(" << RenderScriptVar << ")");
   2133       PaddingSize -= 1;
   2134     }
   2135   }
   2136   return;
   2137 }
   2138 
   2139 #undef EB_ADD
   2140 /******** Methods to create Element in Java of given record type /end ********/
   2141 
   2142 bool RSReflection::reflect(const std::string &OutputPathBase,
   2143                            const std::string &OutputPackageName,
   2144                            const std::string &InputFileName,
   2145                            const std::string &OutputBCFileName) {
   2146   Context *C = NULL;
   2147   std::string ResourceId = "";
   2148 
   2149   if (!GetClassNameFromFileName(OutputBCFileName, ResourceId))
   2150     return false;
   2151 
   2152   if (ResourceId.empty())
   2153     ResourceId = "<Resource ID>";
   2154 
   2155   if (OutputPackageName.empty() || OutputPackageName == "-")
   2156     C = new Context(OutputPathBase, InputFileName, "<Package Name>",
   2157                     ResourceId, true);
   2158   else
   2159     C = new Context(OutputPathBase, InputFileName, OutputPackageName,
   2160                     ResourceId, false);
   2161 
   2162   if (C != NULL) {
   2163     std::string ErrorMsg, ScriptClassName;
   2164     // class ScriptC_<ScriptName>
   2165     if (!GetClassNameFromFileName(InputFileName, ScriptClassName))
   2166       return false;
   2167 
   2168     if (ScriptClassName.empty())
   2169       ScriptClassName = "<Input Script Name>";
   2170 
   2171     ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
   2172 
   2173     if (mRSContext->getLicenseNote() != NULL) {
   2174       C->setLicenseNote(*(mRSContext->getLicenseNote()));
   2175     }
   2176 
   2177     if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
   2178       std::cerr << "Failed to generate class " << ScriptClassName << " ("
   2179                 << ErrorMsg << ")" << std::endl;
   2180       return false;
   2181     }
   2182 
   2183     mGeneratedFileNames->push_back(ScriptClassName);
   2184 
   2185     // class ScriptField_<TypeName>
   2186     for (RSContext::const_export_type_iterator TI =
   2187              mRSContext->export_types_begin(),
   2188              TE = mRSContext->export_types_end();
   2189          TI != TE;
   2190          TI++) {
   2191       const RSExportType *ET = TI->getValue();
   2192 
   2193       if (ET->getClass() == RSExportType::ExportClassRecord) {
   2194         const RSExportRecordType *ERT =
   2195             static_cast<const RSExportRecordType*>(ET);
   2196 
   2197         if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
   2198           std::cerr << "Failed to generate type class for struct '"
   2199                     << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl;
   2200           return false;
   2201         }
   2202       }
   2203     }
   2204   }
   2205 
   2206   return true;
   2207 }
   2208 
   2209 /************************** RSReflection::Context **************************/
   2210 const char *const RSReflection::Context::ApacheLicenseNote =
   2211     "/*\n"
   2212     " * Copyright (C) 2011 The Android Open Source Project\n"
   2213     " *\n"
   2214     " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
   2215     " * you may not use this file except in compliance with the License.\n"
   2216     " * You may obtain a copy of the License at\n"
   2217     " *\n"
   2218     " *      http://www.apache.org/licenses/LICENSE-2.0\n"
   2219     " *\n"
   2220     " * Unless required by applicable law or agreed to in writing, software\n"
   2221     " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
   2222     " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
   2223     "implied.\n"
   2224     " * See the License for the specific language governing permissions and\n"
   2225     " * limitations under the License.\n"
   2226     " */\n"
   2227     "\n";
   2228 
   2229 const char *const RSReflection::Context::Import[] = {
   2230   // Renderscript java class
   2231   "android.renderscript.*",
   2232   // Import R
   2233   "android.content.res.Resources",
   2234   // Import for debugging
   2235   // "android.util.Log",
   2236 };
   2237 
   2238 bool RSReflection::Context::openClassFile(const std::string &ClassName,
   2239                                           std::string &ErrorMsg) {
   2240   if (!mUseStdout) {
   2241     mOF.clear();
   2242     std::string Path =
   2243         RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(),
   2244                                                  mPackageName.c_str());
   2245 
   2246     if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg))
   2247       return false;
   2248 
   2249     std::string ClassFile = Path + OS_PATH_SEPARATOR_STR + ClassName + ".java";
   2250 
   2251     mOF.open(ClassFile.c_str());
   2252     if (!mOF.good()) {
   2253       ErrorMsg = "failed to open file '" + ClassFile + "' for write";
   2254       return false;
   2255     }
   2256   }
   2257   return true;
   2258 }
   2259 
   2260 const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) {
   2261   switch (AM) {
   2262     case AM_Public: return "public"; break;
   2263     case AM_Protected: return "protected"; break;
   2264     case AM_Private: return "private"; break;
   2265     case AM_PublicSynchronized: return "public synchronized"; break;
   2266     default: return ""; break;
   2267   }
   2268 }
   2269 
   2270 bool RSReflection::Context::startClass(AccessModifier AM,
   2271                                        bool IsStatic,
   2272                                        const std::string &ClassName,
   2273                                        const char *SuperClassName,
   2274                                        std::string &ErrorMsg) {
   2275   if (mVerbose)
   2276     std::cout << "Generating " << ClassName << ".java ..." << std::endl;
   2277 
   2278   // Open file for class
   2279   if (!openClassFile(ClassName, ErrorMsg))
   2280     return false;
   2281 
   2282   // License
   2283   out() << mLicenseNote;
   2284 
   2285   // Notice of generated file
   2286   out() << "/*" << std::endl;
   2287   out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl;
   2288   out() << " * The source Renderscript file: " << mInputRSFile << std::endl;
   2289   out() << " */" << std::endl;
   2290 
   2291   // Package
   2292   if (!mPackageName.empty())
   2293     out() << "package " << mPackageName << ";" << std::endl;
   2294   out() << std::endl;
   2295 
   2296   // Imports
   2297   for (unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
   2298     out() << "import " << Import[i] << ";" << std::endl;
   2299   out() << std::endl;
   2300 
   2301   // All reflected classes should be annotated as hidden, so that they won't
   2302   // be exposed in SDK.
   2303   out() << "/**" << std::endl;
   2304   out() << " * @hide" << std::endl;
   2305   out() << " */" << std::endl;
   2306 
   2307   out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
   2308         << ClassName;
   2309   if (SuperClassName != NULL)
   2310     out() << " extends " << SuperClassName;
   2311 
   2312   startBlock();
   2313 
   2314   mClassName = ClassName;
   2315 
   2316   return true;
   2317 }
   2318 
   2319 void RSReflection::Context::endClass() {
   2320   endBlock();
   2321   if (!mUseStdout)
   2322     mOF.close();
   2323   clear();
   2324   return;
   2325 }
   2326 
   2327 void RSReflection::Context::startBlock(bool ShouldIndent) {
   2328   if (ShouldIndent)
   2329     indent() << "{" << std::endl;
   2330   else
   2331     out() << " {" << std::endl;
   2332   incIndentLevel();
   2333   return;
   2334 }
   2335 
   2336 void RSReflection::Context::endBlock() {
   2337   decIndentLevel();
   2338   indent() << "}" << std::endl << std::endl;
   2339   return;
   2340 }
   2341 
   2342 void RSReflection::Context::startTypeClass(const std::string &ClassName) {
   2343   indent() << "public static class " << ClassName;
   2344   startBlock();
   2345   return;
   2346 }
   2347 
   2348 void RSReflection::Context::endTypeClass() {
   2349   endBlock();
   2350   return;
   2351 }
   2352 
   2353 void RSReflection::Context::startFunction(AccessModifier AM,
   2354                                           bool IsStatic,
   2355                                           const char *ReturnType,
   2356                                           const std::string &FunctionName,
   2357                                           int Argc, ...) {
   2358   ArgTy Args;
   2359   va_list vl;
   2360   va_start(vl, Argc);
   2361 
   2362   for (int i = 0; i < Argc; i++) {
   2363     const char *ArgType = va_arg(vl, const char*);
   2364     const char *ArgName = va_arg(vl, const char*);
   2365 
   2366     Args.push_back(std::make_pair(ArgType, ArgName));
   2367   }
   2368   va_end(vl);
   2369 
   2370   startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
   2371 
   2372   return;
   2373 }
   2374 
   2375 void RSReflection::Context::startFunction(AccessModifier AM,
   2376                                           bool IsStatic,
   2377                                           const char *ReturnType,
   2378                                           const std::string &FunctionName,
   2379                                           const ArgTy &Args) {
   2380   indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
   2381            << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
   2382 
   2383   bool FirstArg = true;
   2384   for (ArgTy::const_iterator I = Args.begin(), E = Args.end();
   2385        I != E;
   2386        I++) {
   2387     if (!FirstArg)
   2388       out() << ", ";
   2389     else
   2390       FirstArg = false;
   2391 
   2392     out() << I->first << " " << I->second;
   2393   }
   2394 
   2395   out() << ")";
   2396   startBlock();
   2397 
   2398   return;
   2399 }
   2400 
   2401 void RSReflection::Context::endFunction() {
   2402   endBlock();
   2403   return;
   2404 }
   2405 
   2406 }  // namespace slang
   2407