blob: 6dfe1414c3a8eaa9bfd4314bac1de3640d1be27f [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 Murray140b9d42012-11-16 14:24:22 -0800183 write(mClassName + "(android::sp<android::RSC::RS> rs," +
Stephen Hines02a98262012-11-14 12:40:26 -0800184 " const char *cacheDir, size_t cacheDirLength);");
185 write("virtual ~" + mClassName + "();");
186 write("");
187
188
189 // Reflect export variable
190 slot = 0;
191 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
192 E = mRSContext->export_vars_end(); I != E; I++, slot++) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800193 genExportVariable(*I);
Stephen Hines02a98262012-11-14 12:40:26 -0800194 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700195
Stephen Hines02a98262012-11-14 12:40:26 -0800196 // Reflect export for each functions
197 for (RSContext::const_export_foreach_iterator
198 I = mRSContext->export_foreach_begin(),
199 E = mRSContext->export_foreach_end(); I != E; I++) {
200 const RSExportForEach *ef = *I;
201 if (ef->isDummyRoot()) {
202 write("// No forEach_root(...)");
203 continue;
204 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700205
Stephen Hines7dd6da22012-11-15 19:56:03 -0800206 ArgTy Args;
207 stringstream ss;
208 ss << "void forEach_" << ef->getName() << "(";
209
210 if (ef->hasIn()) {
211 Args.push_back(std::make_pair(
212 "android::sp<const android::RSC::Allocation>", "ain"));
Stephen Hines02a98262012-11-14 12:40:26 -0800213 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700214
Stephen Hines7dd6da22012-11-15 19:56:03 -0800215 if (ef->hasOut() || ef->hasReturn()) {
216 Args.push_back(std::make_pair(
217 "android::sp<const android::RSC::Allocation>", "aout"));
218 }
219
220 const RSExportRecordType *ERT = ef->getParamPacketType();
221 if (ERT) {
Stephen Hines02a98262012-11-14 12:40:26 -0800222 for (RSExportForEach::const_param_iterator i = ef->params_begin(),
223 e = ef->params_end(); i != e; i++) {
Jason Sams192392f2012-03-13 16:22:12 -0700224 RSReflectionTypeData rtd;
Stephen Hines02a98262012-11-14 12:40:26 -0800225 (*i)->getType()->convertToRTD(&rtd);
Stephen Hines7dd6da22012-11-15 19:56:03 -0800226 Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
Stephen Hines02a98262012-11-14 12:40:26 -0800227 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700228 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800229 makeArgs(ss, Args);
230 ss << ");";
231 write(ss);
Stephen Hines02a98262012-11-14 12:40:26 -0800232 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700233
234
Stephen Hines02a98262012-11-14 12:40:26 -0800235 // Reflect export function
236 for (RSContext::const_export_func_iterator
237 I = mRSContext->export_funcs_begin(),
238 E = mRSContext->export_funcs_end(); I != E; I++) {
239 const RSExportFunc *ef = *I;
Jason Sams1b6a0882012-03-12 15:07:58 -0700240
Stephen Hines02a98262012-11-14 12:40:26 -0800241 stringstream ss;
242 makeFunctionSignature(ss, false, ef);
243 write(ss);
244 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700245
Stephen Hines02a98262012-11-14 12:40:26 -0800246 decIndent();
247 write("};");
248 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700249}
250
251bool RSReflectionCpp::writeBC() {
Stephen Hines02a98262012-11-14 12:40:26 -0800252 FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
253 if (pfin == NULL) {
254 fprintf(stderr, "Error: could not read file %s\n",
255 mOutputBCFileName.c_str());
256 return false;
257 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700258
Stephen Hines02a98262012-11-14 12:40:26 -0800259 unsigned char buf[16];
260 int read_length;
261 write("static const unsigned char __txt[] = {");
262 incIndent();
263 while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
264 string s;
265 for (int i = 0; i < read_length; i++) {
266 char buf2[16];
267 snprintf(buf2, sizeof(buf2), "0x%02x,", buf[i]);
268 s += buf2;
Jason Sams1b6a0882012-03-12 15:07:58 -0700269 }
Stephen Hines02a98262012-11-14 12:40:26 -0800270 write(s);
271 }
272 decIndent();
273 write("};");
274 write("");
275 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700276}
277
278bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
Stephen Hines7dd6da22012-11-15 19:56:03 -0800279 startFile(mClassName + ".cpp");
Jason Sams1b6a0882012-03-12 15:07:58 -0700280
Stephen Hines02a98262012-11-14 12:40:26 -0800281 write("");
282 write("#include \"" + mClassName + ".h\"");
283 write("");
284
285 writeBC();
286
287 // Imports
288 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
289 //out() << "import " << Import[i] << ";" << std::endl;
290 //out() << std::endl;
291
292 write("\n");
293 stringstream ss;
294 ss << mClassName << "::" << mClassName
Stephen Hines7dd6da22012-11-15 19:56:03 -0800295 << "(android::sp<android::RSC::RS> rs, const char *cacheDir, "
296 "size_t cacheDirLength) :\n"
297 " ScriptC(rs, __txt, sizeof(__txt), \""
Stephen Hines02a98262012-11-14 12:40:26 -0800298 << mClassName << "\", " << mClassName.length()
299 << ", cacheDir, cacheDirLength) {";
300 write(ss);
301 incIndent();
302 //...
303 decIndent();
304 write("}");
305 write("");
306
307 write(mClassName + "::~" + mClassName + "() {");
308 write("}");
309 write("");
310
311 // Reflect export for each functions
312 uint32_t slot = 0;
313 for (RSContext::const_export_foreach_iterator
314 I = mRSContext->export_foreach_begin(),
315 E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
316 const RSExportForEach *ef = *I;
317 if (ef->isDummyRoot()) {
318 write("// No forEach_root(...)");
319 continue;
320 }
321
322 stringstream tmp;
Stephen Hines7dd6da22012-11-15 19:56:03 -0800323 ArgTy Args;
Stephen Hines02a98262012-11-14 12:40:26 -0800324 tmp << "void " << mClassName << "::forEach_" << ef->getName() << "(";
Stephen Hines7dd6da22012-11-15 19:56:03 -0800325
326 if (ef->hasIn()) {
327 Args.push_back(std::make_pair(
328 "android::sp<const android::RSC::Allocation>", "ain"));
Stephen Hines02a98262012-11-14 12:40:26 -0800329 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800330
331 if (ef->hasOut() || ef->hasReturn()) {
332 Args.push_back(std::make_pair(
333 "android::sp<const android::RSC::Allocation>", "aout"));
334 }
335
336 const RSExportRecordType *ERT = ef->getParamPacketType();
337 if (ERT) {
338 for (RSExportForEach::const_param_iterator i = ef->params_begin(),
339 e = ef->params_end(); i != e; i++) {
340 RSReflectionTypeData rtd;
341 (*i)->getType()->convertToRTD(&rtd);
342 Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
343 }
344 }
345 makeArgs(tmp, Args);
346
Stephen Hines713377e2012-11-14 19:32:43 -0800347 tmp << ") {";
Stephen Hines02a98262012-11-14 12:40:26 -0800348 write(tmp);
349 tmp.str("");
350
Stephen Hines7dd6da22012-11-15 19:56:03 -0800351 std::string FieldPackerName = ef->getName() + "_fp";
352 if (ERT) {
353 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
354 genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
355 }
Stephen Hines02a98262012-11-14 12:40:26 -0800356 }
Stephen Hines7dd6da22012-11-15 19:56:03 -0800357 tmp << " forEach(" << slot << ", ";
358
359 if (ef->hasIn()) {
360 tmp << "ain, ";
361 } else {
362 tmp << "NULL, ";
363 }
364
365 if (ef->hasOut() || ef->hasReturn()) {
366 tmp << "aout, ";
367 } else {
368 tmp << "NULL, ";
369 }
370
371 tmp << "NULL, 0);";
Stephen Hines02a98262012-11-14 12:40:26 -0800372 write(tmp);
373
374 write("}");
Jason Sams1b6a0882012-03-12 15:07:58 -0700375 write("");
Stephen Hines02a98262012-11-14 12:40:26 -0800376 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700377
Stephen Hines02a98262012-11-14 12:40:26 -0800378 slot = 0;
379 // Reflect export function
380 for (RSContext::const_export_func_iterator
381 I = mRSContext->export_funcs_begin(),
382 E = mRSContext->export_funcs_end(); I != E; I++) {
383 const RSExportFunc *ef = *I;
Jason Sams1b6a0882012-03-12 15:07:58 -0700384
Stephen Hines38dceea2012-11-13 17:33:55 -0800385 stringstream ss;
Stephen Hines02a98262012-11-14 12:40:26 -0800386 makeFunctionSignature(ss, true, ef);
Stephen Hines38dceea2012-11-13 17:33:55 -0800387 write(ss);
Stephen Hines02a98262012-11-14 12:40:26 -0800388 ss.str("");
Stephen Hines713377e2012-11-14 19:32:43 -0800389 const RSExportRecordType *params = ef->getParamPacketType();
390 size_t param_len = 0;
391 if (params) {
392 param_len = RSExportType::GetTypeAllocSize(params);
Stephen Hines7dd6da22012-11-15 19:56:03 -0800393 if (genCreateFieldPacker(params, "__fp")) {
394 genPackVarOfType(params, NULL, "__fp");
Stephen Hines713377e2012-11-14 19:32:43 -0800395 }
Stephen Hines713377e2012-11-14 19:32:43 -0800396 }
397
398 ss.str("");
399 ss << " invoke(" << slot;
400 if (params) {
401 ss << ", __fp.getData(), " << param_len << ");";
402 } else {
403 ss << ", NULL, 0);";
404 }
Stephen Hines02a98262012-11-14 12:40:26 -0800405 write(ss);
406
Jason Sams1b6a0882012-03-12 15:07:58 -0700407 write("}");
408 write("");
409
Stephen Hines02a98262012-11-14 12:40:26 -0800410 slot++;
411 }
Jason Sams1b6a0882012-03-12 15:07:58 -0700412
Stephen Hines02a98262012-11-14 12:40:26 -0800413 decIndent();
414 return true;
Jason Sams1b6a0882012-03-12 15:07:58 -0700415}
416
Stephen Hines7dd6da22012-11-15 19:56:03 -0800417void RSReflectionCpp::genExportVariable(const RSExportVar *EV) {
418 const RSExportType *ET = EV->getType();
419
420 switch (ET->getClass()) {
421 case RSExportType::ExportClassPrimitive: {
422 genPrimitiveTypeExportVariable(EV);
423 break;
424 }
425 case RSExportType::ExportClassPointer: {
426 genPointerTypeExportVariable(EV);
427 break;
428 }
429 case RSExportType::ExportClassVector: {
430 genVectorTypeExportVariable(EV);
431 break;
432 }
433 case RSExportType::ExportClassMatrix: {
434 genMatrixTypeExportVariable(EV);
435 break;
436 }
437 case RSExportType::ExportClassConstantArray: {
438 genConstantArrayTypeExportVariable(EV);
439 break;
440 }
441 case RSExportType::ExportClassRecord: {
442 genRecordTypeExportVariable(EV);
443 break;
444 }
445 default: {
446 slangAssert(false && "Unknown class of type");
447 }
448 }
449}
450
451
452void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
453 RSReflectionTypeData rtd;
454 EV->getType()->convertToRTD(&rtd);
455
456 if (!EV->isConst()) {
457 write(string("void set_") + EV->getName() + "(" + rtd.type->c_name +
458 " v) {");
459 stringstream tmp;
460 tmp << getNextExportVarSlot();
461 write(string(" setVar(") + tmp.str() + ", &v, sizeof(v));");
462 write(string(" __") + EV->getName() + " = v;");
463 write("}");
464 }
465 write(string(rtd.type->c_name) + " get_" + EV->getName() + "() const {");
466 if (EV->isConst()) {
467 const clang::APValue &val = EV->getInit();
468 bool isBool = !strcmp(rtd.type->c_name, "bool");
469 write(string(" return ") + genInitValue(val, isBool) + ";");
470 } else {
471 write(string(" return __") + EV->getName() + ";");
472 }
473 write("}");
474 write("");
475}
476
477void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
478 const RSExportType *ET = EV->getType();
479
480 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
481 "Variable should be type of pointer here");
482
483 std::string TypeName = GetTypeName(ET);
484 std::string VarName = EV->getName();
485
486 RSReflectionTypeData rtd;
487 EV->getType()->convertToRTD(&rtd);
488 uint32_t slot = getNextExportVarSlot();
489
490 if (!EV->isConst()) {
491 write(string("void bind_") + VarName + "(" + TypeName +
492 " v) {");
493 stringstream tmp;
494 tmp << slot;
495 write(string(" bindAllocation(v, ") + tmp.str() + ");");
496 write(string(" __") + VarName + " = v;");
497 write("}");
498 }
499 write(TypeName + " get_" + VarName + "() const {");
500 if (EV->isConst()) {
501 const clang::APValue &val = EV->getInit();
502 bool isBool = !strcmp(TypeName.c_str(), "bool");
503 write(string(" return ") + genInitValue(val, isBool) + ";");
504 } else {
505 write(string(" return __") + VarName + ";");
506 }
507 write("}");
508 write("");
509
510}
511
512void RSReflectionCpp::genVectorTypeExportVariable(const RSExportVar *EV) {
513 slangAssert(false);
514}
515
516void RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) {
517 slangAssert(false);
518}
519
520void RSReflectionCpp::genConstantArrayTypeExportVariable(
521 const RSExportVar *EV) {
522 slangAssert(false);
523}
524
525void RSReflectionCpp::genRecordTypeExportVariable(const RSExportVar *EV) {
526 slangAssert(false);
527}
528
Jason Sams1b6a0882012-03-12 15:07:58 -0700529
Stephen Hines38dceea2012-11-13 17:33:55 -0800530void RSReflectionCpp::makeFunctionSignature(
Stephen Hines02a98262012-11-14 12:40:26 -0800531 std::stringstream &ss,
532 bool isDefinition,
533 const RSExportFunc *ef) {
534 ss << "void ";
535 if (isDefinition) {
536 ss << mClassName << "::";
537 }
538 ss << "invoke_" << ef->getName() << "(";
Stephen Hines38dceea2012-11-13 17:33:55 -0800539
Stephen Hines02a98262012-11-14 12:40:26 -0800540 if (ef->getParamPacketType()) {
541 bool FirstArg = true;
542 for (RSExportFunc::const_param_iterator i = ef->params_begin(),
543 e = ef->params_end(); i != e; i++) {
544 RSReflectionTypeData rtd;
545 (*i)->getType()->convertToRTD(&rtd);
546 if (!FirstArg) {
547 ss << ", ";
548 } else {
549 FirstArg = false;
550 }
551 ss << rtd.type->c_name << " " << (*i)->getName();
Stephen Hines38dceea2012-11-13 17:33:55 -0800552 }
Stephen Hines02a98262012-11-14 12:40:26 -0800553 }
Stephen Hines38dceea2012-11-13 17:33:55 -0800554
Stephen Hines02a98262012-11-14 12:40:26 -0800555 if (isDefinition) {
556 ss << ") {";
557 } else {
558 ss << ");";
559 }
Stephen Hines38dceea2012-11-13 17:33:55 -0800560}
561
Stephen Hines7dd6da22012-11-15 19:56:03 -0800562void RSReflectionCpp::makeArgs(std::stringstream &ss, const ArgTy& Args) {
563 bool FirstArg = true;
564
565 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) {
566 if (!FirstArg) {
567 ss << ", ";
568 } else {
569 FirstArg = false;
570 }
571
572 ss << I->first << " " << I->second;
573 }
574}
575
576bool RSReflectionCpp::genCreateFieldPacker(const RSExportType *ET,
577 const char *FieldPackerName) {
578 size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
579
580 if (AllocSize > 0) {
581 std::stringstream ss;
582 ss << " FieldPacker " << FieldPackerName << "("
583 << AllocSize << ");";
584 write(ss);
585 return true;
586 }
587
588 return false;
589}
590
591void RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
592 const char *VarName,
593 const char *FieldPackerName) {
594 std::stringstream ss;
595 switch (ET->getClass()) {
596 case RSExportType::ExportClassPrimitive:
597 case RSExportType::ExportClassVector:
598 case RSExportType::ExportClassPointer:
599 case RSExportType::ExportClassMatrix: {
600 RSReflectionTypeData rtd;
601 ET->convertToRTD(&rtd);
602 ss << " " << FieldPackerName << ".add(" << VarName << ");";
603 write(ss);
604 break;
605 }
606 case RSExportType::ExportClassConstantArray: {
607 /*const RSExportConstantArrayType *ECAT =
608 static_cast<const RSExportConstantArrayType *>(ET);
609
610 // TODO(zonr): more elegant way. Currently, we obtain the unique index
611 // variable (this method involves recursive call which means
612 // we may have more than one level loop, therefore we can't
613 // always use the same index variable name here) name given
614 // in the for-loop from counting the '.' in @VarName.
615 unsigned Level = 0;
616 size_t LastDotPos = 0;
617 std::string ElementVarName(VarName);
618
619 while (LastDotPos != std::string::npos) {
620 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
621 Level++;
622 }
623 std::string IndexVarName("ct");
624 IndexVarName.append(llvm::utostr_32(Level));
625
626 C.indent() << "for (int " << IndexVarName << " = 0; " <<
627 IndexVarName << " < " << ECAT->getSize() << "; " <<
628 IndexVarName << "++)";
629 C.startBlock();
630
631 ElementVarName.append("[" + IndexVarName + "]");
632 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
633 FieldPackerName);
634
635 C.endBlock();*/
636 break;
637 }
638 case RSExportType::ExportClassRecord: {
639 const RSExportRecordType *ERT =
640 static_cast<const RSExportRecordType*>(ET);
641 // Relative pos from now on in field packer
642 unsigned Pos = 0;
643
644 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
645 E = ERT->fields_end();
646 I != E;
647 I++) {
648 const RSExportRecordType::Field *F = *I;
649 std::string FieldName;
650 size_t FieldOffset = F->getOffsetInParent();
651 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
652 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
653
654 if (VarName != NULL)
655 FieldName = VarName + ("." + F->getName());
656 else
657 FieldName = F->getName();
658
659 if (FieldOffset > Pos) {
660 ss.str("");
661 ss << " " << FieldPackerName << ".skip("
662 << (FieldOffset - Pos) << ");";
663 write(ss);
664 }
665
666 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
667
668 // There is padding in the field type
669 if (FieldAllocSize > FieldStoreSize) {
670 ss.str("");
671 ss << " " << FieldPackerName << ".skip("
672 << (FieldAllocSize - FieldStoreSize) << ");";
673 write(ss);
674 }
675
676 Pos = FieldOffset + FieldAllocSize;
677 }
678
679 // There maybe some padding after the struct
680 if (RSExportType::GetTypeAllocSize(ERT) > Pos) {
681 ss.str("");
682 ss << " " << FieldPackerName << ".skip("
683 << RSExportType::GetTypeAllocSize(ERT) - Pos << ");";
684 write(ss);
685 }
686 break;
687 }
688 default: {
689 slangAssert(false && "Unknown class of type");
690 }
691 }
692}
693
Stephen Hines02a98262012-11-14 12:40:26 -0800694} // namespace slang