blob: 55b3d4db405bb31ba53c54049a965a045090d263 [file] [log] [blame]
Jason Sams1b6a0882012-03-12 15:07:58 -07001/*
2 * Copyright 2012, 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 <sys/stat.h>
18#include <stdio.h>
19#include <stdlib.h>
20
21#include <cstdarg>
22#include <cctype>
23
24#include <algorithm>
25#include <sstream>
26#include <string>
27#include <utility>
28
29#include "os_sep.h"
30#include "slang_rs_context.h"
31#include "slang_rs_export_var.h"
32#include "slang_rs_export_foreach.h"
33#include "slang_rs_export_func.h"
34#include "slang_rs_reflect_utils.h"
35#include "slang_version.h"
36#include "slang_utils.h"
37
38#include "slang_rs_reflection_cpp.h"
39
40using namespace std;
41
42namespace slang {
43
Stephen Hines7dd6da22012-11-15 19:56:03 -080044#define RS_TYPE_ITEM_CLASS_NAME "Item"
45
46static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
47 static const char *MatrixTypeCNameMap[] = {
48 "rs_matrix2x2",
49 "rs_matrix3x3",
50 "rs_matrix4x4",
51 };
52 unsigned Dim = EMT->getDim();
53
54 if ((Dim - 2) < (sizeof(MatrixTypeCNameMap) / sizeof(const char*)))
55 return MatrixTypeCNameMap[ EMT->getDim() - 2 ];
56
57 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
58 return NULL;
59}
60
61
62static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
63 switch (ET->getClass()) {
64 case RSExportType::ExportClassPrimitive: {
65 return RSExportPrimitiveType::getRSReflectionType(
66 static_cast<const RSExportPrimitiveType*>(ET))->c_name;
67 }
68 case RSExportType::ExportClassPointer: {
69 const RSExportType *PointeeType =
70 static_cast<const RSExportPointerType*>(ET)->getPointeeType();
71
72 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
73 return "android::sp<android::RSC::Allocation>";
74 else
75 return PointeeType->getElementName();
76 }
77 case RSExportType::ExportClassVector: {
78 const RSExportVectorType *EVT =
79 static_cast<const RSExportVectorType*>(ET);
80 std::stringstream VecName;
81 VecName << EVT->getRSReflectionType(EVT)->rs_c_vector_prefix
82 << EVT->getNumElement();
83 return VecName.str();
84 }
85 case RSExportType::ExportClassMatrix: {
86 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
87 }
88 case RSExportType::ExportClassConstantArray: {
89 // TODO: Fix this for C arrays!
90 const RSExportConstantArrayType* CAT =
91 static_cast<const RSExportConstantArrayType*>(ET);
92 std::string ElementTypeName = GetTypeName(CAT->getElementType());
93 if (Brackets) {
94 ElementTypeName.append("[]");
95 }
96 return ElementTypeName;
97 }
98 case RSExportType::ExportClassRecord: {
99 // TODO: Fix for C structs!
100 return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
101 }
102 default: {
103 slangAssert(false && "Unknown class of type");
104 }
105 }
106
107 return "";
108}
109
110
Stephen Hines02a98262012-11-14 12:40:26 -0800111RSReflectionCpp::RSReflectionCpp(const RSContext *con)
112 : RSReflectionBase(con) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800113 clear();
Jason Sams1b6a0882012-03-12 15:07:58 -0700114}
115
116RSReflectionCpp::~RSReflectionCpp() {
Jason Sams1b6a0882012-03-12 15:07:58 -0700117}
118
119bool RSReflectionCpp::reflect(const string &OutputPathBase,
120 const string &InputFileName,
121 const string &OutputBCFileName) {
Stephen Hines02a98262012-11-14 12:40:26 -0800122 mInputFileName = InputFileName;
123 mOutputPath = OutputPathBase;
124 mOutputBCFileName = OutputBCFileName;
125 mClassName = string("ScriptC_") + stripRS(InputFileName);
Jason Sams1b6a0882012-03-12 15:07:58 -0700126
Tim Murray140b9d42012-11-16 14:24:22 -0800127 makeHeader("android::RSC::ScriptC");
Stephen Hines02a98262012-11-14 12:40:26 -0800128 std::vector< std::string > header(mText);
129 mText.clear();
Jason Sams1b6a0882012-03-12 15:07:58 -0700130
Tim Murray140b9d42012-11-16 14:24:22 -0800131 makeImpl("android::RSC::ScriptC");
Stephen Hines02a98262012-11-14 12:40:26 -0800132 std::vector< std::string > cpp(mText);
133 mText.clear();
Jason Sams1b6a0882012-03-12 15:07:58 -0700134
135
Stephen Hines02a98262012-11-14 12:40:26 -0800136 writeFile(mClassName + ".h", header);
137 writeFile(mClassName + ".cpp", cpp);
Jason Sams1b6a0882012-03-12 15:07:58 -0700138
139
Stephen Hines02a98262012-11-14 12:40:26 -0800140 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700141}
142
Jason Sams1b6a0882012-03-12 15:07:58 -0700143
144#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
145
146
147
148bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
Stephen Hines02a98262012-11-14 12:40:26 -0800149 startFile(mClassName + ".h");
Jason Sams1b6a0882012-03-12 15:07:58 -0700150
Stephen Hines02a98262012-11-14 12:40:26 -0800151 write("");
152 write("#include \"RenderScript.h\"");
Tim Murray140b9d42012-11-16 14:24:22 -0800153 write("using namespace android::RSC;");
Stephen Hines02a98262012-11-14 12:40:26 -0800154 write("");
Jason Sams1b6a0882012-03-12 15:07:58 -0700155
Stephen Hines02a98262012-11-14 12:40:26 -0800156 // Imports
157 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
158 //out() << "import " << Import[i] << ";" << std::endl;
159 //out() << std::endl;
Jason Sams1b6a0882012-03-12 15:07:58 -0700160
Stephen Hines02a98262012-11-14 12:40:26 -0800161 if (!baseClass.empty()) {
162 write("class " + mClassName + " : public " + baseClass + " {");
163 } else {
164 write("class " + mClassName + " {");
165 }
166
167 write("private:");
168 uint32_t slot = 0;
169 incIndent();
170 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
171 E = mRSContext->export_vars_end(); I != E; I++, slot++) {
172 const RSExportVar *ev = *I;
173 RSReflectionTypeData rtd;
174 ev->getType()->convertToRTD(&rtd);
175 if (!ev->isConst()) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800176 write(GetTypeName(ev->getType()) + " __" + ev->getName() + ";");
Stephen Hines02a98262012-11-14 12:40:26 -0800177 }
178 }
179 decIndent();
180
181 write("public:");
182 incIndent();
Tim Murraydde98532013-07-23 15:55:19 -0700183 write(mClassName + "(android::sp<android::RSC::RS> rs);");
Stephen Hines02a98262012-11-14 12:40:26 -0800184 write("virtual ~" + mClassName + "();");
185 write("");
186
187
188 // Reflect export variable
189 slot = 0;
190 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
191 E = mRSContext->export_vars_end(); I != E; I++, slot++) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800192 genExportVariable(*I);
Stephen Hines02a98262012-11-14 12:40:26 -0800193 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700194
Stephen Hines02a98262012-11-14 12:40:26 -0800195 // Reflect export for each functions
196 for (RSContext::const_export_foreach_iterator
197 I = mRSContext->export_foreach_begin(),
198 E = mRSContext->export_foreach_end(); I != E; I++) {
199 const RSExportForEach *ef = *I;
200 if (ef->isDummyRoot()) {
201 write("// No forEach_root(...)");
202 continue;
203 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700204
Stephen Hines7dd6da22012-11-15 19:56:03 -0800205 ArgTy Args;
206 stringstream ss;
207 ss << "void forEach_" << ef->getName() << "(";
208
209 if (ef->hasIn()) {
210 Args.push_back(std::make_pair(
211 "android::sp<const android::RSC::Allocation>", "ain"));
Stephen Hines02a98262012-11-14 12:40:26 -0800212 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700213
Stephen Hines7dd6da22012-11-15 19:56:03 -0800214 if (ef->hasOut() || ef->hasReturn()) {
215 Args.push_back(std::make_pair(
216 "android::sp<const android::RSC::Allocation>", "aout"));
217 }
218
219 const RSExportRecordType *ERT = ef->getParamPacketType();
220 if (ERT) {
Stephen Hines02a98262012-11-14 12:40:26 -0800221 for (RSExportForEach::const_param_iterator i = ef->params_begin(),
222 e = ef->params_end(); i != e; i++) {
Jason Sams192392f2012-03-13 16:22:12 -0700223 RSReflectionTypeData rtd;
Stephen Hines02a98262012-11-14 12:40:26 -0800224 (*i)->getType()->convertToRTD(&rtd);
Stephen Hines7dd6da22012-11-15 19:56:03 -0800225 Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
Stephen Hines02a98262012-11-14 12:40:26 -0800226 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700227 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800228 makeArgs(ss, Args);
229 ss << ");";
230 write(ss);
Stephen Hines02a98262012-11-14 12:40:26 -0800231 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700232
233
Stephen Hines02a98262012-11-14 12:40:26 -0800234 // Reflect export function
235 for (RSContext::const_export_func_iterator
236 I = mRSContext->export_funcs_begin(),
237 E = mRSContext->export_funcs_end(); I != E; I++) {
238 const RSExportFunc *ef = *I;
Jason Sams1b6a0882012-03-12 15:07:58 -0700239
Stephen Hines02a98262012-11-14 12:40:26 -0800240 stringstream ss;
241 makeFunctionSignature(ss, false, ef);
242 write(ss);
243 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700244
Stephen Hines02a98262012-11-14 12:40:26 -0800245 decIndent();
246 write("};");
247 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700248}
249
250bool RSReflectionCpp::writeBC() {
Stephen Hines02a98262012-11-14 12:40:26 -0800251 FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
252 if (pfin == NULL) {
253 fprintf(stderr, "Error: could not read file %s\n",
254 mOutputBCFileName.c_str());
255 return false;
256 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700257
Stephen Hines02a98262012-11-14 12:40:26 -0800258 unsigned char buf[16];
259 int read_length;
260 write("static const unsigned char __txt[] = {");
261 incIndent();
262 while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
263 string s;
264 for (int i = 0; i < read_length; i++) {
265 char buf2[16];
266 snprintf(buf2, sizeof(buf2), "0x%02x,", buf[i]);
267 s += buf2;
Jason Sams1b6a0882012-03-12 15:07:58 -0700268 }
Stephen Hines02a98262012-11-14 12:40:26 -0800269 write(s);
270 }
271 decIndent();
272 write("};");
273 write("");
274 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700275}
276
277bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800278 startFile(mClassName + ".cpp");
Jason Sams1b6a0882012-03-12 15:07:58 -0700279
Stephen Hines02a98262012-11-14 12:40:26 -0800280 write("");
281 write("#include \"" + mClassName + ".h\"");
282 write("");
283
284 writeBC();
285
286 // Imports
287 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
288 //out() << "import " << Import[i] << ";" << std::endl;
289 //out() << std::endl;
290
291 write("\n");
292 stringstream ss;
Tim Murraydde98532013-07-23 15:55:19 -0700293 const std::string &packageName = mRSContext->getReflectJavaPackageName();
Stephen Hines02a98262012-11-14 12:40:26 -0800294 ss << mClassName << "::" << mClassName
Tim Murraydde98532013-07-23 15:55:19 -0700295 << "(android::sp<android::RSC::RS> rs):\n"
Stephen Hines7dd6da22012-11-15 19:56:03 -0800296 " ScriptC(rs, __txt, sizeof(__txt), \""
Stephen Hines02a98262012-11-14 12:40:26 -0800297 << mClassName << "\", " << mClassName.length()
Tim Murraydde98532013-07-23 15:55:19 -0700298 << ", \"/data/data/" << packageName << "/app\", sizeof(\"" << packageName << "\")) {";
Stephen Hines02a98262012-11-14 12:40:26 -0800299 write(ss);
300 incIndent();
301 //...
302 decIndent();
303 write("}");
304 write("");
305
306 write(mClassName + "::~" + mClassName + "() {");
307 write("}");
308 write("");
309
310 // Reflect export for each functions
311 uint32_t slot = 0;
312 for (RSContext::const_export_foreach_iterator
313 I = mRSContext->export_foreach_begin(),
314 E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
315 const RSExportForEach *ef = *I;
316 if (ef->isDummyRoot()) {
317 write("// No forEach_root(...)");
318 continue;
319 }
320
321 stringstream tmp;
Stephen Hines7dd6da22012-11-15 19:56:03 -0800322 ArgTy Args;
Stephen Hines02a98262012-11-14 12:40:26 -0800323 tmp << "void " << mClassName << "::forEach_" << ef->getName() << "(";
Stephen Hines7dd6da22012-11-15 19:56:03 -0800324
325 if (ef->hasIn()) {
326 Args.push_back(std::make_pair(
327 "android::sp<const android::RSC::Allocation>", "ain"));
Stephen Hines02a98262012-11-14 12:40:26 -0800328 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800329
330 if (ef->hasOut() || ef->hasReturn()) {
331 Args.push_back(std::make_pair(
332 "android::sp<const android::RSC::Allocation>", "aout"));
333 }
334
335 const RSExportRecordType *ERT = ef->getParamPacketType();
336 if (ERT) {
337 for (RSExportForEach::const_param_iterator i = ef->params_begin(),
338 e = ef->params_end(); i != e; i++) {
339 RSReflectionTypeData rtd;
340 (*i)->getType()->convertToRTD(&rtd);
341 Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
342 }
343 }
344 makeArgs(tmp, Args);
345
Stephen Hines713377e2012-11-14 19:32:43 -0800346 tmp << ") {";
Stephen Hines02a98262012-11-14 12:40:26 -0800347 write(tmp);
348 tmp.str("");
349
Stephen Hines7dd6da22012-11-15 19:56:03 -0800350 std::string FieldPackerName = ef->getName() + "_fp";
351 if (ERT) {
352 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
353 genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
354 }
Stephen Hines02a98262012-11-14 12:40:26 -0800355 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800356 tmp << " forEach(" << slot << ", ";
357
358 if (ef->hasIn()) {
359 tmp << "ain, ";
360 } else {
361 tmp << "NULL, ";
362 }
363
364 if (ef->hasOut() || ef->hasReturn()) {
365 tmp << "aout, ";
366 } else {
367 tmp << "NULL, ";
368 }
369
370 tmp << "NULL, 0);";
Stephen Hines02a98262012-11-14 12:40:26 -0800371 write(tmp);
372
373 write("}");
Jason Sams1b6a0882012-03-12 15:07:58 -0700374 write("");
Stephen Hines02a98262012-11-14 12:40:26 -0800375 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700376
Stephen Hines02a98262012-11-14 12:40:26 -0800377 slot = 0;
378 // Reflect export function
379 for (RSContext::const_export_func_iterator
380 I = mRSContext->export_funcs_begin(),
381 E = mRSContext->export_funcs_end(); I != E; I++) {
382 const RSExportFunc *ef = *I;
Jason Sams1b6a0882012-03-12 15:07:58 -0700383
Stephen Hines38dceea2012-11-13 17:33:55 -0800384 stringstream ss;
Stephen Hines02a98262012-11-14 12:40:26 -0800385 makeFunctionSignature(ss, true, ef);
Stephen Hines38dceea2012-11-13 17:33:55 -0800386 write(ss);
Stephen Hines02a98262012-11-14 12:40:26 -0800387 ss.str("");
Stephen Hines713377e2012-11-14 19:32:43 -0800388 const RSExportRecordType *params = ef->getParamPacketType();
389 size_t param_len = 0;
390 if (params) {
391 param_len = RSExportType::GetTypeAllocSize(params);
Stephen Hines7dd6da22012-11-15 19:56:03 -0800392 if (genCreateFieldPacker(params, "__fp")) {
393 genPackVarOfType(params, NULL, "__fp");
Stephen Hines713377e2012-11-14 19:32:43 -0800394 }
Stephen Hines713377e2012-11-14 19:32:43 -0800395 }
396
397 ss.str("");
398 ss << " invoke(" << slot;
399 if (params) {
400 ss << ", __fp.getData(), " << param_len << ");";
401 } else {
402 ss << ", NULL, 0);";
403 }
Stephen Hines02a98262012-11-14 12:40:26 -0800404 write(ss);
405
Jason Sams1b6a0882012-03-12 15:07:58 -0700406 write("}");
407 write("");
408
Stephen Hines02a98262012-11-14 12:40:26 -0800409 slot++;
410 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700411
Stephen Hines02a98262012-11-14 12:40:26 -0800412 decIndent();
413 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700414}
415
Stephen Hines7dd6da22012-11-15 19:56:03 -0800416void RSReflectionCpp::genExportVariable(const RSExportVar *EV) {
417 const RSExportType *ET = EV->getType();
418
419 switch (ET->getClass()) {
420 case RSExportType::ExportClassPrimitive: {
421 genPrimitiveTypeExportVariable(EV);
422 break;
423 }
424 case RSExportType::ExportClassPointer: {
425 genPointerTypeExportVariable(EV);
426 break;
427 }
428 case RSExportType::ExportClassVector: {
429 genVectorTypeExportVariable(EV);
430 break;
431 }
432 case RSExportType::ExportClassMatrix: {
433 genMatrixTypeExportVariable(EV);
434 break;
435 }
436 case RSExportType::ExportClassConstantArray: {
437 genConstantArrayTypeExportVariable(EV);
438 break;
439 }
440 case RSExportType::ExportClassRecord: {
441 genRecordTypeExportVariable(EV);
442 break;
443 }
444 default: {
445 slangAssert(false && "Unknown class of type");
446 }
447 }
448}
449
450
451void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
452 RSReflectionTypeData rtd;
453 EV->getType()->convertToRTD(&rtd);
454
455 if (!EV->isConst()) {
456 write(string("void set_") + EV->getName() + "(" + rtd.type->c_name +
457 " v) {");
458 stringstream tmp;
459 tmp << getNextExportVarSlot();
460 write(string(" setVar(") + tmp.str() + ", &v, sizeof(v));");
461 write(string(" __") + EV->getName() + " = v;");
462 write("}");
463 }
464 write(string(rtd.type->c_name) + " get_" + EV->getName() + "() const {");
465 if (EV->isConst()) {
466 const clang::APValue &val = EV->getInit();
467 bool isBool = !strcmp(rtd.type->c_name, "bool");
468 write(string(" return ") + genInitValue(val, isBool) + ";");
469 } else {
470 write(string(" return __") + EV->getName() + ";");
471 }
472 write("}");
473 write("");
474}
475
476void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
477 const RSExportType *ET = EV->getType();
478
479 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
480 "Variable should be type of pointer here");
481
482 std::string TypeName = GetTypeName(ET);
483 std::string VarName = EV->getName();
484
485 RSReflectionTypeData rtd;
486 EV->getType()->convertToRTD(&rtd);
487 uint32_t slot = getNextExportVarSlot();
488
489 if (!EV->isConst()) {
490 write(string("void bind_") + VarName + "(" + TypeName +
491 " v) {");
492 stringstream tmp;
493 tmp << slot;
494 write(string(" bindAllocation(v, ") + tmp.str() + ");");
495 write(string(" __") + VarName + " = v;");
496 write("}");
497 }
498 write(TypeName + " get_" + VarName + "() const {");
499 if (EV->isConst()) {
500 const clang::APValue &val = EV->getInit();
501 bool isBool = !strcmp(TypeName.c_str(), "bool");
502 write(string(" return ") + genInitValue(val, isBool) + ";");
503 } else {
504 write(string(" return __") + VarName + ";");
505 }
506 write("}");
507 write("");
508
509}
510
511void RSReflectionCpp::genVectorTypeExportVariable(const RSExportVar *EV) {
512 slangAssert(false);
513}
514
515void RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) {
516 slangAssert(false);
517}
518
519void RSReflectionCpp::genConstantArrayTypeExportVariable(
520 const RSExportVar *EV) {
521 slangAssert(false);
522}
523
524void RSReflectionCpp::genRecordTypeExportVariable(const RSExportVar *EV) {
525 slangAssert(false);
526}
527
Jason Sams1b6a0882012-03-12 15:07:58 -0700528
Stephen Hines38dceea2012-11-13 17:33:55 -0800529void RSReflectionCpp::makeFunctionSignature(
Stephen Hines02a98262012-11-14 12:40:26 -0800530 std::stringstream &ss,
531 bool isDefinition,
532 const RSExportFunc *ef) {
533 ss << "void ";
534 if (isDefinition) {
535 ss << mClassName << "::";
536 }
537 ss << "invoke_" << ef->getName() << "(";
Stephen Hines38dceea2012-11-13 17:33:55 -0800538
Stephen Hines02a98262012-11-14 12:40:26 -0800539 if (ef->getParamPacketType()) {
540 bool FirstArg = true;
541 for (RSExportFunc::const_param_iterator i = ef->params_begin(),
542 e = ef->params_end(); i != e; i++) {
543 RSReflectionTypeData rtd;
544 (*i)->getType()->convertToRTD(&rtd);
545 if (!FirstArg) {
546 ss << ", ";
547 } else {
548 FirstArg = false;
549 }
550 ss << rtd.type->c_name << " " << (*i)->getName();
Stephen Hines38dceea2012-11-13 17:33:55 -0800551 }
Stephen Hines02a98262012-11-14 12:40:26 -0800552 }
Stephen Hines38dceea2012-11-13 17:33:55 -0800553
Stephen Hines02a98262012-11-14 12:40:26 -0800554 if (isDefinition) {
555 ss << ") {";
556 } else {
557 ss << ");";
558 }
Stephen Hines38dceea2012-11-13 17:33:55 -0800559}
560
Stephen Hines7dd6da22012-11-15 19:56:03 -0800561void RSReflectionCpp::makeArgs(std::stringstream &ss, const ArgTy& Args) {
562 bool FirstArg = true;
563
564 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
565 if (!FirstArg) {
566 ss << ", ";
567 } else {
568 FirstArg = false;
569 }
570
571 ss << I->first << " " << I->second;
572 }
573}
574
575bool RSReflectionCpp::genCreateFieldPacker(const RSExportType *ET,
576 const char *FieldPackerName) {
577 size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
578
579 if (AllocSize > 0) {
580 std::stringstream ss;
581 ss << " FieldPacker " << FieldPackerName << "("
582 << AllocSize << ");";
583 write(ss);
584 return true;
585 }
586
587 return false;
588}
589
590void RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
591 const char *VarName,
592 const char *FieldPackerName) {
593 std::stringstream ss;
594 switch (ET->getClass()) {
595 case RSExportType::ExportClassPrimitive:
596 case RSExportType::ExportClassVector:
597 case RSExportType::ExportClassPointer:
598 case RSExportType::ExportClassMatrix: {
599 RSReflectionTypeData rtd;
600 ET->convertToRTD(&rtd);
601 ss << " " << FieldPackerName << ".add(" << VarName << ");";
602 write(ss);
603 break;
604 }
605 case RSExportType::ExportClassConstantArray: {
606 /*const RSExportConstantArrayType *ECAT =
607 static_cast<const RSExportConstantArrayType *>(ET);
608
609 // TODO(zonr): more elegant way. Currently, we obtain the unique index
610 // variable (this method involves recursive call which means
611 // we may have more than one level loop, therefore we can't
612 // always use the same index variable name here) name given
613 // in the for-loop from counting the '.' in @VarName.
614 unsigned Level = 0;
615 size_t LastDotPos = 0;
616 std::string ElementVarName(VarName);
617
618 while (LastDotPos != std::string::npos) {
619 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
620 Level++;
621 }
622 std::string IndexVarName("ct");
623 IndexVarName.append(llvm::utostr_32(Level));
624
625 C.indent() << "for (int " << IndexVarName << " = 0; " <<
626 IndexVarName << " < " << ECAT->getSize() << "; " <<
627 IndexVarName << "++)";
628 C.startBlock();
629
630 ElementVarName.append("[" + IndexVarName + "]");
631 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
632 FieldPackerName);
633
634 C.endBlock();*/
635 break;
636 }
637 case RSExportType::ExportClassRecord: {
638 const RSExportRecordType *ERT =
639 static_cast<const RSExportRecordType*>(ET);
640 // Relative pos from now on in field packer
641 unsigned Pos = 0;
642
643 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
644 E = ERT->fields_end();
645 I != E;
646 I++) {
647 const RSExportRecordType::Field *F = *I;
648 std::string FieldName;
649 size_t FieldOffset = F->getOffsetInParent();
650 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
651 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
652
653 if (VarName != NULL)
654 FieldName = VarName + ("." + F->getName());
655 else
656 FieldName = F->getName();
657
658 if (FieldOffset > Pos) {
659 ss.str("");
660 ss << " " << FieldPackerName << ".skip("
661 << (FieldOffset - Pos) << ");";
662 write(ss);
663 }
664
665 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
666
667 // There is padding in the field type
668 if (FieldAllocSize > FieldStoreSize) {
669 ss.str("");
670 ss << " " << FieldPackerName << ".skip("
671 << (FieldAllocSize - FieldStoreSize) << ");";
672 write(ss);
673 }
674
675 Pos = FieldOffset + FieldAllocSize;
676 }
677
678 // There maybe some padding after the struct
679 if (RSExportType::GetTypeAllocSize(ERT) > Pos) {
680 ss.str("");
681 ss << " " << FieldPackerName << ".skip("
682 << RSExportType::GetTypeAllocSize(ERT) - Pos << ");";
683 write(ss);
684 }
685 break;
686 }
687 default: {
688 slangAssert(false && "Unknown class of type");
689 }
690 }
691}
692
Stephen Hines02a98262012-11-14 12:40:26 -0800693} // namespace slang