11b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/*
21b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Copyright 2012, 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
17efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_  // NOLINT
181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_
191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
201f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet#include "slang_rs_reflect_utils.h"
211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
22003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines#include <set>
23003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines#include <string>
24003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#define RS_EXPORT_VAR_PREFIX "mExportVar_"
2680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsnamespace slang {
281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
29efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletclass RSReflectionCpp {
30efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet public:
3159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  RSReflectionCpp(const RSContext *Context, const std::string &OutputDirectory,
3259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                  const std::string &RSSourceFileName,
3359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet                  const std::string &BitCodeFileName);
3402a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  virtual ~RSReflectionCpp();
351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
3659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet  bool reflect();
371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
38efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet private:
391c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  struct Argument {
401c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala    std::string Type;
411c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala    std::string Name;
421c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala    std::string DefaultValue;
431c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala    Argument(std::string Type, std::string Name, std::string DefaultValue = "")
441c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala      : Type(Type), Name(Name), DefaultValue(DefaultValue) {}
451c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  };
461c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  typedef std::vector<Argument> ArgumentList;
47efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
48efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // Information coming from the compiler about the code we're reflecting.
49efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  const RSContext *mRSContext;
50efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
51efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // Path to the *.rs file for which we're generating C++ code.
52efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::string mRSSourceFilePath;
53efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // Path to the file that contains the byte code generated from the *.rs file.
54efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::string mBitCodeFilePath;
55efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // The directory where we'll generate the C++ files.
56efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::string mOutputDirectory;
57efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // A cleaned up version of the *.rs file name that can be used in generating
58efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // C++ identifiers.
59efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::string mCleanedRSFileName;
60efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // The name of the generated C++ class.
61efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::string mClassName;
62efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
63efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // TODO document
647dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  unsigned int mNextExportVarSlot;
657dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  unsigned int mNextExportFuncSlot;
667dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  unsigned int mNextExportForEachSlot;
677dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
68efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  // Generated RS Elements for type-checking code.
69efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  std::set<std::string> mTypesToCheck;
70efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
717dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  inline void clear() {
727dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    mNextExportVarSlot = 0;
737dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    mNextExportFuncSlot = 0;
747dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    mNextExportForEachSlot = 0;
75003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines    mTypesToCheck.clear();
767dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
777dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
781f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  // The file we are currently generating, either the header or the
791f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  // implementation file.
801f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  GeneratedFile mOut;
811f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet
82efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  void genInitValue(const clang::APValue &Val, bool asBool = false);
83efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  static const char *getVectorAccessor(unsigned index);
84efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  inline unsigned int getNextExportVarSlot() { return mNextExportVarSlot++; }
867dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  inline unsigned int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
887dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
897dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  inline unsigned int getNextExportForEachSlot() {
907dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines    return mNextExportForEachSlot++;
917dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  }
927dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
93eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  bool writeHeaderFile();
94eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  bool writeImplementationFile();
951c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala
961c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  // Write out signatures both in the header and implementation.
971f9d1217da29911dcd216b1b196da0ed170c166aJean-Luc Brouillet  void makeFunctionSignature(bool isDefinition, const RSExportFunc *ef);
981c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala
99eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  bool genEncodedBitCode();
1001cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genFieldsToStoreExportVariableValues();
1011cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genTypeInstancesUsedInForEach();
1021cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genFieldsForAllocationTypeVerification();
1031c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala
1041c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  // Write out the code for the getters and setters.
1051cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genExportVariablesGetterAndSetter();
1061c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala
1071c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  // Write out the code for the declaration of the kernel entry points.
1081cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genForEachDeclarations();
1091cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genExportFunctionDeclarations();
1101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1111c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  // Write out code for the definitions of the kernel entry points.
1121c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  void genExportForEachBodies();
1131c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  void genExportFunctionBodies();
1141c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala
11502a9826b586f765a95e3c75bd6080c4ee8e2e911Stephen Hines  bool startScriptHeader();
1167dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
11780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  // Write out code for an export variable initialization.
1182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  void genInitExportVariable(const RSExportType *ET, const std::string &VarName,
11980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                             const clang::APValue &Val);
12080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  void genZeroInitExportVariable(const std::string &VarName);
12180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  void genInitBoolExportVariable(const std::string &VarName,
12280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                 const clang::APValue &Val);
12380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines  void genInitPrimitiveExportVariable(const std::string &VarName,
12480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines                                      const clang::APValue &Val);
12580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines
1267dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  // Produce an argument string of the form "T1 t, T2 u, T3 v".
127eb8b99eb6a25284017169ed91e1a3520b375ef03Jean-Luc Brouillet  void genArguments(const ArgumentList &Args, int Offset);
1287dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
1297dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  void genPointerTypeExportVariable(const RSExportVar *EV);
1307dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  void genMatrixTypeExportVariable(const RSExportVar *EV);
1317dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  void genRecordTypeExportVariable(const RSExportVar *EV);
1327dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
1331cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genGetterAndSetter(const RSExportPrimitiveType *EPT, const RSExportVar* EV);
1341cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genGetterAndSetter(const RSExportVectorType *EVT, const RSExportVar* EV);
1351cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genGetterAndSetter(const RSExportConstantArrayType *AT, const RSExportVar* EV);
1361cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet  void genGetterAndSetter(const RSExportRecordType *ERT, const RSExportVar *EV);
1371cea27191515a15bbec86e259be622865e34d63eJean-Luc Brouillet
1387dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  // Write out a local FieldPacker (if necessary).
1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName);
1407dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines
1417dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines  // Populate (write) the FieldPacker with add() operations.
1422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  void genPackVarOfType(const RSExportType *ET, const char *VarName,
1437dd6da2077ad17ea59f4239f5275074bf5642859Stephen Hines                        const char *FieldPackerName);
144003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
145003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  // Generate a runtime type check for VarName.
146003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  void genTypeCheck(const RSExportType *ET, const char *VarName);
147003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
1481c6b927b4c59fabf44db846855ff5c4cfd48aa53Matt Wala  // Generate a type instance for a given type.
149003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  void genTypeInstanceFromPointer(const RSExportType *ET);
150003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines  void genTypeInstance(const RSExportType *ET);
151003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines
1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}; // class RSReflectionCpp
1531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang
1551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_  NOLINT
157