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