slang_rs_reflection.h revision e639eb5caa2c386b4a60659a4929e8a6141a2cbe
1/*
2 * Copyright 2010, 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_H_  // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
19
20#include <cassert>
21#include <fstream>
22#include <iostream>
23#include <map>
24#include <string>
25#include <vector>
26
27#include "llvm/ADT/StringExtras.h"
28
29#include "slang_rs_export_type.h"
30
31namespace slang {
32
33  class RSContext;
34  class RSExportVar;
35  class RSExportFunc;
36
37class RSReflection {
38 private:
39  const RSContext *mRSContext;
40
41  std::string mLastError;
42  inline void setError(const std::string &Error) { mLastError = Error; }
43
44  class Context {
45   private:
46    static const char *const ApacheLicenseNote;
47
48    static const char *const Import[];
49
50    bool mVerbose;
51
52    std::string mOutputPathBase;
53
54    std::string mInputRSFile;
55
56    std::string mPackageName;
57    std::string mResourceId;
58
59    std::string mClassName;
60
61    std::string mLicenseNote;
62
63    std::string mIndent;
64
65    int mPaddingFieldIndex;
66
67    int mNextExportVarSlot;
68    int mNextExportFuncSlot;
69
70    // A mapping from a field in a record type to its index in the rsType
71    // instance. Only used when generates TypeClass (ScriptField_*).
72    typedef std::map<const RSExportRecordType::Field*, unsigned>
73        FieldIndexMapTy;
74    FieldIndexMapTy mFieldIndexMap;
75    // Field index of current processing TypeClass.
76    unsigned mFieldIndex;
77
78    inline void clear() {
79      mClassName = "";
80      mIndent = "";
81      mPaddingFieldIndex = 1;
82      mNextExportVarSlot = 0;
83      mNextExportFuncSlot = 0;
84      return;
85    }
86
87    bool openClassFile(const std::string &ClassName,
88                       std::string &ErrorMsg);
89
90   public:
91    typedef enum {
92      AM_Public,
93      AM_Protected,
94      AM_Private
95    } AccessModifier;
96
97    bool mUseStdout;
98    mutable std::ofstream mOF;
99
100    static const char *AccessModifierStr(AccessModifier AM);
101
102    Context(const std::string &OutputPathBase,
103            const std::string &InputRSFile,
104            const std::string &PackageName,
105            const std::string &ResourceId,
106            bool UseStdout)
107        : mVerbose(true),
108          mOutputPathBase(OutputPathBase),
109          mInputRSFile(InputRSFile),
110          mPackageName(PackageName),
111          mResourceId(ResourceId),
112          mLicenseNote(ApacheLicenseNote),
113          mUseStdout(UseStdout) {
114      clear();
115      resetFieldIndex();
116      clearFieldIndexMap();
117      return;
118    }
119
120    inline std::ostream &out() const {
121      return ((mUseStdout) ? std::cout : mOF);
122    }
123    inline std::ostream &indent() const {
124      out() << mIndent;
125      return out();
126    }
127
128    inline void incIndentLevel() {
129      mIndent.append(4, ' ');
130      return;
131    }
132
133    inline void decIndentLevel() {
134      assert(getIndentLevel() > 0 && "No indent");
135      mIndent.erase(0, 4);
136      return;
137    }
138
139    inline int getIndentLevel() { return (mIndent.length() >> 2); }
140
141    inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
142
143    inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
144
145    // Will remove later due to field name information is not necessary for
146    // C-reflect-to-Java
147    inline std::string createPaddingField() {
148      return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
149    }
150
151    inline void setLicenseNote(const std::string &LicenseNote) {
152      mLicenseNote = LicenseNote;
153    }
154
155    bool startClass(AccessModifier AM,
156                    bool IsStatic,
157                    const std::string &ClassName,
158                    const char *SuperClassName,
159                    std::string &ErrorMsg);
160    void endClass();
161
162    void startFunction(AccessModifier AM,
163                       bool IsStatic,
164                       const char *ReturnType,
165                       const std::string &FunctionName,
166                       int Argc, ...);
167
168    typedef std::vector<std::pair<std::string, std::string> > ArgTy;
169    void startFunction(AccessModifier AM,
170                       bool IsStatic,
171                       const char *ReturnType,
172                       const std::string &FunctionName,
173                       const ArgTy &Args);
174    void endFunction();
175
176    void startBlock(bool ShouldIndent = false);
177    void endBlock();
178
179    inline const std::string &getPackageName() const { return mPackageName; }
180    inline const std::string &getClassName() const { return mClassName; }
181    inline const std::string &getResourceId() const { return mResourceId; }
182
183    void startTypeClass(const std::string &ClassName);
184    void endTypeClass();
185
186    inline void incFieldIndex() { mFieldIndex++; }
187
188    inline void resetFieldIndex() { mFieldIndex = 0; }
189
190    inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
191      assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
192             "Nested structure never occurs in C language.");
193      mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
194    }
195
196    inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
197      FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
198      assert((I != mFieldIndexMap.end()) &&
199             "Requesting field is out of scope.");
200      return I->second;
201    }
202
203    inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
204  };
205
206  bool genScriptClass(Context &C,
207                      const std::string &ClassName,
208                      std::string &ErrorMsg);
209  void genScriptClassConstructor(Context &C);
210
211  void genInitBoolExportVariable(Context &C,
212                                 const std::string &VarName,
213                                 const clang::APValue &Val);
214  void genInitPrimitiveExportVariable(Context &C,
215                                      const std::string &VarName,
216                                      const clang::APValue &Val);
217  void genInitExportVariable(Context &C,
218                             const RSExportType *ET,
219                             const std::string &VarName,
220                             const clang::APValue &Val);
221  void genExportVariable(Context &C, const RSExportVar *EV);
222  void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
223  void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
224  void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
225  void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
226  void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
227  void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
228  void genGetExportVariable(Context &C,
229                            const std::string &TypeName,
230                            const std::string &VarName);
231
232  void genExportFunction(Context &C,
233                         const RSExportFunc *EF);
234
235  bool genTypeClass(Context &C,
236                    const RSExportRecordType *ERT,
237                    std::string &ErrorMsg);
238  void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
239  void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
240  void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
241  void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
242  void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
243  void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
244  void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
245  void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
246  void genTypeClassResize(Context &C);
247
248  void genBuildElement(Context &C,
249                       const char *ElementBuilderName,
250                       const RSExportRecordType *ERT,
251                       const char *RenderScriptVar,
252                       bool IsInline);
253  void genAddElementToElementBuilder(Context &C,
254                                     const RSExportType *ERT,
255                                     const std::string &VarName,
256                                     const char *ElementBuilderName,
257                                     const char *RenderScriptVar,
258                                     unsigned ArraySize);
259  void genAddPaddingToElementBuiler(Context &C,
260                                    int PaddingSize,
261                                    const char *ElementBuilderName,
262                                    const char *RenderScriptVar);
263
264  bool genCreateFieldPacker(Context &C,
265                            const RSExportType *T,
266                            const char *FieldPackerName);
267  void genPackVarOfType(Context &C,
268                        const RSExportType *T,
269                        const char *VarName,
270                        const char *FieldPackerName);
271  void genAllocateVarOfType(Context &C,
272                            const RSExportType *T,
273                            const std::string &VarName);
274  void genNewItemBufferIfNull(Context &C, const char *Index);
275  void genNewItemBufferPackerIfNull(Context &C);
276
277 public:
278  explicit RSReflection(const RSContext *Context)
279      : mRSContext(Context),
280        mLastError("") {
281    return;
282  }
283
284  bool reflect(const std::string &OutputPathBase,
285               const std::string &OutputPackageName,
286               const std::string &InputFileName,
287               const std::string &OutputBCFileName);
288
289  inline const char *getLastError() const {
290    if (mLastError.empty())
291      return NULL;
292    else
293      return mLastError.c_str();
294  }
295};  // class RSReflection
296
297}   // namespace slang
298
299#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
300