blob: 77f01d1ab521d93a41a37abc9bf3b457f276bb78 [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 <cassert>
21#include <fstream>
22#include <iostream>
Stephen Hinese639eb52010-11-08 19:27:20 -080023#include <map>
24#include <string>
25#include <vector>
Shih-wei Liao462aefd2010-06-04 15:32:04 -070026
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_*).
Stephen Hinese639eb52010-11-08 19:27:20 -080072 typedef std::map<const RSExportRecordType::Field*, unsigned>
73 FieldIndexMapTy;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070074 FieldIndexMapTy mFieldIndexMap;
75 // Field index of current processing TypeClass.
76 unsigned mFieldIndex;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -070077
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070078 inline void clear() {
79 mClassName = "";
80 mIndent = "";
81 mPaddingFieldIndex = 1;
82 mNextExportVarSlot = 0;
83 mNextExportFuncSlot = 0;
84 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070085 }
86
Zonr Chang8c6d9b22010-10-07 18:01:19 +080087 bool openClassFile(const std::string &ClassName,
88 std::string &ErrorMsg);
89
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070090 public:
91 typedef enum {
92 AM_Public,
93 AM_Protected,
94 AM_Private
95 } AccessModifier;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070096
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070097 bool mUseStdout;
98 mutable std::ofstream mOF;
99
100 static const char *AccessModifierStr(AccessModifier AM);
101
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700102 Context(const std::string &OutputPathBase,
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800103 const std::string &InputRSFile,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700104 const std::string &PackageName,
105 const std::string &ResourceId,
106 bool UseStdout)
107 : mVerbose(true),
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700108 mOutputPathBase(OutputPathBase),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700109 mInputRSFile(InputRSFile),
110 mPackageName(PackageName),
111 mResourceId(ResourceId),
112 mLicenseNote(ApacheLicenseNote),
113 mUseStdout(UseStdout) {
114 clear();
Zonr Chang66aa2992010-10-05 15:56:31 +0800115 resetFieldIndex();
116 clearFieldIndexMap();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700117 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700118 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700119
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700120 inline std::ostream &out() const {
zonr6315f762010-10-05 15:35:14 +0800121 return ((mUseStdout) ? std::cout : mOF);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 }
123 inline std::ostream &indent() const {
124 out() << mIndent;
125 return out();
126 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700127
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700128 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
Zonr Chang92b344a2010-10-05 20:39:03 +0800139 inline int getIndentLevel() { return (mIndent.length() >> 2); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140
Zonr Chang92b344a2010-10-05 20:39:03 +0800141 inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700142
Zonr Chang92b344a2010-10-05 20:39:03 +0800143 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700144
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
Zonr Chang92b344a2010-10-05 20:39:03 +0800186 inline void incFieldIndex() { mFieldIndex++; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700187
Zonr Chang92b344a2010-10-05 20:39:03 +0800188 inline void resetFieldIndex() { mFieldIndex = 0; }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189
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
Zonr Chang92b344a2010-10-05 20:39:03 +0800203 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700204 };
205
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 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,
zonr6315f762010-10-05 15:35:14 +0800215 const std::string &VarName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700216 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);
Zonr Chang92b344a2010-10-05 20:39:03 +0800225 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800226 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700227 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);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800238 void genTypeItemClass(Context &C, const RSExportRecordType *ERT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800239 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT);
240 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT);
241 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700242 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);
Zonr Changd42a4292010-10-17 02:38:43 +0800246 void genTypeClassResize(Context &C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700247
248 void genBuildElement(Context &C,
Zonr Chang89273bd2010-10-14 20:57:38 +0800249 const char *ElementBuilderName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700250 const RSExportRecordType *ERT,
Zonr Chang89273bd2010-10-14 20:57:38 +0800251 const char *RenderScriptVar,
252 bool IsInline);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700253 void genAddElementToElementBuilder(Context &C,
254 const RSExportType *ERT,
255 const std::string &VarName,
256 const char *ElementBuilderName,
Zonr Chang89273bd2010-10-14 20:57:38 +0800257 const char *RenderScriptVar,
258 unsigned ArraySize);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700259 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);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800271 void genAllocateVarOfType(Context &C,
272 const RSExportType *T,
273 const std::string &VarName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700274 void genNewItemBufferIfNull(Context &C, const char *Index);
275 void genNewItemBufferPackerIfNull(Context &C);
276
277 public:
zonr6315f762010-10-05 15:35:14 +0800278 explicit RSReflection(const RSContext *Context)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700279 : mRSContext(Context),
280 mLastError("") {
281 return;
282 }
283
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700284 bool reflect(const std::string &OutputPathBase,
285 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700286 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
Stephen Hinese639eb52010-11-08 19:27:20 -0800299#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT