blob: c26f82f5df451d056a44103eb478b8aa75a6d9ed [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
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
Stephen Hinese639eb52010-11-08 19:27:20 -080017#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020#include <fstream>
21#include <iostream>
Stephen Hinese639eb52010-11-08 19:27:20 -080022#include <map>
23#include <string>
24#include <vector>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070025
zonr6315f762010-10-05 15:35:14 +080026#include "llvm/ADT/StringExtras.h"
27
Stephen Hines6e6578a2011-02-07 18:05:48 -080028#include "slang_assert.h"
zonr6315f762010-10-05 15:35:14 +080029#include "slang_rs_export_type.h"
30
Shih-wei Liao462aefd2010-06-04 15:32:04 -070031namespace slang {
32
zonr6315f762010-10-05 15:35:14 +080033 class RSContext;
34 class RSExportVar;
35 class RSExportFunc;
Stephen Hines593a8942011-05-10 15:29:50 -070036 class RSExportForEach;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070037
38class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070039 private:
40 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070041
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070042 std::string mLastError;
Stephen Hines4cc67fc2011-01-31 16:48:57 -080043 std::vector<std::string> *mGeneratedFileNames;
44
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047 class Context {
48 private:
49 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080050
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070052
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070053 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070054
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070055 std::string mOutputPathBase;
Zonr Chang8c6d9b22010-10-07 18:01:19 +080056
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070057 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059 std::string mPackageName;
60 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070061
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070062 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070063
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070064 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070065
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070066 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070067
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070068 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070069
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070070 int mNextExportVarSlot;
71 int mNextExportFuncSlot;
Stephen Hines593a8942011-05-10 15:29:50 -070072 int mNextExportForEachSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070073
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070074 // A mapping from a field in a record type to its index in the rsType
75 // instance. Only used when generates TypeClass (ScriptField_*).
Stephen Hinese639eb52010-11-08 19:27:20 -080076 typedef std::map<const RSExportRecordType::Field*, unsigned>
77 FieldIndexMapTy;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070078 FieldIndexMapTy mFieldIndexMap;
79 // Field index of current processing TypeClass.
80 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070081
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070082 inline void clear() {
83 mClassName = "";
84 mIndent = "";
85 mPaddingFieldIndex = 1;
86 mNextExportVarSlot = 0;
87 mNextExportFuncSlot = 0;
Stephen Hines593a8942011-05-10 15:29:50 -070088 mNextExportForEachSlot = 0;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070089 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070090 }
91
Zonr Chang8c6d9b22010-10-07 18:01:19 +080092 bool openClassFile(const std::string &ClassName,
93 std::string &ErrorMsg);
94
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070095 public:
96 typedef enum {
97 AM_Public,
98 AM_Protected,
99 AM_Private
100 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700101
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700102 bool mUseStdout;
103 mutable std::ofstream mOF;
104
105 static const char *AccessModifierStr(AccessModifier AM);
106
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700107 Context(const std::string &OutputPathBase,
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800108 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700109 const std::string &PackageName,
110 const std::string &ResourceId,
111 bool UseStdout)
112 : mVerbose(true),
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700113 mOutputPathBase(OutputPathBase),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700114 mInputRSFile(InputRSFile),
115 mPackageName(PackageName),
116 mResourceId(ResourceId),
117 mLicenseNote(ApacheLicenseNote),
118 mUseStdout(UseStdout) {
119 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +0800120 resetFieldIndex();
121 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700123 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700124
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700125 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800126 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700127 }
128 inline std::ostream &indent() const {
129 out() << mIndent;
130 return out();
131 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700132
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700133 inline void incIndentLevel() {
134 mIndent.append(4, ' ');
135 return;
136 }
137
138 inline void decIndentLevel() {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800139 slangAssert(getIndentLevel() > 0 && "No indent");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140 mIndent.erase(0, 4);
141 return;
142 }
143
Zonr Chang92b344a2010-10-05 20:39:03 +0800144 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700145
Zonr Chang92b344a2010-10-05 20:39:03 +0800146 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700147
Zonr Chang92b344a2010-10-05 20:39:03 +0800148 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Stephen Hines593a8942011-05-10 15:29:50 -0700149 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700150
151 // Will remove later due to field name information is not necessary for
152 // C-reflect-to-Java
153 inline std::string createPaddingField() {
154 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
155 }
156
157 inline void setLicenseNote(const std::string &LicenseNote) {
158 mLicenseNote = LicenseNote;
159 }
160
161 bool startClass(AccessModifier AM,
162 bool IsStatic,
163 const std::string &ClassName,
164 const char *SuperClassName,
165 std::string &ErrorMsg);
166 void endClass();
167
168 void startFunction(AccessModifier AM,
169 bool IsStatic,
170 const char *ReturnType,
171 const std::string &FunctionName,
172 int Argc, ...);
173
174 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
175 void startFunction(AccessModifier AM,
176 bool IsStatic,
177 const char *ReturnType,
178 const std::string &FunctionName,
179 const ArgTy &Args);
180 void endFunction();
181
182 void startBlock(bool ShouldIndent = false);
183 void endBlock();
184
185 inline const std::string &getPackageName() const { return mPackageName; }
186 inline const std::string &getClassName() const { return mClassName; }
187 inline const std::string &getResourceId() const { return mResourceId; }
188
189 void startTypeClass(const std::string &ClassName);
190 void endTypeClass();
191
Zonr Chang92b344a2010-10-05 20:39:03 +0800192 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700193
Zonr Chang92b344a2010-10-05 20:39:03 +0800194 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195
196 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800197 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
198 "Nested structure never occurs in C language.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700199 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
200 }
201
202 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
203 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
Stephen Hines6e6578a2011-02-07 18:05:48 -0800204 slangAssert((I != mFieldIndexMap.end()) &&
205 "Requesting field is out of scope.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 return I->second;
207 }
208
Zonr Chang92b344a2010-10-05 20:39:03 +0800209 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700210 };
211
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700212 bool genScriptClass(Context &C,
213 const std::string &ClassName,
214 std::string &ErrorMsg);
215 void genScriptClassConstructor(Context &C);
216
217 void genInitBoolExportVariable(Context &C,
218 const std::string &VarName,
219 const clang::APValue &Val);
220 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800221 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700222 const clang::APValue &Val);
223 void genInitExportVariable(Context &C,
224 const RSExportType *ET,
225 const std::string &VarName,
226 const clang::APValue &Val);
227 void genExportVariable(Context &C, const RSExportVar *EV);
228 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
229 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
230 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800231 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800232 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700233 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
234 void genGetExportVariable(Context &C,
235 const std::string &TypeName,
236 const std::string &VarName);
237
238 void genExportFunction(Context &C,
239 const RSExportFunc *EF);
240
Stephen Hines593a8942011-05-10 15:29:50 -0700241 void genExportForEach(Context &C,
242 const RSExportForEach *EF);
243
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700244 bool genTypeClass(Context &C,
245 const RSExportRecordType *ERT,
246 std::string &ErrorMsg);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800247 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800248 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
249 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
250 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700251 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
252 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
253 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
254 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
Zonr Changd42a4292010-10-17 02:38:43 +0800255 void genTypeClassResize(Context &C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700256
257 void genBuildElement(Context &C,
Zonr Chang89273bd2010-10-14 20:57:38 +0800258 const char *ElementBuilderName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700259 const RSExportRecordType *ERT,
Zonr Chang89273bd2010-10-14 20:57:38 +0800260 const char *RenderScriptVar,
261 bool IsInline);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700262 void genAddElementToElementBuilder(Context &C,
263 const RSExportType *ERT,
264 const std::string &VarName,
265 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +0800266 const char *RenderScriptVar,
267 unsigned ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700268 void genAddPaddingToElementBuiler(Context &C,
269 int PaddingSize,
270 const char *ElementBuilderName,
271 const char *RenderScriptVar);
272
273 bool genCreateFieldPacker(Context &C,
274 const RSExportType *T,
275 const char *FieldPackerName);
276 void genPackVarOfType(Context &C,
277 const RSExportType *T,
278 const char *VarName,
279 const char *FieldPackerName);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800280 void genAllocateVarOfType(Context &C,
281 const RSExportType *T,
282 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700283 void genNewItemBufferIfNull(Context &C, const char *Index);
284 void genNewItemBufferPackerIfNull(Context &C);
285
286 public:
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800287 explicit RSReflection(const RSContext *Context,
288 std::vector<std::string> *GeneratedFileNames)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700289 : mRSContext(Context),
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800290 mLastError(""),
291 mGeneratedFileNames(GeneratedFileNames) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800292 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700293 return;
294 }
295
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700296 bool reflect(const std::string &OutputPathBase,
297 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298 const std::string &InputFileName,
299 const std::string &OutputBCFileName);
300
301 inline const char *getLastError() const {
302 if (mLastError.empty())
303 return NULL;
304 else
305 return mLastError.c_str();
306 }
307}; // class RSReflection
308
309} // namespace slang
310
Stephen Hinese639eb52010-11-08 19:27:20 -0800311#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT