blob: ff6099ed8aa46d747d7b77eab106617dd34eab03 [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
zonr6315f762010-10-05 15:35:14 +080017#ifndef _SLANG_COMPILER_RS_REFLECTION_H
18#define _SLANG_COMPILER_RS_REFLECTION_H
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020#include <map>
21#include <vector>
22#include <string>
23#include <cassert>
24#include <fstream>
25#include <iostream>
26
zonr6315f762010-10-05 15:35:14 +080027#include "llvm/ADT/StringExtras.h"
28
29#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;
42 inline void setError(const std::string &Error) { mLastError = Error; }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070043
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070044 class Context {
45 private:
46 static const char *const ApacheLicenseNote;
Victor Hsiehd8a0d182010-07-07 19:22:33 +080047
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048 static const char *const Import[];
Shih-wei Liao462aefd2010-06-04 15:32:04 -070049
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050 bool mVerbose;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070051
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070052 std::string mOutputPathBase;
Zonr Chang8c6d9b22010-10-07 18:01:19 +080053
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054 std::string mInputRSFile;
Ying Wang4e348442010-08-18 10:29:12 -070055
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 std::string mPackageName;
57 std::string mResourceId;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070058
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070059 std::string mClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070061 std::string mLicenseNote;
Shih-wei Liaocecd11d2010-09-21 08:07:58 -070062
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070063 std::string mIndent;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070065 int mPaddingFieldIndex;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 int mNextExportVarSlot;
68 int mNextExportFuncSlot;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070069
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070070 // 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> FieldIndexMapTy;
73 FieldIndexMapTy mFieldIndexMap;
74 // Field index of current processing TypeClass.
75 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070076
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070077 inline void clear() {
78 mClassName = "";
79 mIndent = "";
80 mPaddingFieldIndex = 1;
81 mNextExportVarSlot = 0;
82 mNextExportFuncSlot = 0;
83 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070084 }
85
Zonr Chang8c6d9b22010-10-07 18:01:19 +080086 bool openClassFile(const std::string &ClassName,
87 std::string &ErrorMsg);
88
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070089 public:
90 typedef enum {
91 AM_Public,
92 AM_Protected,
93 AM_Private
94 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070095
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 bool mUseStdout;
97 mutable std::ofstream mOF;
98
99 static const char *AccessModifierStr(AccessModifier AM);
100
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700101 Context(const std::string &OutputPathBase,
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800102 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700103 const std::string &PackageName,
104 const std::string &ResourceId,
105 bool UseStdout)
106 : mVerbose(true),
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700107 mOutputPathBase(OutputPathBase),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700108 mInputRSFile(InputRSFile),
109 mPackageName(PackageName),
110 mResourceId(ResourceId),
111 mLicenseNote(ApacheLicenseNote),
112 mUseStdout(UseStdout) {
113 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +0800114 resetFieldIndex();
115 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700117 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700118
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700119 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800120 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700121 }
122 inline std::ostream &indent() const {
123 out() << mIndent;
124 return out();
125 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700126
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700127 inline void incIndentLevel() {
128 mIndent.append(4, ' ');
129 return;
130 }
131
132 inline void decIndentLevel() {
133 assert(getIndentLevel() > 0 && "No indent");
134 mIndent.erase(0, 4);
135 return;
136 }
137
Zonr Chang92b344a2010-10-05 20:39:03 +0800138 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700139
Zonr Chang92b344a2010-10-05 20:39:03 +0800140 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700141
Zonr Chang92b344a2010-10-05 20:39:03 +0800142 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700143
144 // Will remove later due to field name information is not necessary for
145 // C-reflect-to-Java
146 inline std::string createPaddingField() {
147 return "#padding_" + llvm::itostr(mPaddingFieldIndex++);
148 }
149
150 inline void setLicenseNote(const std::string &LicenseNote) {
151 mLicenseNote = LicenseNote;
152 }
153
154 bool startClass(AccessModifier AM,
155 bool IsStatic,
156 const std::string &ClassName,
157 const char *SuperClassName,
158 std::string &ErrorMsg);
159 void endClass();
160
161 void startFunction(AccessModifier AM,
162 bool IsStatic,
163 const char *ReturnType,
164 const std::string &FunctionName,
165 int Argc, ...);
166
167 typedef std::vector<std::pair<std::string, std::string> > ArgTy;
168 void startFunction(AccessModifier AM,
169 bool IsStatic,
170 const char *ReturnType,
171 const std::string &FunctionName,
172 const ArgTy &Args);
173 void endFunction();
174
175 void startBlock(bool ShouldIndent = false);
176 void endBlock();
177
178 inline const std::string &getPackageName() const { return mPackageName; }
179 inline const std::string &getClassName() const { return mClassName; }
180 inline const std::string &getResourceId() const { return mResourceId; }
181
182 void startTypeClass(const std::string &ClassName);
183 void endTypeClass();
184
Zonr Chang92b344a2010-10-05 20:39:03 +0800185 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700186
Zonr Chang92b344a2010-10-05 20:39:03 +0800187 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700188
189 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
190 assert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
191 "Nested structure never occurs in C language.");
192 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
193 }
194
195 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
196 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
197 assert((I != mFieldIndexMap.end()) &&
198 "Requesting field is out of scope.");
199 return I->second;
200 }
201
Zonr Chang92b344a2010-10-05 20:39:03 +0800202 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700203 };
204
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 bool genScriptClass(Context &C,
206 const std::string &ClassName,
207 std::string &ErrorMsg);
208 void genScriptClassConstructor(Context &C);
209
210 void genInitBoolExportVariable(Context &C,
211 const std::string &VarName,
212 const clang::APValue &Val);
213 void genInitPrimitiveExportVariable(Context &C,
zonr6315f762010-10-05 15:35:14 +0800214 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700215 const clang::APValue &Val);
216 void genInitExportVariable(Context &C,
217 const RSExportType *ET,
218 const std::string &VarName,
219 const clang::APValue &Val);
220 void genExportVariable(Context &C, const RSExportVar *EV);
221 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
222 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
223 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang92b344a2010-10-05 20:39:03 +0800224 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800225 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700226 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV);
227 void genGetExportVariable(Context &C,
228 const std::string &TypeName,
229 const std::string &VarName);
230
231 void genExportFunction(Context &C,
232 const RSExportFunc *EF);
233
234 bool genTypeClass(Context &C,
235 const RSExportRecordType *ERT,
236 std::string &ErrorMsg);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800237 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800238 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
239 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
240 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700241 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT);
242 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT);
243 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT);
244 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
245
246 void genBuildElement(Context &C,
Zonr Chang89273bd2010-10-14 20:57:38 +0800247 const char *ElementBuilderName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700248 const RSExportRecordType *ERT,
Zonr Chang89273bd2010-10-14 20:57:38 +0800249 const char *RenderScriptVar,
250 bool IsInline);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700251 void genAddElementToElementBuilder(Context &C,
252 const RSExportType *ERT,
253 const std::string &VarName,
254 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +0800255 const char *RenderScriptVar,
256 unsigned ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700257 void genAddPaddingToElementBuiler(Context &C,
258 int PaddingSize,
259 const char *ElementBuilderName,
260 const char *RenderScriptVar);
261
262 bool genCreateFieldPacker(Context &C,
263 const RSExportType *T,
264 const char *FieldPackerName);
265 void genPackVarOfType(Context &C,
266 const RSExportType *T,
267 const char *VarName,
268 const char *FieldPackerName);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800269 void genAllocateVarOfType(Context &C,
270 const RSExportType *T,
271 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700272 void genNewItemBufferIfNull(Context &C, const char *Index);
273 void genNewItemBufferPackerIfNull(Context &C);
274
275 public:
zonr6315f762010-10-05 15:35:14 +0800276 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 : mRSContext(Context),
278 mLastError("") {
279 return;
280 }
281
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700282 bool reflect(const std::string &OutputPathBase,
283 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700284 const std::string &InputFileName,
285 const std::string &OutputBCFileName);
286
287 inline const char *getLastError() const {
288 if (mLastError.empty())
289 return NULL;
290 else
291 return mLastError.c_str();
292 }
293}; // class RSReflection
294
295} // namespace slang
296
zonr6315f762010-10-05 15:35:14 +0800297#endif // _SLANG_COMPILER_RS_REFLECTION_H