11b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/*
2ee9d7b0e0cb74a592cef718d72b589b64997bd21Tim Murray * Copyright 2013, The Android Open Source Project
31b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams *
41b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
51b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * you may not use this file except in compliance with the License.
61b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * You may obtain a copy of the License at
71b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams *
81b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams *     http://www.apache.org/licenses/LICENSE-2.0
91b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams *
101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Unless required by applicable law or agreed to in writing, software
111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * See the License for the specific language governing permissions and
141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * limitations under the License.
151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams */
161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sys/stat.h>
181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <stdio.h>
191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <stdlib.h>
201f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet#include <iostream>
211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <cstdarg>
231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <cctype>
241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <algorithm>
261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sstream>
271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <string>
281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <utility>
291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "os_sep.h"
311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_context.h"
321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_var.h"
331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_foreach.h"
341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_func.h"
351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflect_utils.h"
361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_version.h"
371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_utils.h"
381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflection_cpp.h"
401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsusing namespace std;
421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
431b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsnamespace slang {
441b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_ITEM_CLASS_NAME "Item"
467dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
47003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines#define RS_ELEM_PREFIX "__rs_elem_"
48003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
497dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesstatic const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
507dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  static const char *MatrixTypeCNameMap[] = {
512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      "rs_matrix2x2", "rs_matrix3x3", "rs_matrix4x4",
527dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  };
537dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  unsigned Dim = EMT->getDim();
547dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if ((Dim - 2) < (sizeof(MatrixTypeCNameMap) / sizeof(const char *)))
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return MatrixTypeCNameMap[EMT->getDim() - 2];
577dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
587dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
597dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  return NULL;
607dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
617dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
627dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesstatic std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
637dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  switch (ET->getClass()) {
642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->isRSObjectType()) {
682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return std::string("android::RSC::sp<const android::RSC::") +
692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet             RSExportPrimitiveType::getRSReflectionType(EPT)->c_name + ">";
702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return RSExportPrimitiveType::getRSReflectionType(EPT)->c_name;
727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportType *PointeeType =
762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET)->getPointeeType();
777dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (PointeeType->getClass() != RSExportType::ExportClassRecord)
792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return "android::RSC::sp<android::RSC::Allocation>";
802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    else
812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      return PointeeType->getElementName();
822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::stringstream VecName;
862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    VecName << EVT->getRSReflectionType(EVT)->rs_c_vector_prefix
872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            << EVT->getNumElement();
882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return VecName.str();
892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return GetMatrixTypeName(static_cast<const RSExportMatrixType *>(ET));
922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO: Fix this for C arrays!
952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportConstantArrayType *CAT =
962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(ET);
972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ElementTypeName = GetTypeName(CAT->getElementType());
982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (Brackets) {
992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ElementTypeName.append("[]");
1007dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
1012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return ElementTypeName;
1022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
1042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO: Fix for C structs!
1052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME;
1062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
1087dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
1097dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
1107dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  return "";
1117dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
1127dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
11359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc BrouilletRSReflectionCpp::RSReflectionCpp(const RSContext *Context,
11459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                 const string &OutputDirectory,
11559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                 const string &RSSourceFileName,
11659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                                 const string &BitCodeFileName)
11759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    : mRSContext(Context), mRSSourceFilePath(RSSourceFileName),
11859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mBitCodeFilePath(BitCodeFileName), mOutputDirectory(OutputDirectory),
11959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet      mNextExportVarSlot(0), mNextExportFuncSlot(0), mNextExportForEachSlot(0) {
120efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  mCleanedRSFileName = RootNameFromRSFileName(mRSSourceFilePath);
121efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  mClassName = "ScriptC_" + mCleanedRSFileName;
12259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet}
1231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
12459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc BrouilletRSReflectionCpp::~RSReflectionCpp() {}
125476d4f5a0249a3318cb86460e6a1adb2b40ecd6fStephen Hines
12659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouilletbool RSReflectionCpp::reflect() {
127eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  writeHeaderFile();
128eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  writeImplementationFile();
1291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
13002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  return true;
1311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
1341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
135eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouilletbool RSReflectionCpp::writeHeaderFile() {
1361f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  // Create the file and write the license note.
137efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  if (!mOut.startFile(mOutputDirectory, mClassName + ".h", mRSSourceFilePath,
138fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getLicenseNote(), false,
139fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getVerbose())) {
1401f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    return false;
1411f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  }
14202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
1431f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "#include \"RenderScript.h\"\n\n";
1441f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "using namespace android::RSC;\n\n";
14502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
146f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  mOut.comment("This class encapsulates access to the exported elements of the script.  "
147f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "Typically, you would instantiate this class once, call the set_* methods "
148f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "for each of the exported global variables you want to change, then call "
149f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "one of the forEach_ methods to invoke a kernel.");
150f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  mOut.indent() << "class " << mClassName << " : public android::RSC::ScriptC";
1511cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.startBlock();
1521f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet
1531cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.decreaseIndent();
1541f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "private:\n";
1551f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.increaseIndent();
15602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
1571cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genFieldsToStoreExportVariableValues();
1581cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genTypeInstancesUsedInForEach();
1591cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genFieldsForAllocationTypeVerification();
1601cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
1611cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.decreaseIndent();
1621cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.indent() << "public:\n";
1631cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.increaseIndent();
1641cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
1651cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  // Generate the constructor and destructor declarations.
1661cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.indent() << mClassName << "(android::RSC::sp<android::RSC::RS> rs);\n";
1671cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.indent() << "virtual ~" << mClassName << "();\n\n";
1681cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
1691cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genExportVariablesGetterAndSetter();
1701cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genForEachDeclarations();
1711cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  genExportFunctionDeclarations();
17280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
1731cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.endBlock(true);
1741cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  mOut.closeFile();
1751cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  return true;
1761cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet}
1771cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
1781cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genTypeInstancesUsedInForEach() {
179003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  for (RSContext::const_export_foreach_iterator
180003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines           I = mRSContext->export_foreach_begin(),
1812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           E = mRSContext->export_foreach_end();
1822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
183003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    const RSExportForEach *EF = *I;
184003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    const RSExportType *OET = EF->getOutType();
185c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
186003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    if (OET) {
187003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines      genTypeInstanceFromPointer(OET);
188003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    }
189c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
190c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    const RSExportForEach::InTypeVec &InTypes = EF->getInTypes();
191c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
192c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InTypeIter BI = InTypes.begin(),
193c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         EI = InTypes.end(); BI != EI; BI++) {
194c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
195c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      genTypeInstanceFromPointer(*BI);
196c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
197003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
1981cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet}
199003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
2001cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genFieldsForAllocationTypeVerification() {
201f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  bool CommentAdded = false;
202003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
203003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines                                       E = mTypesToCheck.end();
2042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
205f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (!CommentAdded) {
206f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      mOut.comment("The following elements are used to verify the types of "
207f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "allocations passed to kernels.");
208f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      CommentAdded = true;
209f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
2101f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "android::RSC::sp<const android::RSC::Element> "
2111f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << RS_ELEM_PREFIX << *I << ";\n";
212003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
2131cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet}
214003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
2151cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genFieldsToStoreExportVariableValues() {
216f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  bool CommentAdded = false;
21702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
2182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            E = mRSContext->export_vars_end();
2191cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet       I != E; I++) {
2201cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    const RSExportVar *ev = *I;
221f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (ev->isConst()) {
222f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      continue;
223f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
224f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (!CommentAdded) {
225f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      mOut.comment("For each non-const variable exported by the script, we "
226f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "have an equivalent field.  This field contains the last "
227f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "value this variable was set to using the set_ method.  "
228f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "This may not be current value of the variable in the "
229f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "script, as the script is free to modify its internal "
230f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "variable without changing this field.  If the script "
231f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "initializes the exported variable, the constructor will "
232f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "initialize this field to the same value.");
233f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      CommentAdded = true;
2341cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
235f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    mOut.indent() << GetTypeName(ev->getType()) << " " RS_EXPORT_VAR_PREFIX
236f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                  << ev->getName() << ";\n";
23702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
2381cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet}
23902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
2401cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genForEachDeclarations() {
241f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  bool CommentAdded = false;
24202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  for (RSContext::const_export_foreach_iterator
24302a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines           I = mRSContext->export_foreach_begin(),
2442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           E = mRSContext->export_foreach_end();
2452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
246eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    const RSExportForEach *ForEach = *I;
2471cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
248eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    if (ForEach->isDummyRoot()) {
2491f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut.indent() << "// No forEach_root(...)\n";
25002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      continue;
25102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    }
2521b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
253f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (!CommentAdded) {
254f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      mOut.comment("For each kernel of the script corresponds one method.  "
255f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "That method queues the kernel for execution.  The kernel "
256f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "may not have completed nor even started by the time this "
257f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "function returns.  Calls that extract the data out of the "
258f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet                   "output allocation will wait for the kernels to complete.");
259f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      CommentAdded = true;
260f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
261f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet
262eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    std::string FunctionStart = "void forEach_" + ForEach->getName() + "(";
2631f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << FunctionStart;
2647dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
265eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    ArgumentList Arguments;
266c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    const RSExportForEach::InVec &Ins = ForEach->getIns();
267c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    for (RSExportForEach::InIter BI = Ins.begin(), EI = Ins.end();
268c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes         BI != EI; BI++) {
269c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
270eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet      Arguments.push_back(std::make_pair(
271c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        "android::RSC::sp<const android::RSC::Allocation>", (*BI)->getName()));
2727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
2737dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
274eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    if (ForEach->hasOut() || ForEach->hasReturn()) {
275eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet      Arguments.push_back(std::make_pair(
276ee9d7b0e0cb74a592cef718d72b589b64997bd21Tim Murray          "android::RSC::sp<const android::RSC::Allocation>", "aout"));
2771b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
2781b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
279eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    const RSExportRecordType *ERT = ForEach->getParamPacketType();
2807dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (ERT) {
281eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet      for (RSExportForEach::const_param_iterator i = ForEach->params_begin(),
282eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet                                                 e = ForEach->params_end();
2832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           i != e; i++) {
28402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines        RSReflectionTypeData rtd;
28502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines        (*i)->getType()->convertToRTD(&rtd);
286eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet        Arguments.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
28702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      }
2881b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
289eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    genArguments(Arguments, FunctionStart.length());
2901f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ");\n";
29102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
2921cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet}
2931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
2941cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genExportFunctionDeclarations() {
29502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  for (RSContext::const_export_func_iterator
2962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           I = mRSContext->export_funcs_begin(),
2972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           E = mRSContext->export_funcs_end();
2982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
29902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    const RSExportFunc *ef = *I;
30038dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines
3011f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    makeFunctionSignature(false, ef);
30202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
3031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
3041b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
305eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouilletbool RSReflectionCpp::genEncodedBitCode() {
306efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  FILE *pfin = fopen(mBitCodeFilePath.c_str(), "rb");
30702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  if (pfin == NULL) {
30802a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    fprintf(stderr, "Error: could not read file %s\n",
309efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet            mBitCodeFilePath.c_str());
31002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    return false;
31102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
31202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
31302a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  unsigned char buf[16];
31402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  int read_length;
3151f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "static const unsigned char __txt[] =";
3161f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
31702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
3181f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent();
31902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    for (int i = 0; i < read_length; i++) {
32002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      char buf2[16];
32102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      snprintf(buf2, sizeof(buf2), "0x%02x,", buf[i]);
3221f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << buf2;
3231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
3241f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << "\n";
32502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
3261f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock(true);
3271f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut << "\n";
32802a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  return true;
3291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
3301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
331eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouilletbool RSReflectionCpp::writeImplementationFile() {
332efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  if (!mOut.startFile(mOutputDirectory, mClassName + ".cpp", mRSSourceFilePath,
333fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getLicenseNote(), false,
334fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                      mRSContext->getVerbose())) {
3351f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    return false;
3361f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  }
33702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
3381f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "#include \"" << mClassName << ".h\"\n\n";
33902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
340eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  genEncodedBitCode();
3411f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "\n\n";
34202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
343dde98533fad4c6534af537ae583aa4db35a1c699Tim Murray  const std::string &packageName = mRSContext->getReflectJavaPackageName();
3441f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << mClassName << "::" << mClassName
3451f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                << "(android::RSC::sp<android::RSC::RS> rs):\n"
3461f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                   "        ScriptC(rs, __txt, sizeof(__txt), \""
347efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                << mCleanedRSFileName << "\", " << mCleanedRSFileName.length()
348efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                << ", \"/data/data/" << packageName << "/app\", sizeof(\""
349efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                << packageName << "\"))";
3501f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
351003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
352003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines                                       E = mTypesToCheck.end();
3532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
3541f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << RS_ELEM_PREFIX << *I << " = android::RSC::Element::" << *I
3551f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << "(mRS);\n";
356003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
35780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
35880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
35980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                            E = mRSContext->export_vars_end();
3602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
36180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    const RSExportVar *EV = *I;
36280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    if (!EV->getInit().isUninit()) {
36380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
36480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    } else {
36580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      genZeroInitExportVariable(EV->getName());
36680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    }
36780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  }
3681f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock();
36902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
3701f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << mClassName << "::~" << mClassName << "()";
3711f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
3721f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock();
37302a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
37402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  // Reflect export for each functions
37502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  uint32_t slot = 0;
37602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  for (RSContext::const_export_foreach_iterator
3772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           I = mRSContext->export_foreach_begin(),
3782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           E = mRSContext->export_foreach_end();
3792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++, slot++) {
38002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    const RSExportForEach *ef = *I;
38102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    if (ef->isDummyRoot()) {
3821f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut.indent() << "// No forEach_root(...)\n";
38302a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      continue;
38402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    }
3851b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
386eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    ArgumentList Arguments;
3871f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    std::string FunctionStart =
3881f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet        "void " + mClassName + "::forEach_" + ef->getName() + "(";
3891f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << FunctionStart;
3907dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
391c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (ef->hasIns()) {
392c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      // FIXME: Add support for kernels with multiple inputs.
393c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      assert(ef->getIns().size() == 1);
394eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet      Arguments.push_back(std::make_pair(
395ee9d7b0e0cb74a592cef718d72b589b64997bd21Tim Murray          "android::RSC::sp<const android::RSC::Allocation>", "ain"));
3967dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
3977dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
3987dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (ef->hasOut() || ef->hasReturn()) {
399eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet      Arguments.push_back(std::make_pair(
400ee9d7b0e0cb74a592cef718d72b589b64997bd21Tim Murray          "android::RSC::sp<const android::RSC::Allocation>", "aout"));
4017dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
4027dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
4037dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    const RSExportRecordType *ERT = ef->getParamPacketType();
4047dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (ERT) {
4057dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      for (RSExportForEach::const_param_iterator i = ef->params_begin(),
4062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                 e = ef->params_end();
4072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           i != e; i++) {
4087dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines        RSReflectionTypeData rtd;
4097dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines        (*i)->getType()->convertToRTD(&rtd);
410eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet        Arguments.push_back(std::make_pair(rtd.type->c_name, (*i)->getName()));
4117dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      }
41202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    }
413eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet    genArguments(Arguments, FunctionStart.length());
4141f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ")";
4151f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
41602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
417003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    const RSExportType *OET = ef->getOutType();
418c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    const RSExportForEach::InTypeVec &InTypes = ef->getInTypes();
419c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (ef->hasIns()) {
420c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      // FIXME: Add support for kernels with multiple inputs.
421c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      assert(ef->getIns().size() == 1);
422c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      genTypeCheck(InTypes[0], "ain");
423003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    }
424003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    if (OET) {
425003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines      genTypeCheck(OET, "aout");
426003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    }
427003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
428efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    // TODO Add the appropriate dimension checking code, as seen in
429efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    // slang_rs_reflection.cpp.
430efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
4317dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    std::string FieldPackerName = ef->getName() + "_fp";
4327dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (ERT) {
4337dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
4347dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines        genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
4357dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      }
4367dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
4371f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "forEach(" << slot << ", ";
4387dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
439c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (ef->hasIns()) {
440c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      // FIXME: Add support for kernels with multiple inputs.
441c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      assert(ef->getIns().size() == 1);
4421f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "ain, ";
44302a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    } else {
4441f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "NULL, ";
44502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    }
4467dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
4477dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (ef->hasOut() || ef->hasReturn()) {
4481f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "aout, ";
4497dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    } else {
4501f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "NULL, ";
4517dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
4527dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
453003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    // FIXME (no support for usrData with C++ kernels)
4541f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << "NULL, 0);\n";
4551f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
45602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
4571b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
45802a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  slot = 0;
45902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  // Reflect export function
46002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  for (RSContext::const_export_func_iterator
4612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           I = mRSContext->export_funcs_begin(),
4622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet           E = mRSContext->export_funcs_end();
4632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet       I != E; I++) {
46402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    const RSExportFunc *ef = *I;
4651b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
4661f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    makeFunctionSignature(true, ef);
4671f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
468713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    const RSExportRecordType *params = ef->getParamPacketType();
469713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    size_t param_len = 0;
470713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    if (params) {
471c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet      param_len = params->getAllocSize();
4727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      if (genCreateFieldPacker(params, "__fp")) {
4737dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines        genPackVarOfType(params, NULL, "__fp");
474713377ec412f448273158c954f6816f07f8bcd20Stephen Hines      }
475713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    }
476713377ec412f448273158c954f6816f07f8bcd20Stephen Hines
4771f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "invoke(" << slot;
478713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    if (params) {
4791f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << ", __fp.getData(), " << param_len << ");\n";
480713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    } else {
4811f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << ", NULL, 0);\n";
482713377ec412f448273158c954f6816f07f8bcd20Stephen Hines    }
4831f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
4841b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
48502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    slot++;
48602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
48738dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines
4881f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.closeFile();
48902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  return true;
4901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
4911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
4921cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genExportVariablesGetterAndSetter() {
493f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  mOut.comment("Methods to set and get the variables exported by the script. "
494f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "Const variables will not have a setter.\n\n"
495f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "Note that the value returned by the getter may not be the "
496f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "current value of the variable in the script.  The getter will "
497f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "return the initial value of the variable (as defined in the "
498f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "script) or the the last value set by using the setter method.  "
499f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet               "The script is free to modify its value independently.");
5001cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
5011cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                                            E = mRSContext->export_vars_end();
5021cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet       I != E; I++) {
5031cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    const RSExportVar *EV = *I;
5041cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    const RSExportType *ET = EV->getType();
5057dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5061cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    switch (ET->getClass()) {
5071cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassPrimitive: {
5081cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genGetterAndSetter(static_cast<const RSExportPrimitiveType *>(ET), EV);
5091cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5101cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5111cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassPointer: {
5121cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      // TODO Deprecate this.
5131cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genPointerTypeExportVariable(EV);
5141cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5151cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5161cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassVector: {
5171cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genGetterAndSetter(static_cast<const RSExportVectorType *>(ET), EV);
5181cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5191cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5201cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassMatrix: {
5211cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genMatrixTypeExportVariable(EV);
5221cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5231cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5241cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassConstantArray: {
5251cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genGetterAndSetter(static_cast<const RSExportConstantArrayType *>(ET),
5261cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                         EV);
5271cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5281cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5291cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    case RSExportType::ExportClassRecord: {
5301cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      genGetterAndSetter(static_cast<const RSExportRecordType *>(ET), EV);
5311cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet      break;
5321cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5331cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    default: { slangAssert(false && "Unknown class of type"); }
5341cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet    }
5357dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
5367dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
5377dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5381cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genGetterAndSetter(const RSExportPrimitiveType *EPT,
5391cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                                         const RSExportVar *EV) {
5407dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  RSReflectionTypeData rtd;
541d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines  EPT->convertToRTD(&rtd);
542d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines  std::string TypeName = GetTypeName(EPT, false);
5437dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5447dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  if (!EV->isConst()) {
5451f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "void set_" << EV->getName() << "(" << TypeName << " v)";
5461f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
5471f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "setVar(" << getNextExportVarSlot() << ", ";
548d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines    if (EPT->isRSObjectType()) {
5491f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "v";
550d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines    } else {
5511f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << "&v, sizeof(v)";
552d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines    }
5531f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ");\n";
5541f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;\n";
5551f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
5567dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
5571f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << TypeName << " get_" << EV->getName() << "() const";
5581f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
5597dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  if (EV->isConst()) {
5607dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    const clang::APValue &val = EV->getInit();
561d6f36b1347b487192103c9a17d5e9a1abcab534dStephen Hines    bool isBool = !strcmp(TypeName.c_str(), "bool");
5621f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return ";
5631f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    genInitValue(val, isBool);
5641f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ";\n";
5657dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  } else {
5661f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << EV->getName()
5671f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << ";\n";
5687dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
5691f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock();
5707dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
5717dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesvoid RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
5737dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  const RSExportType *ET = EV->getType();
5747dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5757dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  slangAssert((ET->getClass() == RSExportType::ExportClassPointer) &&
5767dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines              "Variable should be type of pointer here");
5777dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5787dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  std::string TypeName = GetTypeName(ET);
5797dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  std::string VarName = EV->getName();
5807dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5817dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  RSReflectionTypeData rtd;
5827dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  EV->getType()->convertToRTD(&rtd);
5837dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  uint32_t slot = getNextExportVarSlot();
5847dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
5857dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  if (!EV->isConst()) {
5861f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "void bind_" << VarName << "(" << TypeName << " v)";
5871f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
5881f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "bindAllocation(v, " << slot << ");\n";
5891f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = v;\n";
5901f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
5911f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  }
5921f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << TypeName << " get_" << VarName << "() const";
5931f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
5947dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  if (EV->isConst()) {
5957dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    const clang::APValue &val = EV->getInit();
5967dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    bool isBool = !strcmp(TypeName.c_str(), "bool");
5971f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return ";
5981f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    genInitValue(val, isBool);
5991f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ";\n";
6007dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  } else {
6011f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << VarName << ";\n";
6027dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
6031f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock();
6047dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6057dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6061cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genGetterAndSetter(const RSExportVectorType *EVT,
6071cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                                         const RSExportVar *EV) {
60880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  slangAssert(EVT != NULL);
60980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
61080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  RSReflectionTypeData rtd;
61180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  EVT->convertToRTD(&rtd);
61280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
61380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  if (!EV->isConst()) {
6141f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "void set_" << EV->getName() << "("
6151f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << rtd.type->rs_c_vector_prefix << EVT->getNumElement()
6161f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << " v)";
6171f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
6181f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "setVar(" << getNextExportVarSlot()
6191f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << ", &v, sizeof(v));\n";
6201f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;\n";
6211f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
6221f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  }
6231f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << rtd.type->rs_c_vector_prefix << EVT->getNumElement()
6241f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                << " get_" << EV->getName() << "() const";
6251f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.startBlock();
62680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  if (EV->isConst()) {
62780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    const clang::APValue &val = EV->getInit();
6281f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return ";
6291f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    genInitValue(val, false);
6301f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ";\n";
63180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  } else {
6321f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return " << RS_EXPORT_VAR_PREFIX << EV->getName()
6331f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << ";\n";
63480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  }
6351f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.endBlock();
6367dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6377dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6387dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesvoid RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) {
6397dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  slangAssert(false);
6407dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6417dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6421cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genGetterAndSetter(const RSExportConstantArrayType *AT,
6431cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                                         const RSExportVar *EV) {
6447dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  slangAssert(false);
6457dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6467dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6471cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouilletvoid RSReflectionCpp::genGetterAndSetter(const RSExportRecordType *ERT,
6481cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet                                         const RSExportVar *EV) {
6497dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  slangAssert(false);
6507dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6517dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6521f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouilletvoid RSReflectionCpp::makeFunctionSignature(bool isDefinition,
6532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            const RSExportFunc *ef) {
6541f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "void ";
65502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  if (isDefinition) {
6561f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << mClassName << "::";
65702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
6581f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut << "invoke_" << ef->getName() << "(";
65902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines
66002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  if (ef->getParamPacketType()) {
66102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    bool FirstArg = true;
66202a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines    for (RSExportFunc::const_param_iterator i = ef->params_begin(),
6632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                            e = ef->params_end();
6642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         i != e; i++) {
66502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      RSReflectionTypeData rtd;
66602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      (*i)->getType()->convertToRTD(&rtd);
66702a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      if (!FirstArg) {
6681f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet        mOut << ", ";
66902a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      } else {
67002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines        FirstArg = false;
67102a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines      }
6721f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << rtd.type->c_name << " " << (*i)->getName();
67338dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines    }
67402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
67538dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines
67602a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  if (isDefinition) {
6771f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ")";
67802a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  } else {
6791f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << ");\n";
68002a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  }
68138dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines}
68238dceea4b8e90f326c90252d3c2762914d3ee6a5Stephen Hines
683eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouilletvoid RSReflectionCpp::genArguments(const ArgumentList &Arguments, int Offset) {
6847dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  bool FirstArg = true;
6857dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
686eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  for (ArgumentList::const_iterator I = Arguments.begin(), E = Arguments.end();
687eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet       I != E; I++) {
6887dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    if (!FirstArg) {
6891f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut << ",\n";
6901f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut.indent() << string(Offset, ' ');
6917dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    } else {
6927dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      FirstArg = false;
6937dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
6947dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6951f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut << I->first << " " << I->second;
6967dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
6977dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
6987dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
6997dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesbool RSReflectionCpp::genCreateFieldPacker(const RSExportType *ET,
7007dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines                                           const char *FieldPackerName) {
701c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet  size_t AllocSize = ET->getAllocSize();
7027dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
7037dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  if (AllocSize > 0) {
7041f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "android::RSC::FieldPacker " << FieldPackerName << "("
7051f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << AllocSize << ");\n";
7067dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    return true;
7077dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
7087dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
7097dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  return false;
7107dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
7117dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
7127dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hinesvoid RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
7137dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines                                       const char *VarName,
7147dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines                                       const char *FieldPackerName) {
7157dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  switch (ET->getClass()) {
7162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
7172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
7182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer:
7192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix: {
7201f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << FieldPackerName << ".add(" << VarName << ");\n";
7212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray: {
7242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    /*const RSExportConstantArrayType *ECAT =
7252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportConstantArrayType *>(ET);
7262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // TODO(zonr): more elegant way. Currently, we obtain the unique index
7282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             variable (this method involves recursive call which means
7292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             we may have more than one level loop, therefore we can't
7302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             always use the same index variable name here) name given
7312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //             in the for-loop from counting the '.' in @VarName.
7322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Level = 0;
7332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    size_t LastDotPos = 0;
7342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string ElementVarName(VarName);
7352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7361f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  while (LastDotPos != std::string::npos) {
7371f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
7381f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    Level++;
7391f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  }
7401f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  std::string IndexVarName("ct");
7411f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  IndexVarName.append(llvm::utostr_32(Level));
7422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7431f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  C.indent() << "for (int " << IndexVarName << " = 0; " <<
7441f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                      IndexVarName << " < " << ECAT->getSize() << "; " <<
7451f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                      IndexVarName << "++)";
7461f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  C.startBlock();
7472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7481f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  ElementVarName.append("[" + IndexVarName + "]");
7491f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
7501f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                   FieldPackerName);
7512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7521f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  C.endBlock();*/
7532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
7562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportRecordType *ERT = static_cast<const RSExportRecordType *>(ET);
7572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Relative pos from now on in field packer
7582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    unsigned Pos = 0;
7592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
7612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                  E = ERT->fields_end();
7622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet         I != E; I++) {
7632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportRecordType::Field *F = *I;
7642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::string FieldName;
7652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldOffset = F->getOffsetInParent();
7662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      const RSExportType *T = F->getType();
7672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldStoreSize = T->getStoreSize();
7682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      size_t FieldAllocSize = T->getAllocSize();
7692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      if (VarName != NULL)
7712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = VarName + ("." + F->getName());
7722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      else
7732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        FieldName = F->getName();
7747dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
7752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      if (FieldOffset > Pos) {
7761f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet        mOut.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos)
7771f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                      << ");\n";
7787dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      }
7797dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
7802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName);
7812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      // There is padding in the field type
7832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      if (FieldAllocSize > FieldStoreSize) {
7841f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet        mOut.indent() << FieldPackerName << ".skip("
7851f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                      << (FieldAllocSize - FieldStoreSize) << ");\n";
7867dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines      }
7872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      Pos = FieldOffset + FieldAllocSize;
7897dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
7902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
7912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // There maybe some padding after the struct
7922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (ERT->getAllocSize() > Pos) {
7931f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet      mOut.indent() << FieldPackerName << ".skip(" << ERT->getAllocSize() - Pos
7941f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                    << ");\n";
7957dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    }
7962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
7972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
7982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
7997dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
8007dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines}
8017dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
802003ac666e57669d4312b5792068c3db302ee7b84Stephen Hinesvoid RSReflectionCpp::genTypeCheck(const RSExportType *ET,
803003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines                                   const char *VarName) {
8041f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "// Type check for " << VarName << "\n";
805003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
806003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
807003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    const RSExportPointerType *EPT =
8082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
809003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    ET = EPT->getPointeeType();
810003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
811003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
812003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  std::string TypeName;
813003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  switch (ET->getClass()) {
8142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
8152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
8162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
8172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    TypeName = ET->getElementName();
8182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
820003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
8212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
8222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
823003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
824003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
825003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  if (!TypeName.empty()) {
8261f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "if (!" << VarName
8271f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << "->getType()->getElement()->isCompatible("
8281f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                  << RS_ELEM_PREFIX << TypeName << "))";
8291f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.startBlock();
8301f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "mRS->throwError(RS_ERROR_RUNTIME_ERROR, "
8311f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                     "\"Incompatible type\");\n";
8321f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.indent() << "return;\n";
8331f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet    mOut.endBlock();
834003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
835003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines}
836003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
837003ac666e57669d4312b5792068c3db302ee7b84Stephen Hinesvoid RSReflectionCpp::genTypeInstanceFromPointer(const RSExportType *ET) {
838003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  if (ET->getClass() == RSExportType::ExportClassPointer) {
839003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    // For pointer parameters to original forEach kernels.
840003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    const RSExportPointerType *EPT =
8412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPointerType *>(ET);
842003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    genTypeInstance(EPT->getPointeeType());
843003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  } else {
844003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    // For handling pass-by-value kernel parameters.
845003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    genTypeInstance(ET);
846003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
847003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines}
848003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
849003ac666e57669d4312b5792068c3db302ee7b84Stephen Hinesvoid RSReflectionCpp::genTypeInstance(const RSExportType *ET) {
850003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  switch (ET->getClass()) {
8512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive:
8522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector:
8532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
8542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
8552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::string TypeName = ET->getElementName();
856efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    mTypesToCheck.insert(TypeName);
8572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
859003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
8602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
8612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
862003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  }
863003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines}
864003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
86580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hinesvoid RSReflectionCpp::genInitExportVariable(const RSExportType *ET,
86680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                            const std::string &VarName,
86780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                            const clang::APValue &Val) {
86880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
869003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
87080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  switch (ET->getClass()) {
8712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPrimitive: {
8722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportPrimitiveType *EPT =
8732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        static_cast<const RSExportPrimitiveType *>(ET);
8742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (EPT->getType() == DataTypeBoolean) {
8752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      genInitBoolExportVariable(VarName, Val);
8762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
8772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      genInitPrimitiveExportVariable(VarName, Val);
8782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
8792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassPointer: {
8822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
8832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      std::cerr << "Initializer which is non-NULL to pointer type variable "
8842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                   "will be ignored" << std::endl;
8852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
8862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
8872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassVector: {
8882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const RSExportVectorType *EVT = static_cast<const RSExportVectorType *>(ET);
8892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    switch (Val.getKind()) {
8902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Int:
8912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Float: {
8922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < EVT->getNumElement(); i++) {
8932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + getVectorAccessor(i);
8942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, Val);
89580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      }
89680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      break;
89780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    }
8982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Vector: {
8992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      unsigned NumElements = std::min(
9002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet          static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
9012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      for (unsigned i = 0; i < NumElements; i++) {
9022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        const clang::APValue &ElementVal = Val.getVectorElt(i);
9032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        std::string Name = VarName + "." + getVectorAccessor(i);
9042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        genInitPrimitiveExportVariable(Name, ElementVal);
90580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      }
90680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines      break;
90780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    }
9082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::MemberPointer:
9092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Uninitialized:
9102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexInt:
9112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::ComplexFloat:
9122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::LValue:
9132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Array:
9142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Struct:
9152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::Union:
9162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case clang::APValue::AddrLabelDiff: {
9172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      slangAssert(false && "Unexpected type of value of initializer.");
91880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    }
91980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines    }
9202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
9212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
9222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassMatrix:
9232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassConstantArray:
9242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case RSExportType::ExportClassRecord: {
9252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    slangAssert(false && "Unsupported initializer for record/matrix/constant "
9262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                         "array type variable currently");
9272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
9282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
9292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default: { slangAssert(false && "Unknown class of type"); }
93080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  }
93180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines}
93280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
933efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletconst char *RSReflectionCpp::getVectorAccessor(unsigned Index) {
934efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  static const char *VectorAccessorMap[] = {/* 0 */ "x",
935efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                            /* 1 */ "y",
936efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                            /* 2 */ "z",
937efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                            /* 3 */ "w",
938efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  };
939efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
940efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char *))) &&
941efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet              "Out-of-bound index to access vector member");
942efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
943efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  return VectorAccessorMap[Index];
944efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
945efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
94680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hinesvoid RSReflectionCpp::genZeroInitExportVariable(const std::string &VarName) {
9471f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << "memset(&" << RS_EXPORT_VAR_PREFIX << VarName
9481f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                << ", 0, sizeof(" << RS_EXPORT_VAR_PREFIX << VarName << "));\n";
94980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines}
95080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
9512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletvoid
9522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc BrouilletRSReflectionCpp::genInitPrimitiveExportVariable(const std::string &VarName,
9532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                const clang::APValue &Val) {
95480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
95580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
956efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
957efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  genInitValue(Val);
958efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  mOut << ";\n";
959efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
960efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
961efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletvoid RSReflectionCpp::genInitValue(const clang::APValue &Val, bool asBool) {
962efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  switch (Val.getKind()) {
963efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Int: {
964efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    llvm::APInt api = Val.getInt();
965efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (asBool) {
966efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      mOut << ((api.getSExtValue() == 0) ? "false" : "true");
967efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    } else {
968efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      // TODO: Handle unsigned correctly for C++
969efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      mOut << api.getSExtValue();
970efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (api.getBitWidth() > 32) {
971efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        mOut << "L";
972efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
973efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
974efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
975efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
976efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
977efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Float: {
978efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    llvm::APFloat apf = Val.getFloat();
979efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    llvm::SmallString<30> s;
980efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    apf.toString(s);
981efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    mOut << s.c_str();
982efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
983efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      if (s.count('.') == 0) {
984efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        mOut << ".f";
985efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      } else {
986efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        mOut << "f";
987efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet      }
988efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
989efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
990efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
991efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
992efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexInt:
993efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::ComplexFloat:
994efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::LValue:
995efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  case clang::APValue::Vector: {
996efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    slangAssert(false && "Primitive type cannot have such kind of initializer");
997efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    break;
998efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
999efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1000efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  default: { slangAssert(false && "Unknown kind of initializer"); }
1001efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  }
100280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines}
100380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
100480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hinesvoid RSReflectionCpp::genInitBoolExportVariable(const std::string &VarName,
100580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                                const clang::APValue &Val) {
100680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  slangAssert(!Val.isUninit() && "Not a valid initializer");
100780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  slangAssert((Val.getKind() == clang::APValue::Int) &&
100880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines              "Bool type has wrong initial APValue");
100980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
10101f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  mOut.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "
10111f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
10121f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet                << ";";
101380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines}
1014003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
10152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang
1016