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