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