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>
231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <sstream>
241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <string>
251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include <utility>
261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "os_sep.h"
281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_context.h"
291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_var.h"
301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_foreach.h"
311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_export_func.h"
321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflect_utils.h"
331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_version.h"
341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_utils.h"
351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams#include "slang_rs_reflection_base.h"
371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsusing namespace std;
411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsnamespace slang {
431b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
441b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsstatic const char *const gApacheLicenseNote =
451b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams"/*\n"
461b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Copyright (C) 2012 The Android Open Source Project\n"
471b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n"
481b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
491b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * you may not use this file except in compliance with the License.\n"
501b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * You may obtain a copy of the License at\n"
511b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n"
521b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *      http://www.apache.org/licenses/LICENSE-2.0\n"
531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" *\n"
541b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * Unless required by applicable law or agreed to in writing, software\n"
551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
561b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
571b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * See the License for the specific language governing permissions and\n"
581b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" * limitations under the License.\n"
591b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams" */\n"
601b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams"\n";
611b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
621b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
631b6a0883cd6984e11e59b0c847fb334df1f41afcJason SamsRSReflectionBase::RSReflectionBase(const RSContext *con) {
64192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  mRSContext = con;
65192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  mLicenseNote = gApacheLicenseNote;
661b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
671b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
681b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
691b6a0883cd6984e11e59b0c847fb334df1f41afcJason SamsRSReflectionBase::~RSReflectionBase() {
701b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
711b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
721b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
731b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams/*
741b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsbool RSReflectionBase::openFile(const string &name, string &errorMsg) {
751b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    if(!mUseStdout) {
761b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        mOF.clear();
771b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        if(!SlangUtils::CreateDirectoryWithParents(mOutputPath, &errorMsg)) {
781b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams            return false;
791b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        }
801b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
811b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        string cf(mOutputPath + OS_PATH_SEPARATOR_STR + name);
821b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        mOF.open(cf.c_str());
831b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        if(!mOF.good()) {
841b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams            errorMsg = "failed to open file '" + cf + "' for write";
851b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams            return false;
861b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams        }
871b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
881b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    return true;
891b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams*/
911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::startFile(const string &filename) {
93192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  if(mVerbose) {
94192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    printf("Generating %s\n", filename.c_str());
95192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  }
96192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
97192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  // License
98192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write(mLicenseNote);
99192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
100192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  // Notice of generated file
101192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write("/*");
102192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write(" * This file is auto-generated. DO NOT MODIFY!");
103192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write(" * The source Renderscript file: " + mInputFileName);
104192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write(" */");
105192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  write("");
1061b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1071b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsstring RSReflectionBase::stripRS(const string &s) const {
109192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  size_t pos = s.rfind(".rs");
110192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  if(pos != string::npos) {
111192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    string tmp(s);
112192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    tmp.erase(pos);
113192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    return tmp;
114192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  }
115192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  return s;
1161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::write(const std::string &t) {
119192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  //printf("%s%s\n", mIndent.c_str(), t.c_str());
120192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  mText.push_back(mIndent + t);
121192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams}
122192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
123192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Samsvoid RSReflectionBase::write(const std::stringstream &t) {
124192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  mText.push_back(mIndent + t.str());
1251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::incIndent() {
1291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams  mIndent.append("    ");
1301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSReflectionBase::decIndent() {
1331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams  mIndent.erase(0, 4);
1341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsbool RSReflectionBase::writeFile(const string &filename, const vector< string > &txt) {
137192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  FILE *pfin = fopen(filename.c_str(), "wt");
138192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  if (pfin == NULL) {
139192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    fprintf(stderr, "Error: could not write file %s\n", filename.c_str());
140192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    return false;
141192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  }
142192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
143192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  for(size_t ct=0; ct < txt.size(); ct++) {
144192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    fprintf(pfin, "%s\n", txt[ct].c_str());
145192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  }
146192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  fclose(pfin);
147192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  return true;
148192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams}
149192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
150192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
151192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Samsstring RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
152192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  stringstream tmp;
153192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  switch (Val.getKind()) {
154192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::Int: {
155192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      llvm::APInt api = Val.getInt();
156192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      if(asBool) {
157192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        tmp << ((api.getSExtValue() == 0) ? "false" : "true");
158192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      } else {
159192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        tmp << api.getSExtValue();
160192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        if (api.getBitWidth() > 32) {
161192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams          tmp << "L";
162192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        }
163192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      }
164192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      break;
1651b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
1661b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
167192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::Float: {
168192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      llvm::APFloat apf = Val.getFloat();
169192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
170192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        tmp << apf.convertToFloat() << "f";
171192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      } else {
172192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams        tmp << apf.convertToDouble();
173192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      }
174192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      break;
1751b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams    }
176192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
177192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::ComplexInt:
178192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::ComplexFloat:
179192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::LValue:
180192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    case clang::APValue::Vector: {
181192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      slangAssert(false && "Primitive type cannot have such kind of initializer");
182192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      break;
183192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    }
184192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams
185192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    default: {
186192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams      slangAssert(false && "Unknown kind of initializer");
187192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams    }
188192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  }
189192392fc5ffedc06eb8ae2b89d703b3c658fddd6Jason Sams  return tmp.str();
1901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
1911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams
1931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams}
194