11b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/* 21b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Copyright 2012, The Android Open Source Project 31b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 41b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 51b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * you may not use this file except in compliance with the License. 61b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * You may obtain a copy of the License at 71b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 81b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * http://www.apache.org/licenses/LICENSE-2.0 91b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * 101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * Unless required by applicable law or agreed to in writing, software 111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * See the License for the specific language governing permissions and 141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams * limitations under the License. 151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams */ 161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sys/stat.h> 181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <cstdarg> 201b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <cctype> 211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <algorithm> 2380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines#include <limits> 241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sstream> 251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <string> 261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <utility> 271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "os_sep.h" 291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_context.h" 301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_var.h" 311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_foreach.h" 321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_func.h" 331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflect_utils.h" 341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_version.h" 351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_utils.h" 361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflection_base.h" 381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsusing namespace std; 421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 431b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsnamespace slang { 441b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 451b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsstatic const char *const gApacheLicenseNote = 461b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams"/*\n" 471b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Copyright (C) 2012 The Android Open Source Project\n" 481b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n" 491b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 501b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * you may not use this file except in compliance with the License.\n" 511b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * You may obtain a copy of the License at\n" 521b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n" 531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * http://www.apache.org/licenses/LICENSE-2.0\n" 541b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n" 551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Unless required by applicable law or agreed to in writing, software\n" 561b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 571b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 581b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * See the License for the specific language governing permissions and\n" 591b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * limitations under the License.\n" 601b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" */\n" 611b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams"\n"; 621b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 631b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 64925879fa622dda293806ed25b1ee63d2f4a8d65aStephen HinesRSReflectionBase::RSReflectionBase(const RSContext *con) 65925879fa622dda293806ed25b1ee63d2f4a8d65aStephen Hines : mVerbose(true) { 66192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams mRSContext = con; 67192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams mLicenseNote = gApacheLicenseNote; 681b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 691b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 701b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 711b6a0883cd6984e11e59b0c847fb334df1f41afcJason SamsRSReflectionBase::~RSReflectionBase() { 721b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 731b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 741b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 751b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/* 761b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsbool RSReflectionBase::openFile(const string &name, string &errorMsg) { 771b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams if(!mUseStdout) { 781b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams mOF.clear(); 791b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams if(!SlangUtils::CreateDirectoryWithParents(mOutputPath, &errorMsg)) { 801b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return false; 811b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 821b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 831b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams string cf(mOutputPath + OS_PATH_SEPARATOR_STR + name); 841b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams mOF.open(cf.c_str()); 851b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams if(!mOF.good()) { 861b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams errorMsg = "failed to open file '" + cf + "' for write"; 871b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return false; 881b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 891b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return true; 911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams*/ 931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 941b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::startFile(const string &filename) { 95192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if(mVerbose) { 96192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams printf("Generating %s\n", filename.c_str()); 97192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 98192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 99192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams // License 100192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write(mLicenseNote); 101192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 102192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams // Notice of generated file 103192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write("/*"); 104192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write(" * This file is auto-generated. DO NOT MODIFY!"); 105192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write(" * The source Renderscript file: " + mInputFileName); 106192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write(" */"); 107192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams write(""); 1081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 1091b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 110b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray// remove path plus .rs from filename to generate class name 1111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsstring RSReflectionBase::stripRS(const string &s) const { 112b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray string tmp(s); 113b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray size_t pos = tmp.rfind(".rs"); 114192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if(pos != string::npos) { 115192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams tmp.erase(pos); 116192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 117b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray pos = tmp.rfind("/"); 118b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray if (pos != string::npos) { 119b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray tmp.erase(0, pos+1); 120b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray } 121b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray return tmp; 1221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 1231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::write(const std::string &t) { 125192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams //printf("%s%s\n", mIndent.c_str(), t.c_str()); 126192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams mText.push_back(mIndent + t); 127192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams} 128192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 129192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Samsvoid RSReflectionBase::write(const std::stringstream &t) { 130192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams mText.push_back(mIndent + t.str()); 1311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 1321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::incIndent() { 1351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams mIndent.append(" "); 1361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 1371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::decIndent() { 1391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams mIndent.erase(0, 4); 1401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 1411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsbool RSReflectionBase::writeFile(const string &filename, const vector< string > &txt) { 143b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray FILE *pfin = fopen((mOutputPath + filename).c_str(), "wt"); 144192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if (pfin == NULL) { 145192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams fprintf(stderr, "Error: could not write file %s\n", filename.c_str()); 146192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams return false; 147192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 148192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 149192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams for(size_t ct=0; ct < txt.size(); ct++) { 150192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams fprintf(pfin, "%s\n", txt[ct].c_str()); 151192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 152192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams fclose(pfin); 153192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams return true; 154192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams} 155192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 156192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 157192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Samsstring RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) { 158192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams stringstream tmp; 159192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams switch (Val.getKind()) { 160192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::Int: { 161192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams llvm::APInt api = Val.getInt(); 162192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if(asBool) { 163192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams tmp << ((api.getSExtValue() == 0) ? "false" : "true"); 164192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } else { 16580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines // TODO: Handle unsigned possibly for C++ API. 166192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams tmp << api.getSExtValue(); 167192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if (api.getBitWidth() > 32) { 168192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams tmp << "L"; 169192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 170192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 171192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams break; 1721b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 1731b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 174192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::Float: { 175192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams llvm::APFloat apf = Val.getFloat(); 17680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines llvm::SmallString<30> s; 17780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines apf.toString(s); 17880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines tmp << s.c_str(); 179192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) { 18080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines if (s.count('.') == 0) { 18180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines tmp << ".f"; 18280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines } else { 18380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines tmp << "f"; 18480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines } 185192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 186192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams break; 1871b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 188192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 189192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::ComplexInt: 190192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::ComplexFloat: 191192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::LValue: 192192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams case clang::APValue::Vector: { 193192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams slangAssert(false && "Primitive type cannot have such kind of initializer"); 194192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams break; 195192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 196192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams 197192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams default: { 198192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams slangAssert(false && "Unknown kind of initializer"); 199192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 200192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams } 201192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams return tmp.str(); 2021b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 2031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 204003ac666e57669d4312b5792068c3db302ee7b84Stephen Hinesbool RSReflectionBase::addTypeNameForElement( 205003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines const std::string &TypeName) { 206003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) { 207003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines mTypesToCheck.insert(TypeName); 208003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines return true; 209003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines } else { 210003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines return false; 211003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines } 212003ac666e57669d4312b5792068c3db302ee7b84Stephen Hines} 2131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 21480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hinesconst char *RSReflectionBase::getVectorAccessor(unsigned Index) { 21580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines static const char *VectorAccessorMap[] = { 21680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines /* 0 */ "x", 21780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines /* 1 */ "y", 21880706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines /* 2 */ "z", 21980706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines /* 3 */ "w", 22080706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines }; 22180706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines 22280706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && 22380706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines "Out-of-bound index to access vector member"); 22480706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines 22580706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines return VectorAccessorMap[Index]; 22680706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines} 22780706836b18127b5733d790613a5d1b9f97cbb1dStephen Hines 2281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 229