aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-28 18:08:57 -0700
committerStephen Hines <srhines@google.com>2013-08-29 18:24:29 -0700
commit80706836b18127b5733d790613a5d1b9f97cbb1d (patch)
treefd02b533657e8409a1b407ae8a8edbeed5ce973a
parent8de1922e037612f2521acac2f4c4289a9f71450d (diff)
downloadslang-kitkat-cts-dev.tar.gz
Bug: 10427951 This also fixes a bug with floating point initialization (where relevant digits could be truncated because of C++ iostream operators). Change-Id: I2761dea38dd6ad758ea31217744e45436596afce
-rw-r--r--slang_rs_reflection.cpp4
-rw-r--r--slang_rs_reflection.h1
-rw-r--r--slang_rs_reflection_base.cpp27
-rw-r--r--slang_rs_reflection_base.h2
-rw-r--r--slang_rs_reflection_cpp.cpp162
-rw-r--r--slang_rs_reflection_cpp.h13
-rw-r--r--tests/P_kernel_cpp/kernel_cpp.rs8
7 files changed, 205 insertions, 12 deletions
diff --git a/slang_rs_reflection.cpp b/slang_rs_reflection.cpp
index 772545b..65b6b43 100644
--- a/slang_rs_reflection.cpp
+++ b/slang_rs_reflection.cpp
@@ -424,10 +424,10 @@ void RSReflection::genInitBoolExportVariable(Context &C,
const std::string &VarName,
const clang::APValue &Val) {
slangAssert(!Val.isUninit() && "Not a valid initializer");
+ slangAssert((Val.getKind() == clang::APValue::Int)
+ && "Bool type has wrong initial APValue");
C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
- slangAssert((Val.getKind() == clang::APValue::Int) &&
- "Bool type has wrong initial APValue");
C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
<< ";" << std::endl;
diff --git a/slang_rs_reflection.h b/slang_rs_reflection.h
index ded42b4..b309325 100644
--- a/slang_rs_reflection.h
+++ b/slang_rs_reflection.h
@@ -242,7 +242,6 @@ class RSReflection {
const RSExportType *ET,
const std::string &VarName,
const clang::APValue &Val);
- static void genInitValue(Context &C, const clang::APValue &Val);
void genExportVariable(Context &C, const RSExportVar *EV);
void genPrimitiveTypeExportVariable(Context &C, const RSExportVar *EV);
void genPointerTypeExportVariable(Context &C, const RSExportVar *EV);
diff --git a/slang_rs_reflection_base.cpp b/slang_rs_reflection_base.cpp
index fe93054..7f1aa96 100644
--- a/slang_rs_reflection_base.cpp
+++ b/slang_rs_reflection_base.cpp
@@ -20,6 +20,7 @@
#include <cctype>
#include <algorithm>
+#include <limits>
#include <sstream>
#include <string>
#include <utility>
@@ -161,6 +162,7 @@ string RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
if(asBool) {
tmp << ((api.getSExtValue() == 0) ? "false" : "true");
} else {
+ // TODO: Handle unsigned possibly for C++ API.
tmp << api.getSExtValue();
if (api.getBitWidth() > 32) {
tmp << "L";
@@ -171,10 +173,15 @@ string RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
case clang::APValue::Float: {
llvm::APFloat apf = Val.getFloat();
+ llvm::SmallString<30> s;
+ apf.toString(s);
+ tmp << s.c_str();
if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
- tmp << apf.convertToFloat() << "f";
- } else {
- tmp << apf.convertToDouble();
+ if (s.count('.') == 0) {
+ tmp << ".f";
+ } else {
+ tmp << "f";
+ }
}
break;
}
@@ -204,4 +211,18 @@ bool RSReflectionBase::addTypeNameForElement(
}
}
+const char *RSReflectionBase::getVectorAccessor(unsigned Index) {
+ static const char *VectorAccessorMap[] = {
+ /* 0 */ "x",
+ /* 1 */ "y",
+ /* 2 */ "z",
+ /* 3 */ "w",
+ };
+
+ slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
+ "Out-of-bound index to access vector member");
+
+ return VectorAccessorMap[Index];
+}
+
}
diff --git a/slang_rs_reflection_base.h b/slang_rs_reflection_base.h
index 100f5eb..3383ad1 100644
--- a/slang_rs_reflection_base.h
+++ b/slang_rs_reflection_base.h
@@ -70,6 +70,8 @@ protected:
bool addTypeNameForElement(const std::string &TypeName);
+ static const char *getVectorAccessor(unsigned index);
+
private:
public:
diff --git a/slang_rs_reflection_cpp.cpp b/slang_rs_reflection_cpp.cpp
index ea4227d..f583148 100644
--- a/slang_rs_reflection_cpp.cpp
+++ b/slang_rs_reflection_cpp.cpp
@@ -173,9 +173,11 @@ bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
E = mRSContext->export_vars_end(); I != E; I++, slot++) {
const RSExportVar *ev = *I;
if (!ev->isConst()) {
- write(GetTypeName(ev->getType()) + " __" + ev->getName() + ";");
+ write(GetTypeName(ev->getType()) + " " RS_EXPORT_VAR_PREFIX
+ + ev->getName() + ";");
}
}
+
for (RSContext::const_export_foreach_iterator
I = mRSContext->export_foreach_begin(),
E = mRSContext->export_foreach_end(); I != E; I++) {
@@ -319,6 +321,7 @@ bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
<< stripRS(mInputFileName) << "\", " << stripRS(mInputFileName).length()
<< ", \"/data/data/" << packageName << "/app\", sizeof(\"" << packageName << "\")) {";
write(ss);
+ ss.str("");
incIndent();
for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
E = mTypesToCheck.end();
@@ -326,6 +329,18 @@ bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
I++) {
write(RS_ELEM_PREFIX + *I + " = android::RSC::Element::" + *I + "(mRS);");
}
+
+ for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
+ E = mRSContext->export_vars_end();
+ I != E;
+ I++) {
+ const RSExportVar *EV = *I;
+ if (!EV->getInit().isUninit()) {
+ genInitExportVariable(EV->getType(), EV->getName(), EV->getInit());
+ } else {
+ genZeroInitExportVariable(EV->getName());
+ }
+ }
decIndent();
write("}");
write("");
@@ -499,7 +514,7 @@ void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
stringstream tmp;
tmp << getNextExportVarSlot();
write(string(" setVar(") + tmp.str() + ", &v, sizeof(v));");
- write(string(" __") + EV->getName() + " = v;");
+ write(string(" " RS_EXPORT_VAR_PREFIX) + EV->getName() + " = v;");
write("}");
}
write(string(rtd.type->c_name) + " get_" + EV->getName() + "() const {");
@@ -508,7 +523,7 @@ void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) {
bool isBool = !strcmp(rtd.type->c_name, "bool");
write(string(" return ") + genInitValue(val, isBool) + ";");
} else {
- write(string(" return __") + EV->getName() + ";");
+ write(string(" return " RS_EXPORT_VAR_PREFIX) + EV->getName() + ";");
}
write("}");
write("");
@@ -533,7 +548,7 @@ void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
stringstream tmp;
tmp << slot;
write(string(" bindAllocation(v, ") + tmp.str() + ");");
- write(string(" __") + VarName + " = v;");
+ write(string(" " RS_EXPORT_VAR_PREFIX) + VarName + " = v;");
write("}");
}
write(TypeName + " get_" + VarName + "() const {");
@@ -542,7 +557,7 @@ void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
bool isBool = !strcmp(TypeName.c_str(), "bool");
write(string(" return ") + genInitValue(val, isBool) + ";");
} else {
- write(string(" return __") + VarName + ";");
+ write(string(" return " RS_EXPORT_VAR_PREFIX) + VarName + ";");
}
write("}");
write("");
@@ -550,7 +565,41 @@ void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) {
}
void RSReflectionCpp::genVectorTypeExportVariable(const RSExportVar *EV) {
- slangAssert(false);
+ slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
+ "Variable should be type of vector here");
+
+ const RSExportVectorType *EVT =
+ static_cast<const RSExportVectorType*>(EV->getType());
+ slangAssert(EVT != NULL);
+
+ RSReflectionTypeData rtd;
+ EVT->convertToRTD(&rtd);
+
+ std::stringstream ss;
+
+ if (!EV->isConst()) {
+ ss << "void set_" << EV->getName() << "(" << rtd.type->rs_c_vector_prefix
+ << EVT->getNumElement() << " v) {";
+ write(ss);
+ ss.str("");
+ ss << getNextExportVarSlot();
+ write(string(" setVar(") + ss.str() + ", &v, sizeof(v));");
+ ss.str("");
+ write(string(" " RS_EXPORT_VAR_PREFIX) + EV->getName() + " = v;");
+ write("}");
+ }
+ ss << rtd.type->rs_c_vector_prefix << EVT->getNumElement() << " get_"
+ << EV->getName() << "() const {";
+ write(ss);
+ ss.str("");
+ if (EV->isConst()) {
+ const clang::APValue &val = EV->getInit();
+ write(string(" return ") + genInitValue(val, false) + ";");
+ } else {
+ write(string(" return " RS_EXPORT_VAR_PREFIX) + EV->getName() + ";");
+ }
+ write("}");
+ write("");
}
void RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) {
@@ -802,6 +851,107 @@ void RSReflectionCpp::genTypeInstance(const RSExportType *ET) {
}
}
+void RSReflectionCpp::genInitExportVariable(const RSExportType *ET,
+ const std::string &VarName,
+ const clang::APValue &Val) {
+ slangAssert(!Val.isUninit() && "Not a valid initializer");
+ switch (ET->getClass()) {
+ case RSExportType::ExportClassPrimitive: {
+ const RSExportPrimitiveType *EPT =
+ static_cast<const RSExportPrimitiveType*>(ET);
+ if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
+ genInitBoolExportVariable(VarName, Val);
+ } else {
+ genInitPrimitiveExportVariable(VarName, Val);
+ }
+ break;
+ }
+ case RSExportType::ExportClassPointer: {
+ if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
+ std::cerr << "Initializer which is non-NULL to pointer type variable "
+ "will be ignored" << std::endl;
+ break;
+ }
+ case RSExportType::ExportClassVector: {
+ const RSExportVectorType *EVT =
+ static_cast<const RSExportVectorType*>(ET);
+ switch (Val.getKind()) {
+ case clang::APValue::Int:
+ case clang::APValue::Float: {
+ for (unsigned i = 0; i < EVT->getNumElement(); i++) {
+ std::string Name = VarName + "." + getVectorAccessor(i);
+ genInitPrimitiveExportVariable(Name, Val);
+ }
+ break;
+ }
+ case clang::APValue::Vector: {
+ unsigned NumElements =
+ std::min(static_cast<unsigned>(EVT->getNumElement()),
+ Val.getVectorLength());
+ for (unsigned i = 0; i < NumElements; i++) {
+ const clang::APValue &ElementVal = Val.getVectorElt(i);
+ std::string Name = VarName + "." + getVectorAccessor(i);
+ genInitPrimitiveExportVariable(Name, ElementVal);
+ }
+ break;
+ }
+ case clang::APValue::MemberPointer:
+ case clang::APValue::Uninitialized:
+ case clang::APValue::ComplexInt:
+ case clang::APValue::ComplexFloat:
+ case clang::APValue::LValue:
+ case clang::APValue::Array:
+ case clang::APValue::Struct:
+ case clang::APValue::Union:
+ case clang::APValue::AddrLabelDiff: {
+ slangAssert(false && "Unexpected type of value of initializer.");
+ }
+ }
+ break;
+ }
+ case RSExportType::ExportClassMatrix:
+ case RSExportType::ExportClassConstantArray:
+ case RSExportType::ExportClassRecord: {
+ slangAssert(false && "Unsupported initializer for record/matrix/constant "
+ "array type variable currently");
+ break;
+ }
+ default: {
+ slangAssert(false && "Unknown class of type");
+ }
+ }
+ return;
+}
+
+void RSReflectionCpp::genZeroInitExportVariable(const std::string &VarName) {
+ std::stringstream ss;
+ ss << "memset(&" RS_EXPORT_VAR_PREFIX << VarName << ", 0, sizeof("
+ << RS_EXPORT_VAR_PREFIX << VarName << "));";
+ write(ss);
+}
+
+void RSReflectionCpp::genInitPrimitiveExportVariable(
+ const std::string &VarName,
+ const clang::APValue &Val) {
+ slangAssert(!Val.isUninit() && "Not a valid initializer");
+
+ std::stringstream ss;
+ ss << RS_EXPORT_VAR_PREFIX << VarName << " = "
+ << RSReflectionBase::genInitValue(Val) << ";";
+ write(ss);
+}
+
+void RSReflectionCpp::genInitBoolExportVariable(const std::string &VarName,
+ const clang::APValue &Val) {
+ slangAssert(!Val.isUninit() && "Not a valid initializer");
+ slangAssert((Val.getKind() == clang::APValue::Int) &&
+ "Bool type has wrong initial APValue");
+
+ std::stringstream ss;
+ ss << RS_EXPORT_VAR_PREFIX << VarName << " = "
+ << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") << ";";
+ write(ss);
+}
} // namespace slang
diff --git a/slang_rs_reflection_cpp.h b/slang_rs_reflection_cpp.h
index 948d624..b887ee7 100644
--- a/slang_rs_reflection_cpp.h
+++ b/slang_rs_reflection_cpp.h
@@ -22,6 +22,8 @@
#include <set>
#include <string>
+#define RS_EXPORT_VAR_PREFIX "mExportVar_"
+
namespace slang {
class RSReflectionCpp : public RSReflectionBase {
@@ -66,6 +68,17 @@ class RSReflectionCpp : public RSReflectionBase {
bool startScriptHeader();
+
+ // Write out code for an export variable initialization.
+ void genInitExportVariable(const RSExportType *ET,
+ const std::string &VarName,
+ const clang::APValue &Val);
+ void genZeroInitExportVariable(const std::string &VarName);
+ void genInitBoolExportVariable(const std::string &VarName,
+ const clang::APValue &Val);
+ void genInitPrimitiveExportVariable(const std::string &VarName,
+ const clang::APValue &Val);
+
// Produce an argument string of the form "T1 t, T2 u, T3 v".
void makeArgs(std::stringstream &ss, const ArgTy& Args);
diff --git a/tests/P_kernel_cpp/kernel_cpp.rs b/tests/P_kernel_cpp/kernel_cpp.rs
index 4474c9f..2a854c2 100644
--- a/tests/P_kernel_cpp/kernel_cpp.rs
+++ b/tests/P_kernel_cpp/kernel_cpp.rs
@@ -2,6 +2,14 @@
#pragma version(1)
#pragma rs java_package_name(foo)
+//int2 i2;
+
+int i1 = 5;
+bool bt = true;
+bool bf = false;
+int2 i2 = 2;
+int3 i3 = {1, 2, 3};
+
int __attribute__((kernel)) root(uint32_t ain) {
return 0;
}