1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_  // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_
19
20#include "slang_rs_reflect_utils.h"
21
22#include <set>
23#include <string>
24
25#define RS_EXPORT_VAR_PREFIX "mExportVar_"
26
27namespace slang {
28
29class RSReflectionCpp {
30 public:
31  RSReflectionCpp(const RSContext *Context, const std::string &OutputDirectory,
32                  const std::string &RSSourceFileName,
33                  const std::string &BitCodeFileName);
34  virtual ~RSReflectionCpp();
35
36  bool reflect();
37
38 private:
39  struct Argument {
40    std::string Type;
41    std::string Name;
42    std::string DefaultValue;
43    Argument(std::string Type, std::string Name, std::string DefaultValue = "")
44      : Type(Type), Name(Name), DefaultValue(DefaultValue) {}
45  };
46  typedef std::vector<Argument> ArgumentList;
47
48  // Information coming from the compiler about the code we're reflecting.
49  const RSContext *mRSContext;
50
51  // Path to the *.rs file for which we're generating C++ code.
52  std::string mRSSourceFilePath;
53  // Path to the file that contains the byte code generated from the *.rs file.
54  std::string mBitCodeFilePath;
55  // The directory where we'll generate the C++ files.
56  std::string mOutputDirectory;
57  // A cleaned up version of the *.rs file name that can be used in generating
58  // C++ identifiers.
59  std::string mCleanedRSFileName;
60  // The name of the generated C++ class.
61  std::string mClassName;
62
63  // TODO document
64  unsigned int mNextExportVarSlot;
65  unsigned int mNextExportFuncSlot;
66  unsigned int mNextExportForEachSlot;
67
68  // Generated RS Elements for type-checking code.
69  std::set<std::string> mTypesToCheck;
70
71  inline void clear() {
72    mNextExportVarSlot = 0;
73    mNextExportFuncSlot = 0;
74    mNextExportForEachSlot = 0;
75    mTypesToCheck.clear();
76  }
77
78  // The file we are currently generating, either the header or the
79  // implementation file.
80  GeneratedFile mOut;
81
82  void genInitValue(const clang::APValue &Val, bool asBool = false);
83  static const char *getVectorAccessor(unsigned index);
84
85  inline unsigned int getNextExportVarSlot() { return mNextExportVarSlot++; }
86
87  inline unsigned int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
88
89  inline unsigned int getNextExportForEachSlot() {
90    return mNextExportForEachSlot++;
91  }
92
93  bool writeHeaderFile();
94  bool writeImplementationFile();
95
96  // Write out signatures both in the header and implementation.
97  void makeFunctionSignature(bool isDefinition, const RSExportFunc *ef);
98
99  bool genEncodedBitCode();
100  void genFieldsToStoreExportVariableValues();
101  void genTypeInstancesUsedInForEach();
102  void genFieldsForAllocationTypeVerification();
103
104  // Write out the code for the getters and setters.
105  void genExportVariablesGetterAndSetter();
106
107  // Write out the code for the declaration of the kernel entry points.
108  void genForEachDeclarations();
109  void genExportFunctionDeclarations();
110
111  // Write out code for the definitions of the kernel entry points.
112  void genExportForEachBodies();
113  void genExportFunctionBodies();
114
115  bool startScriptHeader();
116
117  // Write out code for an export variable initialization.
118  void genInitExportVariable(const RSExportType *ET, const std::string &VarName,
119                             const clang::APValue &Val);
120  void genZeroInitExportVariable(const std::string &VarName);
121  void genInitBoolExportVariable(const std::string &VarName,
122                                 const clang::APValue &Val);
123  void genInitPrimitiveExportVariable(const std::string &VarName,
124                                      const clang::APValue &Val);
125
126  // Produce an argument string of the form "T1 t, T2 u, T3 v".
127  void genArguments(const ArgumentList &Args, int Offset);
128
129  void genPointerTypeExportVariable(const RSExportVar *EV);
130  void genMatrixTypeExportVariable(const RSExportVar *EV);
131  void genRecordTypeExportVariable(const RSExportVar *EV);
132
133  void genGetterAndSetter(const RSExportPrimitiveType *EPT, const RSExportVar* EV);
134  void genGetterAndSetter(const RSExportVectorType *EVT, const RSExportVar* EV);
135  void genGetterAndSetter(const RSExportConstantArrayType *AT, const RSExportVar* EV);
136  void genGetterAndSetter(const RSExportRecordType *ERT, const RSExportVar *EV);
137
138  // Write out a local FieldPacker (if necessary).
139  bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName);
140
141  // Populate (write) the FieldPacker with add() operations.
142  void genPackVarOfType(const RSExportType *ET, const char *VarName,
143                        const char *FieldPackerName);
144
145  // Generate a runtime type check for VarName.
146  void genTypeCheck(const RSExportType *ET, const char *VarName);
147
148  // Generate a type instance for a given type.
149  void genTypeInstanceFromPointer(const RSExportType *ET);
150  void genTypeInstance(const RSExportType *ET);
151
152}; // class RSReflectionCpp
153
154} // namespace slang
155
156#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_  NOLINT
157