blob: 2f9e18c3cd1f5dc6b721e40e0d3743d82168d231 [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;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070036
37class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038 private:
39 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070040
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070041 std::string mLastError;
Stephen Hines4cc67fc2011-01-31 16:48:57 -080042 std::vector<std::string> *mGeneratedFileNames;
43
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070044 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070046 class Context {
47 private:
48 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080049
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070051
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070052 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070054 std::string mOutputPathBase;
Zonr Chang8c6d9b22010-10-07 18:01:19 +080055
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070057
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070058 std::string mPackageName;
59 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070061 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070062
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070063 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070064
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070065 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070069 int mNextExportVarSlot;
70 int mNextExportFuncSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070071
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070072 // A mapping from a field in a record type to its index in the rsType
73 // instance. Only used when generates TypeClass (ScriptField_*).
Stephen Hinese639eb52010-11-08 19:27:20 -080074 typedef std::map<const RSExportRecordType::Field*, unsigned>
75 FieldIndexMapTy;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070076 FieldIndexMapTy mFieldIndexMap;
77 // Field index of current processing TypeClass.
78 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070079
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070080 inline void clear() {
81 mClassName = "";
82 mIndent = "";
83 mPaddingFieldIndex = 1;
84 mNextExportVarSlot = 0;
85 mNextExportFuncSlot = 0;
86 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070087 }
88
Zonr Chang8c6d9b22010-10-07 18:01:19 +080089 bool openClassFile(const std::string &ClassName,
90 std::string &ErrorMsg);
91
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070092 public:
93 typedef enum {
94 AM_Public,
95 AM_Protected,
96 AM_Private
97 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070098
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070099 bool mUseStdout;
100 mutable std::ofstream mOF;
101
102 static const char *AccessModifierStr(AccessModifier AM);
103
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700104 Context(const std::string &OutputPathBase,
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800105 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700106 const std::string &PackageName,
107 const std::string &ResourceId,
108 bool UseStdout)
109 : mVerbose(true),
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700110 mOutputPathBase(OutputPathBase),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700111 mInputRSFile(InputRSFile),
112 mPackageName(PackageName),
113 mResourceId(ResourceId),
114 mLicenseNote(ApacheLicenseNote),
115 mUseStdout(UseStdout) {
116 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +0800117 resetFieldIndex();
118 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700119 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700120 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700121
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800123 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700124 }
125 inline std::ostream &indent() const {
126 out() << mIndent;
127 return out();
128 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700129
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130 inline void incIndentLevel() {
131 mIndent.append(4, ' ');
132 return;
133 }
134
135 inline void decIndentLevel() {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800136 slangAssert(getIndentLevel() > 0 && "No indent");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700137 mIndent.erase(0, 4);
138 return;
139 }
140
Zonr Chang92b344a2010-10-05 20:39:03 +0800141 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700142
Zonr Chang92b344a2010-10-05 20:39:03 +0800143 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700144
Zonr Chang92b344a2010-10-05 20:39:03 +0800145 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700146
147 // Will remove later due to field name information is not necessary for
148 // C-reflect-to-Java
149 inline std::string createPaddingField() {
150 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
151 }
152
153 inline void setLicenseNote(const std::string &LicenseNote) {
154 mLicenseNote = LicenseNote;
155 }
156
157 bool startClass(AccessModifier AM,
158 bool IsStatic,
159 const std::string &ClassName,
160 const char *SuperClassName,
161 std::string &ErrorMsg);
162 void endClass();
163
164 void startFunction(AccessModifier AM,
165 bool IsStatic,
166 const char *ReturnType,
167 const std::string &FunctionName,
168 int Argc, ...);
169
170 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
171 void startFunction(AccessModifier AM,
172 bool IsStatic,
173 const char *ReturnType,
174 const std::string &FunctionName,
175 const ArgTy &Args);
176 void endFunction();
177
178 void startBlock(bool ShouldIndent = false);
179 void endBlock();
180
181 inline const std::string &getPackageName() const { return mPackageName; }
182 inline const std::string &getClassName() const { return mClassName; }
183 inline const std::string &getResourceId() const { return mResourceId; }
184
185 void startTypeClass(const std::string &ClassName);
186 void endTypeClass();
187
Zonr Chang92b344a2010-10-05 20:39:03 +0800188 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189
Zonr Chang92b344a2010-10-05 20:39:03 +0800190 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700191
192 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800193 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
194 "Nested structure never occurs in C language.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
196 }
197
198 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
199 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
Stephen Hines6e6578a2011-02-07 18:05:48 -0800200 slangAssert((I != mFieldIndexMap.end()) &&
201 "Requesting field is out of scope.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700202 return I->second;
203 }
204
Zonr Chang92b344a2010-10-05 20:39:03 +0800205 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 };
207
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700208 bool genScriptClass(Context &C,
209 const std::string &ClassName,
210 std::string &ErrorMsg);
211 void genScriptClassConstructor(Context &C);
212
213 void genInitBoolExportVariable(Context &C,
214 const std::string &VarName,
215 const clang::APValue &Val);
216 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800217 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700218 const clang::APValue &Val);
219 void genInitExportVariable(Context &C,
220 const RSExportType *ET,
221 const std::string &VarName,
222 const clang::APValue &Val);
223 void genExportVariable(Context &C, const RSExportVar *EV);
224 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
225 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
226 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800227 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800228 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700229 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
230 void genGetExportVariable(Context &C,
231 const std::string &TypeName,
232 const std::string &VarName);
233
234 void genExportFunction(Context &C,
235 const RSExportFunc *EF);
236
237 bool genTypeClass(Context &C,
238 const RSExportRecordType *ERT,
239 std::string &ErrorMsg);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800240 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800241 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
242 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
243 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700244 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
245 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
246 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
247 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
Zonr Changd42a4292010-10-17 02:38:43 +0800248 void genTypeClassResize(Context &C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700249
250 void genBuildElement(Context &C,
Zonr Chang89273bd2010-10-14 20:57:38 +0800251 const char *ElementBuilderName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700252 const RSExportRecordType *ERT,
Zonr Chang89273bd2010-10-14 20:57:38 +0800253 const char *RenderScriptVar,
254 bool IsInline);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700255 void genAddElementToElementBuilder(Context &C,
256 const RSExportType *ERT,
257 const std::string &VarName,
258 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +0800259 const char *RenderScriptVar,
260 unsigned ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700261 void genAddPaddingToElementBuiler(Context &C,
262 int PaddingSize,
263 const char *ElementBuilderName,
264 const char *RenderScriptVar);
265
266 bool genCreateFieldPacker(Context &C,
267 const RSExportType *T,
268 const char *FieldPackerName);
269 void genPackVarOfType(Context &C,
270 const RSExportType *T,
271 const char *VarName,
272 const char *FieldPackerName);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800273 void genAllocateVarOfType(Context &C,
274 const RSExportType *T,
275 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700276 void genNewItemBufferIfNull(Context &C, const char *Index);
277 void genNewItemBufferPackerIfNull(Context &C);
278
279 public:
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800280 explicit RSReflection(const RSContext *Context,
281 std::vector<std::string> *GeneratedFileNames)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700282 : mRSContext(Context),
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800283 mLastError(""),
284 mGeneratedFileNames(GeneratedFileNames) {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800285 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700286 return;
287 }
288
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700289 bool reflect(const std::string &OutputPathBase,
290 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700291 const std::string &InputFileName,
292 const std::string &OutputBCFileName);
293
294 inline const char *getLastError() const {
295 if (mLastError.empty())
296 return NULL;
297 else
298 return mLastError.c_str();
299 }
300}; // class RSReflection
301
302} // namespace slang
303
Stephen Hinese639eb52010-11-08 19:27:20 -0800304#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT