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