1 /* 2 * Copyright 2010-2012, 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 setError(const std::string & Error)46 inline void setError(const std::string &Error) { mLastError = Error; } 47 48 class Context { 49 private: 50 static const char *const ApacheLicenseNote; 51 52 bool mVerbose; 53 54 std::string mOutputPathBase; 55 56 std::string mInputRSFile; 57 58 std::string mPackageName; 59 std::string mRSPackageName; 60 std::string mResourceId; 61 std::string mPaddingPrefix; 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 clear()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 // Generated RS Elements for type-checking code. 108 std::set<std::string> mTypesToCheck; 109 110 // Generated FieldPackers for unsigned setters/validation. 111 std::set<std::string> mFieldPackerTypes; 112 113 bool addTypeNameForElement(const std::string &TypeName); 114 bool addTypeNameForFieldPacker(const std::string &TypeName); 115 116 static const char *AccessModifierStr(AccessModifier AM); 117 Context(const std::string & OutputPathBase,const std::string & InputRSFile,const std::string & PackageName,const std::string & RSPackageName,const std::string & ResourceId,const std::string & PaddingPrefix,bool UseStdout)118 Context(const std::string &OutputPathBase, 119 const std::string &InputRSFile, 120 const std::string &PackageName, 121 const std::string &RSPackageName, 122 const std::string &ResourceId, 123 const std::string &PaddingPrefix, 124 bool UseStdout) 125 : mVerbose(true), 126 mOutputPathBase(OutputPathBase), 127 mInputRSFile(InputRSFile), 128 mPackageName(PackageName), 129 mRSPackageName(RSPackageName), 130 mResourceId(ResourceId), 131 mPaddingPrefix(PaddingPrefix), 132 mLicenseNote(ApacheLicenseNote), 133 mUseStdout(UseStdout) { 134 clear(); 135 resetFieldIndex(); 136 clearFieldIndexMap(); 137 return; 138 } 139 out()140 inline std::ostream &out() const { 141 return ((mUseStdout) ? std::cout : mOF); 142 } indent()143 inline std::ostream &indent() const { 144 out() << mIndent; 145 return out(); 146 } 147 incIndentLevel()148 inline void incIndentLevel() { 149 mIndent.append(4, ' '); 150 return; 151 } 152 decIndentLevel()153 inline void decIndentLevel() { 154 slangAssert(getIndentLevel() > 0 && "No indent"); 155 mIndent.erase(0, 4); 156 return; 157 } 158 getIndentLevel()159 inline int getIndentLevel() { return (mIndent.length() >> 2); } 160 getNextExportVarSlot()161 inline int getNextExportVarSlot() { return mNextExportVarSlot++; } 162 getNextExportFuncSlot()163 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; } getNextExportForEachSlot()164 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; } 165 166 // Will remove later due to field name information is not necessary for 167 // C-reflect-to-Java createPaddingField()168 inline std::string createPaddingField() { 169 return mPaddingPrefix + llvm::itostr(mPaddingFieldIndex++); 170 } 171 setLicenseNote(const std::string & LicenseNote)172 inline void setLicenseNote(const std::string &LicenseNote) { 173 mLicenseNote = LicenseNote; 174 } 175 176 bool startClass(AccessModifier AM, 177 bool IsStatic, 178 const std::string &ClassName, 179 const char *SuperClassName, 180 std::string &ErrorMsg); 181 void endClass(); 182 183 void startFunction(AccessModifier AM, 184 bool IsStatic, 185 const char *ReturnType, 186 const std::string &FunctionName, 187 int Argc, ...); 188 189 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 190 void startFunction(AccessModifier AM, 191 bool IsStatic, 192 const char *ReturnType, 193 const std::string &FunctionName, 194 const ArgTy &Args); 195 void endFunction(); 196 197 void startBlock(bool ShouldIndent = false); 198 void endBlock(); 199 getPackageName()200 inline const std::string &getPackageName() const { return mPackageName; } getRSPackageName()201 inline const std::string &getRSPackageName() const { 202 return mRSPackageName; 203 } getClassName()204 inline const std::string &getClassName() const { return mClassName; } getResourceId()205 inline const std::string &getResourceId() const { return mResourceId; } 206 207 void startTypeClass(const std::string &ClassName); 208 void endTypeClass(); 209 incFieldIndex()210 inline void incFieldIndex() { mFieldIndex++; } 211 resetFieldIndex()212 inline void resetFieldIndex() { mFieldIndex = 0; } 213 addFieldIndexMapping(const RSExportRecordType::Field * F)214 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 215 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 216 "Nested structure never occurs in C language."); 217 mFieldIndexMap.insert(std::make_pair(F, mFieldIndex)); 218 } 219 getFieldIndex(const RSExportRecordType::Field * F)220 inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const { 221 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 222 slangAssert((I != mFieldIndexMap.end()) && 223 "Requesting field is out of scope."); 224 return I->second; 225 } 226 clearFieldIndexMap()227 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); } 228 }; 229 230 bool genScriptClass(Context &C, 231 const std::string &ClassName, 232 std::string &ErrorMsg); 233 void genScriptClassConstructor(Context &C); 234 235 static void genInitBoolExportVariable(Context &C, 236 const std::string &VarName, 237 const clang::APValue &Val); 238 static void genInitPrimitiveExportVariable(Context &C, 239 const std::string &VarName, 240 const clang::APValue &Val); 241 static void genInitExportVariable(Context &C, 242 const RSExportType *ET, 243 const std::string &VarName, 244 const clang::APValue &Val); 245 void genExportVariable(Context &C, const RSExportVar *EV); 246 void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV); 247 void genPointerTypeExportVariable(Context &C, const RSExportVar *EV); 248 void genVectorTypeExportVariable(Context &C, const RSExportVar *EV); 249 void genMatrixTypeExportVariable(Context &C, const RSExportVar *EV); 250 void genConstantArrayTypeExportVariable(Context &C, const RSExportVar *EV); 251 void genRecordTypeExportVariable(Context &C, const RSExportVar *EV); 252 void genPrivateExportVariable(Context &C, 253 const std::string &TypeName, 254 const std::string &VarName); 255 void genSetExportVariable(Context &C, 256 const std::string &TypeName, 257 const RSExportVar *EV); 258 void genGetExportVariable(Context &C, 259 const std::string &TypeName, 260 const std::string &VarName); 261 void genGetFieldID(Context &C, 262 const std::string &VarName); 263 264 void genExportFunction(Context &C, 265 const RSExportFunc *EF); 266 267 void genExportForEach(Context &C, 268 const RSExportForEach *EF); 269 270 static void genTypeCheck(Context &C, 271 const RSExportType *ET, 272 const char *VarName); 273 274 static void genTypeInstanceFromPointer(Context &C, 275 const RSExportType *ET); 276 277 static void genTypeInstance(Context &C, 278 const RSExportType *ET); 279 280 static void genFieldPackerInstance(Context &C, 281 const RSExportType *ET); 282 283 bool genTypeClass(Context &C, 284 const RSExportRecordType *ERT, 285 std::string &ErrorMsg); 286 void genTypeItemClass(Context &C, const RSExportRecordType *ERT); 287 void genTypeClassConstructor(Context &C, const RSExportRecordType *ERT); 288 void genTypeClassCopyToArray(Context &C, const RSExportRecordType *ERT); 289 void genTypeClassCopyToArrayLocal(Context &C, const RSExportRecordType *ERT); 290 void genTypeClassItemSetter(Context &C, const RSExportRecordType *ERT); 291 void genTypeClassItemGetter(Context &C, const RSExportRecordType *ERT); 292 void genTypeClassComponentSetter(Context &C, const RSExportRecordType *ERT); 293 void genTypeClassComponentGetter(Context &C, const RSExportRecordType *ERT); 294 void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT); 295 void genTypeClassResize(Context &C); 296 297 void genBuildElement(Context &C, 298 const char *ElementBuilderName, 299 const RSExportRecordType *ERT, 300 const char *RenderScriptVar, 301 bool IsInline); 302 void genAddElementToElementBuilder(Context &C, 303 const RSExportType *ERT, 304 const std::string &VarName, 305 const char *ElementBuilderName, 306 const char *RenderScriptVar, 307 unsigned ArraySize); 308 void genAddPaddingToElementBuiler(Context &C, 309 int PaddingSize, 310 const char *ElementBuilderName, 311 const char *RenderScriptVar); 312 313 bool genCreateFieldPacker(Context &C, 314 const RSExportType *T, 315 const char *FieldPackerName); 316 void genPackVarOfType(Context &C, 317 const RSExportType *T, 318 const char *VarName, 319 const char *FieldPackerName); 320 void genAllocateVarOfType(Context &C, 321 const RSExportType *T, 322 const std::string &VarName); 323 void genNewItemBufferIfNull(Context &C, const char *Index); 324 void genNewItemBufferPackerIfNull(Context &C); 325 326 public: RSReflection(const RSContext * Context,std::vector<std::string> * GeneratedFileNames)327 explicit RSReflection(const RSContext *Context, 328 std::vector<std::string> *GeneratedFileNames) 329 : mRSContext(Context), 330 mLastError(""), 331 mGeneratedFileNames(GeneratedFileNames) { 332 slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames"); 333 return; 334 } 335 336 bool reflect(const std::string &OutputPathBase, 337 const std::string &OutputPackageName, 338 const std::string &RSPackageName, 339 const std::string &InputFileName, 340 const std::string &OutputBCFileName); 341 getLastError()342 inline const char *getLastError() const { 343 if (mLastError.empty()) 344 return NULL; 345 else 346 return mLastError.c_str(); 347 } 348 }; // class RSReflection 349 350 } // namespace slang 351 352 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT 353