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