blob: c4750dca28b6be11ecfa488e8c58527c6ab50f51 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#ifndef _SLANG_COMPILER_RS_REFLECTION_H
2#define _SLANG_COMPILER_RS_REFLECTION_H
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003
Shih-wei Liao462aefd2010-06-04 15:32:04 -07004#include <map>
5#include <vector>
6#include <string>
7#include <cassert>
8#include <fstream>
9#include <iostream>
10
zonr6315f762010-10-05 15:35:14 +080011#include "llvm/ADT/StringExtras.h"
12
13#include "slang_rs_export_type.h"
14
Shih-wei Liao462aefd2010-06-04 15:32:04 -070015namespace slang {
16
zonr6315f762010-10-05 15:35:14 +080017 class RSContext;
18 class RSExportVar;
19 class RSExportFunc;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
21class RSReflection {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022 private:
23 const RSContext *mRSContext;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070024
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070025 std::string mLastError;
26 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070028 class Context {
29 private:
30 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080031
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070032 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070034 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070035
Zonr Chang8c6d9b22010-10-07 18:01:19 +080036 std::string mOutputPath;
37
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070038 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070039
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070040 std::string mPackageName;
41 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070042
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070044
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070049 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070050
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051 int mNextExportVarSlot;
52 int mNextExportFuncSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070053
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054 // A mapping from a field in a record type to its index in the rsType
55 // instance. Only used when generates TypeClass (ScriptField_*).
56 typedef std::map<const RSExportRecordType::Field*, unsigned> FieldIndexMapTy;
57 FieldIndexMapTy mFieldIndexMap;
58 // Field index of current processing TypeClass.
59 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070060
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070061 inline void clear() {
62 mClassName = "";
63 mIndent = "";
64 mPaddingFieldIndex = 1;
65 mNextExportVarSlot = 0;
66 mNextExportFuncSlot = 0;
67 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068 }
69
Zonr Chang8c6d9b22010-10-07 18:01:19 +080070 bool openClassFile(const std::string &ClassName,
71 std::string &ErrorMsg);
72
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070073 public:
74 typedef enum {
75 AM_Public,
76 AM_Protected,
77 AM_Private
78 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070079
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070080 bool mUseStdout;
81 mutable std::ofstream mOF;
82
83 static const char *AccessModifierStr(AccessModifier AM);
84
Zonr Chang8c6d9b22010-10-07 18:01:19 +080085 Context(const std::string &OutputPath,
86 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070087 const std::string &PackageName,
88 const std::string &ResourceId,
89 bool UseStdout)
90 : mVerbose(true),
Zonr Chang8c6d9b22010-10-07 18:01:19 +080091 mOutputPath(OutputPath),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070092 mInputRSFile(InputRSFile),
93 mPackageName(PackageName),
94 mResourceId(ResourceId),
95 mLicenseNote(ApacheLicenseNote),
96 mUseStdout(UseStdout) {
97 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +080098 resetFieldIndex();
99 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700100 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700101 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700103 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800104 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 }
106 inline std::ostream &indent() const {
107 out() << mIndent;
108 return out();
109 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700110
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700111 inline void incIndentLevel() {
112 mIndent.append(4, ' ');
113 return;
114 }
115
116 inline void decIndentLevel() {
117 assert(getIndentLevel() > 0 && "No indent");
118 mIndent.erase(0, 4);
119 return;
120 }
121
Zonr Chang92b344a2010-10-05 20:39:03 +0800122 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700123
Zonr Chang92b344a2010-10-05 20:39:03 +0800124 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700125
Zonr Chang92b344a2010-10-05 20:39:03 +0800126 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700127
128 // Will remove later due to field name information is not necessary for
129 // C-reflect-to-Java
130 inline std::string createPaddingField() {
131 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
132 }
133
134 inline void setLicenseNote(const std::string &LicenseNote) {
135 mLicenseNote = LicenseNote;
136 }
137
138 bool startClass(AccessModifier AM,
139 bool IsStatic,
140 const std::string &ClassName,
141 const char *SuperClassName,
142 std::string &ErrorMsg);
143 void endClass();
144
145 void startFunction(AccessModifier AM,
146 bool IsStatic,
147 const char *ReturnType,
148 const std::string &FunctionName,
149 int Argc, ...);
150
151 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
152 void startFunction(AccessModifier AM,
153 bool IsStatic,
154 const char *ReturnType,
155 const std::string &FunctionName,
156 const ArgTy &Args);
157 void endFunction();
158
159 void startBlock(bool ShouldIndent = false);
160 void endBlock();
161
162 inline const std::string &getPackageName() const { return mPackageName; }
163 inline const std::string &getClassName() const { return mClassName; }
164 inline const std::string &getResourceId() const { return mResourceId; }
165
166 void startTypeClass(const std::string &ClassName);
167 void endTypeClass();
168
Zonr Chang92b344a2010-10-05 20:39:03 +0800169 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700170
Zonr Chang92b344a2010-10-05 20:39:03 +0800171 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700172
173 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
174 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
175 "Nested structure never occurs in C language.");
176 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
177 }
178
179 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
180 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
181 assert((I != mFieldIndexMap.end()) &&
182 "Requesting field is out of scope.");
183 return I->second;
184 }
185
Zonr Chang92b344a2010-10-05 20:39:03 +0800186 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700187 };
188
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189 bool genScriptClass(Context &C,
190 const std::string &ClassName,
191 std::string &ErrorMsg);
192 void genScriptClassConstructor(Context &C);
193
194 void genInitBoolExportVariable(Context &C,
195 const std::string &VarName,
196 const clang::APValue &Val);
197 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800198 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700199 const clang::APValue &Val);
200 void genInitExportVariable(Context &C,
201 const RSExportType *ET,
202 const std::string &VarName,
203 const clang::APValue &Val);
204 void genExportVariable(Context &C, const RSExportVar *EV);
205 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
206 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
207 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800208 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800209 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700210 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
211 void genGetExportVariable(Context &C,
212 const std::string &TypeName,
213 const std::string &VarName);
214
215 void genExportFunction(Context &C,
216 const RSExportFunc *EF);
217
218 bool genTypeClass(Context &C,
219 const RSExportRecordType *ERT,
220 std::string &ErrorMsg);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800221 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800222 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
223 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
224 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700225 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
226 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
227 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
228 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
229
230 void genBuildElement(Context &C,
231 const RSExportRecordType *ERT,
232 const char *RenderScriptVar);
233 void genAddElementToElementBuilder(Context &C,
234 const RSExportType *ERT,
235 const std::string &VarName,
236 const char *ElementBuilderName,
237 const char *RenderScriptVar);
238 void genAddPaddingToElementBuiler(Context &C,
239 int PaddingSize,
240 const char *ElementBuilderName,
241 const char *RenderScriptVar);
242
243 bool genCreateFieldPacker(Context &C,
244 const RSExportType *T,
245 const char *FieldPackerName);
246 void genPackVarOfType(Context &C,
247 const RSExportType *T,
248 const char *VarName,
249 const char *FieldPackerName);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800250 void genAllocateVarOfType(Context &C,
251 const RSExportType *T,
252 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700253 void genNewItemBufferIfNull(Context &C, const char *Index);
254 void genNewItemBufferPackerIfNull(Context &C);
255
256 public:
zonr6315f762010-10-05 15:35:14 +0800257 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700258 : mRSContext(Context),
259 mLastError("") {
260 return;
261 }
262
263 bool reflect(const char *OutputPackageName,
264 const std::string &InputFileName,
265 const std::string &OutputBCFileName);
266
267 inline const char *getLastError() const {
268 if (mLastError.empty())
269 return NULL;
270 else
271 return mLastError.c_str();
272 }
273}; // class RSReflection
274
275} // namespace slang
276
zonr6315f762010-10-05 15:35:14 +0800277#endif // _SLANG_COMPILER_RS_REFLECTION_H