1 /* 2 * Copyright 2010-2011, 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 17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT 18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ 19 20 #include <fstream> 21 #include <iostream> 22 #include <map> 23 #include <set> 24 #include <string> 25 #include <vector> 26 27 #include "llvm/ADT/StringExtras.h" 28 29 #include "slang_assert.h" 30 #include "slang_rs_export_type.h" 31 32 namespace slang { 33 34 class RSContext; 35 class RSExportVar; 36 class RSExportFunc; 37 class RSExportForEach; 38 39 class RSReflection { 40 private: 41 const RSContext *mRSContext; 42 43 std::string mLastError; 44 std::vector<std::string> *mGeneratedFileNames; 45 46 inline void setError(const std::string &Error) { mLastError = Error; } 47 48 class Context { 49 private: 50 static const char *const ApacheLicenseNote; 51 52 static const char *const Import[]; 53 54 bool mVerbose; 55 56 std::string mOutputPathBase; 57 58 std::string mInputRSFile; 59 60 std::string mPackageName; 61 std::string mResourceId; 62 63 std::string mClassName; 64 65 std::string mLicenseNote; 66 67 std::string mIndent; 68 69 int mPaddingFieldIndex; 70 71 int mNextExportVarSlot; 72 int mNextExportFuncSlot; 73 int mNextExportForEachSlot; 74 75 // A mapping from a field in a record type to its index in the rsType 76 // instance. Only used when generates TypeClass (ScriptField_*). 77 typedef std::map<const RSExportRecordType::Field*, unsigned> 78 FieldIndexMapTy; 79 FieldIndexMapTy mFieldIndexMap; 80 // Field index of current processing TypeClass. 81 unsigned mFieldIndex; 82 83 inline void clear() { 84 mClassName = ""; 85 mIndent = ""; 86 mPaddingFieldIndex = 1; 87 mNextExportVarSlot = 0; 88 mNextExportFuncSlot = 0; 89 mNextExportForEachSlot = 0; 90 return; 91 } 92 93 bool openClassFile(const std::string &ClassName, 94 std::string &ErrorMsg); 95 96 public: 97 typedef enum { 98 AM_Public, 99 AM_Protected, 100 AM_Private, 101 AM_PublicSynchronized 102 } AccessModifier; 103 104 bool mUseStdout; 105 mutable std::ofstream mOF; 106 107 std::set<std::string> mTypesToCheck; 108 109 static const char *AccessModifierStr(AccessModifier AM); 110 111 Context(const std::string &OutputPathBase, 112 const std::string &InputRSFile, 113 const std::string &PackageName, 114 const std::string &ResourceId, 115 bool UseStdout) 116 : mVerbose(true), 117 mOutputPathBase(OutputPathBase), 118 mInputRSFile(InputRSFile), 119 mPackageName(PackageName), 120 mResourceId(ResourceId), 121 mLicenseNote(ApacheLicenseNote), 122 mUseStdout(UseStdout) { 123 clear(); 124 resetFieldIndex(); 125 clearFieldIndexMap(); 126 return; 127 } 128 129 inline std::ostream &out() const { 130 return ((mUseStdout) ? std::cout : mOF); 131 } 132 inline std::ostream &indent() const { 133 out() << mIndent; 134 return out(); 135 } 136 137 inline void incIndentLevel() { 138 mIndent.append(4, ' '); 139 return; 140 } 141 142 inline void decIndentLevel() { 143 slangAssert(getIndentLevel() > 0 && "No indent"); 144 mIndent.erase(0, 4); 145 return; 146 } 147 148 inline int getIndentLevel() { return (mIndent.length() >> 2); } 149 150 inline int getNextExportVarSlot() { return mNextExportVarSlot++; } 151 152 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; } 153 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; } 154 155 // Will remove later due to field name information is not necessary for 156 // C-reflect-to-Java 157 inline std::string createPaddingField() { 158 return "#padding_" + llvm::itostr(mPaddingFieldIndex++); 159 } 160 161 inline void setLicenseNote(const std::string &LicenseNote) { 162 mLicenseNote = LicenseNote; 163 } 164 165 bool startClass(AccessModifier AM, 166 bool IsStatic, 167 const std::string &ClassName, 168 const char *SuperClassName, 169 std::string &ErrorMsg); 170 void endClass(); 171 172 void startFunction(AccessModifier AM, 173 bool IsStatic, 174 const char *ReturnType, 175 const std::string &FunctionName, 176 int Argc, ...); 177 178 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 179 void startFunction(AccessModifier AM, 180 bool IsStatic, 181 const char *ReturnType, 182 const std::string &FunctionName, 183 const ArgTy &Args); 184 void endFunction(); 185 186 void startBlock(bool ShouldIndent = false); 187 void endBlock(); 188 189 inline const std::string &getPackageName() const { return mPackageName; } 190 inline const std::string &getClassName() const { return mClassName; } 191 inline const std::string &getResourceId() const { return mResourceId; } 192 193 void startTypeClass(const std::string &ClassName); 194 void endTypeClass(); 195 196 inline void incFieldIndex() { mFieldIndex++; } 197 198 inline void resetFieldIndex() { mFieldIndex = 0; } 199 200 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 201 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 202 "Nested structure never occurs in C language."); 203 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex)); 204 } 205 206 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const { 207 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 208 slangAssert((I != mFieldIndexMap.end()) && 209 "Requesting field is out of scope."); 210 return I->second; 211 } 212 213 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); } 214 }; 215 216 bool genScriptClass(Context &C, 217 const std::string &ClassName, 218 std::string &ErrorMsg); 219 void genScriptClassConstructor(Context &C); 220 221 void genInitBoolExportVariable(Context &C, 222 const std::string &VarName, 223 const clang::APValue &Val); 224 void genInitPrimitiveExportVariable(Context &C, 225 const std::string &VarName, 226 const clang::APValue &Val); 227 void genInitExportVariable(Context &C, 228 const RSExportType *ET, 229 const std::string &VarName, 230 const clang::APValue &Val); 231 void genExportVariable(Context &C, const RSExportVar *EV); 232 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV); 233 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV); 234 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV); 235 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV); 236 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV); 237 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV); 238 void genGetExportVariable(Context &C, 239 const std::string &TypeName, 240 const std::string &VarName); 241 242 void genExportFunction(Context &C, 243 const RSExportFunc *EF); 244 245 void genExportForEach(Context &C, 246 const RSExportForEach *EF); 247 248 static void genTypeCheck(Context &C, 249 const RSExportType *ET, 250 const char *VarName); 251 252 static void genTypeInstance(Context &C, 253 const RSExportType *ET); 254 255 bool genTypeClass(Context &C, 256 const RSExportRecordType *ERT, 257 std::string &ErrorMsg); 258 void genTypeItemClass(Context &C, const RSExportRecordType *ERT); 259 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT); 260 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT); 261 void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT); 262 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT); 263 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT); 264 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT); 265 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT); 266 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT); 267 void genTypeClassResize(Context &C); 268 269 void genBuildElement(Context &C, 270 const char *ElementBuilderName, 271 const RSExportRecordType *ERT, 272 const char *RenderScriptVar, 273 bool IsInline); 274 void genAddElementToElementBuilder(Context &C, 275 const RSExportType *ERT, 276 const std::string &VarName, 277 const char *ElementBuilderName, 278 const char *RenderScriptVar, 279 unsigned ArraySize); 280 void genAddPaddingToElementBuiler(Context &C, 281 int PaddingSize, 282 const char *ElementBuilderName, 283 const char *RenderScriptVar); 284 285 bool genCreateFieldPacker(Context &C, 286 const RSExportType *T, 287 const char *FieldPackerName); 288 void genPackVarOfType(Context &C, 289 const RSExportType *T, 290 const char *VarName, 291 const char *FieldPackerName); 292 void genAllocateVarOfType(Context &C, 293 const RSExportType *T, 294 const std::string &VarName); 295 void genNewItemBufferIfNull(Context &C, const char *Index); 296 void genNewItemBufferPackerIfNull(Context &C); 297 298 public: 299 explicit RSReflection(const RSContext *Context, 300 std::vector<std::string> *GeneratedFileNames) 301 : mRSContext(Context), 302 mLastError(""), 303 mGeneratedFileNames(GeneratedFileNames) { 304 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames"); 305 return; 306 } 307 308 bool reflect(const std::string &OutputPathBase, 309 const std::string &OutputPackageName, 310 const std::string &InputFileName, 311 const std::string &OutputBCFileName); 312 313 inline const char *getLastError() const { 314 if (mLastError.empty()) 315 return NULL; 316 else 317 return mLastError.c_str(); 318 } 319 }; // class RSReflection 320 321 } // namespace slang 322 323 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT 324