am aabf3b45: Explicitly set DataLayout for 32-bit.
* commit 'aabf3b45a05d80949fdb0551feb1f59754f3742a':
Explicitly set DataLayout for 32-bit.
diff --git a/Android.mk b/Android.mk
index ee0f7a4..c1745a8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,7 +19,8 @@
ifeq ($(TARGET_BUILD_APPS),)
-local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter -Wno-return-type -Werror
+local_cflags_for_slang := -Wno-sign-promo -Wall -Wno-unused-parameter \
+ -Wno-return-type -Werror -std=c++11
ifeq ($(TARGET_BUILD_VARIANT),eng)
local_cflags_for_slang += -O0
else
@@ -69,7 +70,6 @@
LOCAL_SRC_FILES := \
slang.cpp \
- slang_utils.cpp \
slang_backend.cpp \
slang_pragma_recorder.cpp \
slang_diagnostic_buffer.cpp
@@ -78,7 +78,7 @@
LOCAL_LDLIBS := -ldl -lpthread
ifneq ($(HOST_OS),windows)
-LOCAL_LDLIBS += -lc++
+LOCAL_CXX_STL := libc++
endif
include $(CLANG_HOST_BUILD_MK)
@@ -157,6 +157,8 @@
slang_rs_reflect_utils.cpp \
strip_unknown_attributes.cpp
+LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
+
LOCAL_STATIC_LIBRARIES := \
libslang \
$(static_libraries_needed_by_slang)
diff --git a/llvm-rs-as.cpp b/llvm-rs-as.cpp
index b176002..1f81b14 100644
--- a/llvm-rs-as.cpp
+++ b/llvm-rs-as.cpp
@@ -87,12 +87,12 @@
}
}
- std::string ErrorInfo;
+ std::error_code EC;
std::unique_ptr<tool_output_file> Out
- (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
- llvm::sys::fs::F_None));
- if (!ErrorInfo.empty()) {
- errs() << ErrorInfo << '\n';
+ (new tool_output_file(OutputFilename.c_str(), EC, llvm::sys::fs::F_None));
+ if (EC) {
+ // TODO(srhines): This isn't actually very specific and needs cleanup.
+ errs() << EC.message() << '\n';
exit(1);
}
@@ -127,7 +127,7 @@
// Parse the file now...
SMDiagnostic Err;
- std::unique_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
+ std::unique_ptr<Module> M(parseAssemblyFile(InputFilename, Err, Context));
if (M.get() == 0) {
Err.print(argv[0], errs());
return 1;
diff --git a/rs_version.mk b/rs_version.mk
index 909496a..d824bcc 100644
--- a/rs_version.mk
+++ b/rs_version.mk
@@ -14,7 +14,7 @@
# limitations under the License.
#
-RS_VERSION := 22
+RS_VERSION := 23
RS_VERSION_DEFINE := -DRS_VERSION=$(RS_VERSION)
# Use RS_VERSION_DEFINE as part of your LOCAL_CFLAGS to have the proper value.
diff --git a/slang.cpp b/slang.cpp
index 039b17a..731e671 100644
--- a/slang.cpp
+++ b/slang.cpp
@@ -68,32 +68,12 @@
#include "slang_assert.h"
#include "slang_backend.h"
-#include "slang_utils.h"
namespace {
static const char *kRSTriple32 = "armv7-none-linux-gnueabi";
static const char *kRSTriple64 = "aarch64-none-linux-gnueabi";
-struct ForceSlangLinking {
- ForceSlangLinking() {
- // We must reference the functions in such a way that compilers will not
- // delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- if (std::getenv("bar") != reinterpret_cast<char*>(-1))
- return;
-
- // llvm-rs-link needs following functions existing in libslang.
- llvm::parseBitcodeFile(NULL, llvm::getGlobalContext());
- llvm::Linker::LinkModules(NULL, NULL, 0, NULL);
-
- // llvm-rs-cc need this.
- new clang::TextDiagnosticPrinter(llvm::errs(),
- new clang::DiagnosticOptions());
- }
-} ForceSlangLinking;
-
} // namespace
namespace slang {
@@ -113,40 +93,34 @@
static inline llvm::tool_output_file *
OpenOutputFile(const char *OutputFile,
llvm::sys::fs::OpenFlags Flags,
- std::string* Error,
+ std::error_code &EC,
clang::DiagnosticsEngine *DiagEngine) {
- slangAssert((OutputFile != NULL) && (Error != NULL) &&
- (DiagEngine != NULL) && "Invalid parameter!");
+ slangAssert((OutputFile != nullptr) &&
+ (DiagEngine != nullptr) && "Invalid parameter!");
- if (SlangUtils::CreateDirectoryWithParents(
- llvm::sys::path::parent_path(OutputFile), Error)) {
+ EC = llvm::sys::fs::create_directories(
+ llvm::sys::path::parent_path(OutputFile));
+ if (!EC) {
llvm::tool_output_file *F =
- new llvm::tool_output_file(OutputFile, *Error, Flags);
- if (F != NULL)
+ new llvm::tool_output_file(OutputFile, EC, Flags);
+ if (F != nullptr)
return F;
}
// Report error here.
DiagEngine->Report(clang::diag::err_fe_error_opening)
- << OutputFile << *Error;
+ << OutputFile << EC.message();
- return NULL;
+ return nullptr;
}
void Slang::GlobalInitialization() {
if (!GlobalInitialized) {
- // We only support x86, x64 and ARM target
- // For ARM
LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget();
LLVMInitializeARMAsmPrinter();
- // For x86 and x64
- LLVMInitializeX86TargetInfo();
- LLVMInitializeX86Target();
- LLVMInitializeX86AsmPrinter();
-
// Please refer to include/clang/Basic/LangOptions.h to setup
// the options.
LangOpts.RTTI = 0; // Turn off the RTTI information support
@@ -213,7 +187,7 @@
*mSourceMgr,
*HeaderInfo,
*this,
- NULL,
+ nullptr,
/* OwnsHeaderSearch = */true));
// Initialize the preprocessor
mPP->Initialize(getTargetInfo());
@@ -258,7 +232,7 @@
&mPragmas, OS, OT);
}
-Slang::Slang() : mInitialized(false), mDiagClient(NULL),
+Slang::Slang() : mInitialized(false), mDiagClient(nullptr),
mTargetOpts(new clang::TargetOptions()), mOT(OT_Default) {
GlobalInitialization();
}
@@ -299,9 +273,9 @@
mSourceMgr->clearIDTables();
// Load the source
- llvm::MemoryBuffer *SB =
+ std::unique_ptr<llvm::MemoryBuffer> SB =
llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
- mSourceMgr->setMainFileID(mSourceMgr->createFileID(SB));
+ mSourceMgr->setMainFileID(mSourceMgr->createFileID(std::move(SB)));
if (mSourceMgr->getMainFileID().isInvalid()) {
mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
@@ -330,15 +304,14 @@
}
bool Slang::setOutput(const char *OutputFile) {
- std::string Error;
- llvm::tool_output_file *OS = NULL;
+ std::error_code EC;
+ llvm::tool_output_file *OS = nullptr;
switch (mOT) {
case OT_Dependency:
case OT_Assembly:
case OT_LLVMAssembly: {
- OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, &Error,
- mDiagEngine);
+ OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine);
break;
}
case OT_Nothing: {
@@ -346,8 +319,7 @@
}
case OT_Object:
case OT_Bitcode: {
- OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None,
- &Error, mDiagEngine);
+ OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None, EC, mDiagEngine);
break;
}
default: {
@@ -355,7 +327,7 @@
}
}
- if (!Error.empty())
+ if (EC)
return false;
mOS.reset(OS);
@@ -366,11 +338,11 @@
}
bool Slang::setDepOutput(const char *OutputFile) {
- std::string Error;
+ std::error_code EC;
mDOS.reset(
- OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, &Error, mDiagEngine));
- if (!Error.empty() || (mDOS.get() == NULL))
+ OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine));
+ if (EC || (mDOS.get() == nullptr))
return false;
mDepOutputFileName = OutputFile;
@@ -381,7 +353,7 @@
int Slang::generateDepFile() {
if (mDiagEngine->hasErrorOccurred())
return 1;
- if (mDOS.get() == NULL)
+ if (mDOS.get() == nullptr)
return 1;
// Initialize options for generating dependency file
@@ -428,7 +400,7 @@
int Slang::compile() {
if (mDiagEngine->hasErrorOccurred())
return 1;
- if (mOS.get() == NULL)
+ if (mOS.get() == nullptr)
return 1;
// Here is per-compilation needed initialization
@@ -481,6 +453,10 @@
}
mDiagEngine->Reset();
mDiagClient->reset();
+
+ // remove fatal error handler. slang::init needs to be called before another
+ // compilation, which will re-install the error handler.
+ llvm::remove_fatal_error_handler();
}
Slang::~Slang() {
diff --git a/slang_backend.cpp b/slang_backend.cpp
index 43d843e..4c6a3b9 100644
--- a/slang_backend.cpp
+++ b/slang_backend.cpp
@@ -65,7 +65,7 @@
void Backend::CreateFunctionPasses() {
if (!mPerFunctionPasses) {
mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
- mPerFunctionPasses->add(new llvm::DataLayoutPass(mpModule));
+ mPerFunctionPasses->add(new llvm::DataLayoutPass());
llvm::PassManagerBuilder PMBuilder;
PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
@@ -76,7 +76,7 @@
void Backend::CreateModulePasses() {
if (!mPerModulePasses) {
mPerModulePasses = new llvm::PassManager();
- mPerModulePasses->add(new llvm::DataLayoutPass(mpModule));
+ mPerModulePasses->add(new llvm::DataLayoutPass());
llvm::PassManagerBuilder PMBuilder;
PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
@@ -108,7 +108,7 @@
return true;
} else {
mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
- mCodeGenPasses->add(new llvm::DataLayoutPass(mpModule));
+ mCodeGenPasses->add(new llvm::DataLayoutPass());
}
// Create the TargetMachine for generating code.
@@ -117,7 +117,7 @@
std::string Error;
const llvm::Target* TargetInfo =
llvm::TargetRegistry::lookupTarget(Triple, Error);
- if (TargetInfo == NULL) {
+ if (TargetInfo == nullptr) {
mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
return false;
}
@@ -209,13 +209,13 @@
Slang::OutputType OT)
: ASTConsumer(),
mTargetOpts(TargetOpts),
- mpModule(NULL),
+ mpModule(nullptr),
mpOS(OS),
mOT(OT),
- mGen(NULL),
- mPerFunctionPasses(NULL),
- mPerModulePasses(NULL),
- mCodeGenPasses(NULL),
+ mGen(nullptr),
+ mPerFunctionPasses(nullptr),
+ mPerModulePasses(nullptr),
+ mCodeGenPasses(nullptr),
mLLVMContext(llvm::getGlobalContext()),
mDiagEngine(*DiagEngine),
mCodeGenOpts(CodeGenOpts),
@@ -268,7 +268,7 @@
llvm::Module *M = mGen->ReleaseModule();
if (!M) {
// The module has been released by IR gen on failures, do not double free.
- mpModule = NULL;
+ mpModule = nullptr;
return;
}
diff --git a/slang_rs.cpp b/slang_rs.cpp
index c59459b..88eb909 100644
--- a/slang_rs.cpp
+++ b/slang_rs.cpp
@@ -180,11 +180,14 @@
void SlangRS::initDiagnostic() {
clang::DiagnosticsEngine &DiagEngine = getDiagnostics();
+ const auto Flavor = clang::diag::Flavor::WarningOrError;
- if (DiagEngine.setSeverityForGroup("implicit-function-declaration",
- clang::diag::Severity::Error))
- DiagEngine.Report(clang::diag::warn_unknown_warning_option)
+ if (DiagEngine.setSeverityForGroup(Flavor, "implicit-function-declaration",
+ clang::diag::Severity::Error)) {
+ DiagEngine.Report(clang::diag::warn_unknown_diag_option)
+ << /* clang::diag::Flavor::WarningOrError */ 0
<< "implicit-function-declaration";
+ }
DiagEngine.setSeverity(
clang::diag::ext_typecheck_convert_discards_qualifiers,
@@ -266,7 +269,7 @@
}
SlangRS::SlangRS()
- : Slang(), mRSContext(NULL), mAllowRSPrefix(false), mTargetAPI(0),
+ : Slang(), mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0),
mVerbose(false), mIsFilterscript(false) {
}
@@ -440,7 +443,7 @@
void SlangRS::reset(bool SuppressWarnings) {
delete mRSContext;
- mRSContext = NULL;
+ mRSContext = nullptr;
mGeneratedFileNames.clear();
Slang::reset(SuppressWarnings);
}
diff --git a/slang_rs_ast_replace.h b/slang_rs_ast_replace.h
index 0507603..f93171d 100644
--- a/slang_rs_ast_replace.h
+++ b/slang_rs_ast_replace.h
@@ -58,11 +58,11 @@
public:
explicit RSASTReplace(clang::ASTContext &Con)
: C(Con),
- mOuterStmt(NULL),
- mOldStmt(NULL),
- mNewStmt(NULL),
- mOldExpr(NULL),
- mNewExpr(NULL) {
+ mOuterStmt(nullptr),
+ mOldStmt(nullptr),
+ mNewStmt(nullptr),
+ mOldExpr(nullptr),
+ mNewExpr(nullptr) {
}
void VisitStmt(clang::Stmt *S);
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp
index 5d92a12..4d1998e 100644
--- a/slang_rs_backend.cpp
+++ b/slang_rs_backend.cpp
@@ -61,12 +61,12 @@
mSourceMgr(SourceMgr),
mAllowRSPrefix(AllowRSPrefix),
mIsFilterscript(IsFilterscript),
- mExportVarMetadata(NULL),
- mExportFuncMetadata(NULL),
- mExportForEachNameMetadata(NULL),
- mExportForEachSignatureMetadata(NULL),
- mExportTypeMetadata(NULL),
- mRSObjectSlotsMetadata(NULL),
+ mExportVarMetadata(nullptr),
+ mExportFuncMetadata(nullptr),
+ mExportForEachNameMetadata(nullptr),
+ mExportForEachSignatureMetadata(nullptr),
+ mExportTypeMetadata(nullptr),
+ mRSObjectSlotsMetadata(nullptr),
mRefCount(mContext->getASTContext()),
mASTChecker(Context, Context->getTargetAPI(), IsFilterscript) {
}
@@ -88,7 +88,7 @@
for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
I != E; I++) {
clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
- if (FD == NULL)
+ if (FD == nullptr)
continue;
if (!FD->getName().startswith("rs")) // Check prefix
continue;
@@ -182,7 +182,7 @@
///////////////////////////////////////////////////////////////////////////////
void RSBackend::dumpExportVarInfo(llvm::Module *M) {
int slotCount = 0;
- if (mExportVarMetadata == NULL)
+ if (mExportVarMetadata == nullptr)
mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
@@ -251,7 +251,7 @@
llvm::MDNode::get(mLLVMContext, ExportVarInfo));
ExportVarInfo.clear();
- if (mRSObjectSlotsMetadata == NULL) {
+ if (mRSObjectSlotsMetadata == nullptr) {
mRSObjectSlotsMetadata =
M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
}
@@ -266,7 +266,7 @@
}
void RSBackend::dumpExportFunctionInfo(llvm::Module *M) {
- if (mExportFuncMetadata == NULL)
+ if (mExportFuncMetadata == nullptr)
mExportFuncMetadata =
M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
@@ -292,8 +292,9 @@
// Create helper function
{
- llvm::StructType *HelperFunctionParameterTy = NULL;
+ llvm::StructType *HelperFunctionParameterTy = nullptr;
std::vector<bool> isStructInput;
+
if (!F->getArgumentList().empty()) {
std::vector<llvm::Type*> HelperFunctionParameterTys;
for (llvm::Function::arg_iterator AI = F->arg_begin(),
@@ -405,11 +406,11 @@
}
void RSBackend::dumpExportForEachInfo(llvm::Module *M) {
- if (mExportForEachNameMetadata == NULL) {
+ if (mExportForEachNameMetadata == nullptr) {
mExportForEachNameMetadata =
M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
}
- if (mExportForEachSignatureMetadata == NULL) {
+ if (mExportForEachSignatureMetadata == nullptr) {
mExportForEachSignatureMetadata =
M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
}
@@ -461,7 +462,7 @@
const RSExportRecordType *ERT =
static_cast<const RSExportRecordType*>(ET);
- if (mExportTypeMetadata == NULL)
+ if (mExportTypeMetadata == nullptr)
mExportTypeMetadata =
M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
diff --git a/slang_rs_check_ast.cpp b/slang_rs_check_ast.cpp
index b5cb024..848a176 100644
--- a/slang_rs_check_ast.cpp
+++ b/slang_rs_check_ast.cpp
@@ -260,7 +260,7 @@
E = E->IgnoreImpCasts();
if (mIsFilterscript &&
!SlangRS::IsLocInRSHeaderFile(E->getExprLoc(), mSM) &&
- !RSExportType::ValidateType(Context, C, E->getType(), NULL, E->getExprLoc(),
+ !RSExportType::ValidateType(Context, C, E->getType(), nullptr, E->getExprLoc(),
mTargetAPI, mIsFilterscript)) {
mValid = false;
} else {
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index bef4766..608d6cb 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -53,9 +53,9 @@
mPragmas(Pragmas),
mTargetAPI(TargetAPI),
mVerbose(Verbose),
- mDataLayout(NULL),
+ mDataLayout(nullptr),
mLLVMContext(llvm::getGlobalContext()),
- mLicenseNote(NULL),
+ mLicenseNote(nullptr),
mRSPackageName("android.renderscript"),
version(0),
mMangleCtx(Ctx.createMangleContext()),
@@ -77,7 +77,7 @@
return false;
RSExportVar *EV = new RSExportVar(this, VD, ET);
- if (EV == NULL)
+ if (EV == nullptr)
return false;
else
mExportVars.push_back(EV);
@@ -103,7 +103,7 @@
return RSExportForEach::validateSpecialFuncDecl(mTargetAPI, this, FD);
} else if (RSExportForEach::isRSForEachFunc(mTargetAPI, this, FD)) {
RSExportForEach *EFE = RSExportForEach::Create(this, FD);
- if (EFE == NULL)
+ if (EFE == nullptr)
return false;
else
mExportForEach.push_back(EFE);
@@ -111,7 +111,7 @@
}
RSExportFunc *EF = RSExportFunc::Create(this, FD);
- if (EF == NULL)
+ if (EF == nullptr)
return false;
else
mExportFuncs.push_back(EF);
@@ -123,23 +123,23 @@
bool RSContext::processExportType(const llvm::StringRef &Name) {
clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
- slangAssert(TUDecl != NULL && "Translation unit declaration (top-level "
- "declaration) is null object");
+ slangAssert(TUDecl != nullptr && "Translation unit declaration (top-level "
+ "declaration) is null object");
const clang::IdentifierInfo *II = mPP.getIdentifierInfo(Name);
- if (II == NULL)
+ if (II == nullptr)
// TODO(zonr): alert identifier @Name mark as an exportable type cannot be
// found
return false;
clang::DeclContext::lookup_const_result R = TUDecl->lookup(II);
- RSExportType *ET = NULL;
+ RSExportType *ET = nullptr;
for (clang::DeclContext::lookup_const_iterator I = R.begin(), E = R.end();
I != E;
I++) {
clang::NamedDecl *const ND = *I;
- const clang::Type *T = NULL;
+ const clang::Type *T = nullptr;
switch (ND->getKind()) {
case clang::Decl::Typedef: {
@@ -157,11 +157,11 @@
}
}
- if (T != NULL)
+ if (T != nullptr)
ET = RSExportType::Create(this, T);
}
- return (ET != NULL);
+ return (ET != nullptr);
}
diff --git a/slang_rs_context.h b/slang_rs_context.h
index c47f4c1..8e9b577 100644
--- a/slang_rs_context.h
+++ b/slang_rs_context.h
@@ -158,7 +158,7 @@
bool processExport();
inline void newExportable(RSExportable *E) {
- if (E != NULL)
+ if (E != nullptr)
mExportables.push_back(E);
}
typedef ExportableList::iterator exportable_iterator;
diff --git a/slang_rs_export_element.cpp b/slang_rs_export_element.cpp
index 00d5a53..a5985bb 100644
--- a/slang_rs_export_element.cpp
+++ b/slang_rs_export_element.cpp
@@ -74,15 +74,15 @@
// Create RSExportType corresponded to the @T first and then verify
llvm::StringRef TypeName;
- RSExportType *ET = NULL;
+ RSExportType *ET = nullptr;
if (!Initialized)
Init();
- slangAssert(EI != NULL && "Element info not found");
+ slangAssert(EI != nullptr && "Element info not found");
- if (!RSExportType::NormalizeType(T, TypeName, Context, NULL))
- return NULL;
+ if (!RSExportType::NormalizeType(T, TypeName, Context, nullptr))
+ return nullptr;
switch (T->getTypeClass()) {
case clang::Type::Builtin:
@@ -131,7 +131,7 @@
const clang::DeclaratorDecl *DD) {
const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
const clang::Type* CT = GetCanonicalType(T);
- const ElementInfo* EI = NULL;
+ const ElementInfo* EI = nullptr;
// Note: RS element like rs_pixel_rgb elements are either in the type of
// primitive or vector.
@@ -149,14 +149,14 @@
const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
const clang::TypedefNameDecl *TD = TT->getDecl();
EI = GetElementInfo(TD->getName());
- if (EI != NULL)
+ if (EI != nullptr)
break;
T = TD->getUnderlyingType().getTypePtr();
}
}
- if (EI == NULL) {
+ if (EI == nullptr) {
return RSExportType::Create(Context, T);
} else {
return RSExportElement::Create(Context, T, EI);
@@ -170,7 +170,7 @@
ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
if (I == ElementInfoMap.end())
- return NULL;
+ return nullptr;
else
return I->getValue();
}
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index 439f9a9..d3ba154 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -25,11 +25,69 @@
#include "llvm/IR/DerivedTypes.h"
+#include "bcinfo/MetadataExtractor.h"
+
#include "slang_assert.h"
#include "slang_rs_context.h"
#include "slang_rs_export_type.h"
#include "slang_version.h"
+namespace {
+
+const size_t RS_KERNEL_INPUT_LIMIT = 8; // see frameworks/base/libs/rs/cpu_ref/rsCpuCoreRuntime.h
+
+enum SpecialParameterKind {
+ SPK_INT, // 'int' or 'unsigned int'
+ SPK_CTXT, // rs_kernel_context
+};
+
+struct SpecialParameter {
+ const char *name;
+ bcinfo::MetadataSignatureBitval bitval;
+ SpecialParameterKind kind;
+ SlangTargetAPI minAPI;
+};
+
+// Table entries are in the order parameters must occur in a kernel parameter list.
+const SpecialParameter specialParameterTable[] = {
+ { "ctxt", bcinfo::MD_SIG_Ctxt, SPK_CTXT, SLANG_23_TARGET_API },
+ { "x", bcinfo::MD_SIG_X, SPK_INT, SLANG_MINIMUM_TARGET_API },
+ { "y", bcinfo::MD_SIG_Y, SPK_INT, SLANG_MINIMUM_TARGET_API },
+ { "z", bcinfo::MD_SIG_Z, SPK_INT, SLANG_23_TARGET_API },
+ { nullptr, bcinfo::MD_SIG_None, SPK_INT, SLANG_MINIMUM_TARGET_API }, // marks end of table
+};
+
+// If the specified name matches the name of an entry in
+// specialParameterTable, return the corresponding table index;
+// otherwise return -1.
+int lookupSpecialParameter(const llvm::StringRef name) {
+ for (int i = 0; specialParameterTable[i].name != nullptr; ++i)
+ if (name.equals(specialParameterTable[i].name))
+ return i;
+ return -1;
+}
+
+// Return a comma-separated list of names in specialParameterTable
+// that are available at the specified API level.
+std::string listSpecialParameters(unsigned int api) {
+ std::string ret;
+ bool first = true;
+ for (int i = 0; specialParameterTable[i].name != nullptr; ++i) {
+ if (specialParameterTable[i].minAPI > api)
+ continue;
+ if (first)
+ first = false;
+ else
+ ret += ", ";
+ ret += "'";
+ ret += specialParameterTable[i].name;
+ ret += "'";
+ }
+ return ret;
+}
+
+}
+
namespace slang {
// This function takes care of additional validation and construction of
@@ -85,30 +143,30 @@
}
// Validate remaining parameter types
- // TODO(all): Add support for LOD/face when we have them
- size_t IndexOfFirstIterator = numParams;
- valid |= validateIterationParameters(Context, FD, &IndexOfFirstIterator);
+ size_t IndexOfFirstSpecialParameter = numParams;
+ valid |= validateSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
- // Validate the non-iterator parameters, which should all be found before the
- // first iterator.
- for (size_t i = 0; i < IndexOfFirstIterator; i++) {
+ // Validate the non-special parameters, which should all be found before the
+ // first special parameter.
+ for (size_t i = 0; i < IndexOfFirstSpecialParameter; i++) {
const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
clang::QualType QT = PVD->getType().getCanonicalType();
if (!QT->isPointerType()) {
Context->ReportError(PVD->getLocation(),
"Compute kernel %0() cannot have non-pointer "
- "parameters besides 'x' and 'y'. Parameter '%1' is "
- "of type: '%2'")
- << FD->getName() << PVD->getName() << PVD->getType().getAsString();
+ "parameters besides (%1). Parameter '%2' is "
+ "of type: '%3'")
+ << FD->getName() << listSpecialParameters(Context->getTargetAPI())
+ << PVD->getName() << PVD->getType().getAsString();
valid = false;
continue;
}
// The only non-const pointer should be out.
if (!QT->getPointeeType().isConstQualified()) {
- if (mOut == NULL) {
+ if (mOut == nullptr) {
mOut = PVD;
} else {
Context->ReportError(PVD->getLocation(),
@@ -119,9 +177,9 @@
valid = false;
}
} else {
- if (mIns.empty() && mOut == NULL) {
+ if (mIns.empty() && mOut == nullptr) {
mIns.push_back(PVD);
- } else if (mUsrData == NULL) {
+ } else if (mUsrData == nullptr) {
mUsrData = PVD;
} else {
Context->ReportError(
@@ -173,14 +231,13 @@
}
// Validate remaining parameter types
- // TODO(all): Add support for LOD/face when we have them
- size_t IndexOfFirstIterator = numParams;
- valid |= validateIterationParameters(Context, FD, &IndexOfFirstIterator);
+ size_t IndexOfFirstSpecialParameter = numParams;
+ valid |= validateSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
- // Validate the non-iterator parameters, which should all be found before the
- // first iterator.
- for (size_t i = 0; i < IndexOfFirstIterator; i++) {
+ // Validate the non-special parameters, which should all be found before the
+ // first special.
+ for (size_t i = 0; i < IndexOfFirstSpecialParameter; i++) {
const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
/*
@@ -188,7 +245,17 @@
* multi-input feature is officially supported.
*/
if (Context->getTargetAPI() == SLANG_DEVELOPMENT_TARGET_API || i == 0) {
- mIns.push_back(PVD);
+ if (i >= RS_KERNEL_INPUT_LIMIT) {
+ Context->ReportError(PVD->getLocation(),
+ "Invalid parameter '%0' for compute kernel %1(). "
+ "Kernels targeting SDK levels %2-%3 may not use "
+ "more than %4 input parameters.") << PVD->getName() <<
+ FD->getName() << SLANG_MINIMUM_TARGET_API <<
+ SLANG_MAXIMUM_TARGET_API << int(RS_KERNEL_INPUT_LIMIT);
+
+ } else {
+ mIns.push_back(PVD);
+ }
} else {
Context->ReportError(PVD->getLocation(),
"Invalid parameter '%0' for compute kernel %1(). "
@@ -221,73 +288,119 @@
return valid;
}
-// Search for the optional x and y parameters. Returns true if valid. Also
-// sets *IndexOfFirstIterator to the index of the first iterator parameter, or
+// Search for the optional special parameters. Returns true if valid. Also
+// sets *IndexOfFirstSpecialParameter to the index of the first special parameter, or
// FD->getNumParams() if none are found.
-bool RSExportForEach::validateIterationParameters(
+bool RSExportForEach::validateSpecialParameters(
RSContext *Context, const clang::FunctionDecl *FD,
- size_t *IndexOfFirstIterator) {
- slangAssert(IndexOfFirstIterator != NULL);
- slangAssert(mX == NULL && mY == NULL);
+ size_t *IndexOfFirstSpecialParameter) {
+ slangAssert(IndexOfFirstSpecialParameter != nullptr);
+ slangAssert(mSpecialParameterSignatureMetadata == 0);
clang::ASTContext &C = Context->getASTContext();
- // Find the x and y parameters if present.
+ // Find all special parameters if present.
+ int LastSpecialParameterIdx = -1; // index into specialParameterTable
+ int FirstIntSpecialParameterIdx = -1; // index into specialParameterTable
+ clang::QualType FirstIntSpecialParameterType;
size_t NumParams = FD->getNumParams();
- *IndexOfFirstIterator = NumParams;
+ *IndexOfFirstSpecialParameter = NumParams;
bool valid = true;
for (size_t i = 0; i < NumParams; i++) {
const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
llvm::StringRef ParamName = PVD->getName();
- if (ParamName.equals("x")) {
- slangAssert(mX == NULL); // We won't be invoked if two 'x' are present.
- mX = PVD;
- if (mY != NULL) {
+ int SpecialParameterIdx = lookupSpecialParameter(ParamName);
+ if (SpecialParameterIdx >= 0) {
+ const SpecialParameter &SP = specialParameterTable[SpecialParameterIdx];
+ // We won't be invoked if two parameters of the same name are present.
+ slangAssert(!(mSpecialParameterSignatureMetadata & SP.bitval));
+
+ if (Context->getTargetAPI() < SP.minAPI) {
Context->ReportError(PVD->getLocation(),
- "In compute kernel %0(), parameter 'x' should "
- "be defined before parameter 'y'")
- << FD->getName();
+ "Compute kernel %0() targeting SDK levels "
+ "%1-%2 may not use parameter '%3'.")
+ << FD->getName()
+ << SLANG_MINIMUM_TARGET_API
+ << (SP.minAPI - 1)
+ << SP.name;
valid = false;
}
- } else if (ParamName.equals("y")) {
- slangAssert(mY == NULL); // We won't be invoked if two 'y' are present.
- mY = PVD;
+
+ mSpecialParameterSignatureMetadata |= SP.bitval;
+ if (SpecialParameterIdx < LastSpecialParameterIdx) {
+ Context->ReportError(PVD->getLocation(),
+ "In compute kernel %0(), parameter '%1' must "
+ "be defined before parameter '%2'.")
+ << FD->getName()
+ << SP.name
+ << specialParameterTable[LastSpecialParameterIdx].name;
+ valid = false;
+ }
+ LastSpecialParameterIdx = SpecialParameterIdx;
+
+ // Ensure that all SPK_INT special parameters have the same type.
+ if (SP.kind == SPK_INT) {
+ clang::QualType SpecialParameterType = PVD->getType();
+ if (FirstIntSpecialParameterIdx >= 0) {
+ if (SpecialParameterType != FirstIntSpecialParameterType) {
+ Context->ReportError(PVD->getLocation(),
+ "Parameters '%0' and '%1' must be of the same type. "
+ "'%0' is of type '%2' while '%1' is of type '%3'.")
+ << specialParameterTable[FirstIntSpecialParameterIdx].name
+ << SP.name
+ << FirstIntSpecialParameterType.getAsString()
+ << SpecialParameterType.getAsString();
+ valid = false;
+ }
+ } else {
+ FirstIntSpecialParameterIdx = SpecialParameterIdx;
+ FirstIntSpecialParameterType = SpecialParameterType;
+ }
+ }
} else {
- // It's neither x nor y.
- if (*IndexOfFirstIterator < NumParams) {
+ // It's not a special parameter.
+ if (*IndexOfFirstSpecialParameter < NumParams) {
Context->ReportError(PVD->getLocation(),
"In compute kernel %0(), parameter '%1' cannot "
- "appear after the 'x' and 'y' parameters")
- << FD->getName() << ParamName;
+ "appear after any of the (%2) parameters.")
+ << FD->getName() << ParamName << listSpecialParameters(Context->getTargetAPI());
valid = false;
}
continue;
}
- // Validate the data type of x and y.
- clang::QualType QT = PVD->getType().getCanonicalType();
- clang::QualType UT = QT.getUnqualifiedType();
- if (UT != C.UnsignedIntTy && UT != C.IntTy) {
- Context->ReportError(PVD->getLocation(),
- "Parameter '%0' must be of type 'int' or "
- "'unsigned int'. It is of type '%1'")
- << ParamName << PVD->getType().getAsString();
- valid = false;
+ // Validate the data type of the special parameter.
+ switch (specialParameterTable[SpecialParameterIdx].kind) {
+ case SPK_INT: {
+ clang::QualType QT = PVD->getType().getCanonicalType();
+ clang::QualType UT = QT.getUnqualifiedType();
+ if (UT != C.UnsignedIntTy && UT != C.IntTy) {
+ Context->ReportError(PVD->getLocation(),
+ "Parameter '%0' must be of type 'int' or "
+ "'unsigned int'. It is of type '%1'.")
+ << ParamName << PVD->getType().getAsString();
+ valid = false;
+ }
+ break;
+ }
+ case SPK_CTXT: {
+ static const char ExpectedTypeNameMatch[] = "const struct rs_kernel_context_t *";
+ static const char ExpectedTypeNamePrint[] = "rs_kernel_context";
+ clang::QualType QT = PVD->getType().getCanonicalType();
+ clang::QualType UT = QT.getUnqualifiedType();
+ if (UT.getAsString() != ExpectedTypeNameMatch) {
+ Context->ReportError(PVD->getLocation(),
+ "Parameter '%0' must be of type '%1'. "
+ "It is of type '%2'.")
+ << ParamName << ExpectedTypeNamePrint << PVD->getType().getAsString();
+ valid = false;
+ }
+ break;
+ }
+ default:
+ slangAssert(!"Unexpected special parameter type");
}
- // If this is the first time we find an iterator, save it.
- if (*IndexOfFirstIterator >= NumParams) {
- *IndexOfFirstIterator = i;
- }
- }
- // Check that x and y have the same type.
- if (mX != NULL and mY != NULL) {
- clang::QualType XType = mX->getType();
- clang::QualType YType = mY->getType();
-
- if (XType != YType) {
- Context->ReportError(mY->getLocation(),
- "Parameter 'x' and 'y' must be of the same type. "
- "'x' is of type '%0' while 'y' is of type '%1'")
- << XType.getAsString() << YType.getAsString();
- valid = false;
+ // If this is the first time we find a special parameter, save it.
+ if (*IndexOfFirstSpecialParameter >= NumParams) {
+ *IndexOfFirstSpecialParameter = i;
}
}
return valid;
@@ -299,30 +412,30 @@
bool valid = true;
if (mIsKernelStyle) {
- slangAssert(mOut == NULL);
- slangAssert(mUsrData == NULL);
+ slangAssert(mOut == nullptr);
+ slangAssert(mUsrData == nullptr);
} else {
slangAssert(!mHasReturnType);
}
// Set up the bitwise metadata encoding for runtime argument passing.
- // TODO: If this bit field is re-used from C++ code, define the values in a header.
const bool HasOut = mOut || mHasReturnType;
- mSignatureMetadata |= (hasIns() ? 0x01 : 0);
- mSignatureMetadata |= (HasOut ? 0x02 : 0);
- mSignatureMetadata |= (mUsrData ? 0x04 : 0);
- mSignatureMetadata |= (mX ? 0x08 : 0);
- mSignatureMetadata |= (mY ? 0x10 : 0);
- mSignatureMetadata |= (mIsKernelStyle ? 0x20 : 0); // pass-by-value
+ mSignatureMetadata |= (hasIns() ? bcinfo::MD_SIG_In : 0);
+ mSignatureMetadata |= (HasOut ? bcinfo::MD_SIG_Out : 0);
+ mSignatureMetadata |= (mUsrData ? bcinfo::MD_SIG_Usr : 0);
+ mSignatureMetadata |= (mIsKernelStyle ? bcinfo::MD_SIG_Kernel : 0); // pass-by-value
+ mSignatureMetadata |= mSpecialParameterSignatureMetadata;
if (Context->getTargetAPI() < SLANG_ICS_TARGET_API) {
// APIs before ICS cannot skip between parameters. It is ok, however, for
// them to omit further parameters (i.e. skipping X is ok if you skip Y).
- if (mSignatureMetadata != 0x1f && // In, Out, UsrData, X, Y
- mSignatureMetadata != 0x0f && // In, Out, UsrData, X
- mSignatureMetadata != 0x07 && // In, Out, UsrData
- mSignatureMetadata != 0x03 && // In, Out
- mSignatureMetadata != 0x01) { // In
+ if (mSignatureMetadata != (bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out | bcinfo::MD_SIG_Usr |
+ bcinfo::MD_SIG_X | bcinfo::MD_SIG_Y) &&
+ mSignatureMetadata != (bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out | bcinfo::MD_SIG_Usr |
+ bcinfo::MD_SIG_X) &&
+ mSignatureMetadata != (bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out | bcinfo::MD_SIG_Usr) &&
+ mSignatureMetadata != (bcinfo::MD_SIG_In | bcinfo::MD_SIG_Out) &&
+ mSignatureMetadata != (bcinfo::MD_SIG_In)) {
Context->ReportError(FD->getLocation(),
"Compute kernel %0() targeting SDK levels "
"%1-%2 may not skip parameters")
@@ -345,7 +458,7 @@
FE = new RSExportForEach(Context, Name);
if (!FE->validateAndConstructParams(Context, FD)) {
- return NULL;
+ return nullptr;
}
clang::ASTContext &Ctx = Context->getASTContext();
@@ -364,7 +477,7 @@
C.VoidTy) {
// In the case of using const void*, we can't reflect an appopriate
// Java type, so we fall back to just reflecting the ain/aout parameters
- FE->mUsrData = NULL;
+ FE->mUsrData = nullptr;
} else {
clang::RecordDecl *RD =
clang::RecordDecl::Create(Ctx, clang::TTK_Struct,
@@ -380,8 +493,8 @@
clang::SourceLocation(),
PVD->getIdentifier(),
QT->getPointeeType(),
- NULL,
- /* BitWidth = */ NULL,
+ nullptr,
+ /* BitWidth = */ nullptr,
/* Mutable = */ false,
/* HasInit = */ clang::ICIS_NoInit);
RD->addDecl(FD);
@@ -393,11 +506,11 @@
RSExportType *ET = RSExportType::Create(Context, T.getTypePtr());
- if (ET == NULL) {
+ if (ET == nullptr) {
fprintf(stderr, "Failed to export the function %s. There's at least "
"one parameter whose type is not supported by the "
"reflection\n", FE->getName().c_str());
- return NULL;
+ return nullptr;
}
slangAssert((ET->getClass() == RSExportType::ExportClassRecord) &&
@@ -414,7 +527,7 @@
RSExportType *InExportType = RSExportType::Create(Context, T);
if (FE->mIsKernelStyle) {
- slangAssert(InExportType != NULL);
+ slangAssert(InExportType != nullptr);
}
FE->mInTypes.push_back(InExportType);
diff --git a/slang_rs_export_foreach.h b/slang_rs_export_foreach.h
index f401d19..54b1303 100644
--- a/slang_rs_export_foreach.h
+++ b/slang_rs_export_foreach.h
@@ -57,8 +57,9 @@
llvm::SmallVector<const clang::ParmVarDecl*, 16> mIns;
const clang::ParmVarDecl *mOut;
const clang::ParmVarDecl *mUsrData;
- const clang::ParmVarDecl *mX;
- const clang::ParmVarDecl *mY;
+
+ // Accumulator for metadata bits corresponding to special parameters.
+ unsigned int mSpecialParameterSignatureMetadata;
clang::QualType mResultType; // return type (if present).
bool mHasReturnType; // does this kernel have a return type?
@@ -69,9 +70,9 @@
// TODO(all): Add support for LOD/face when we have them
RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
: RSExportable(Context, RSExportable::EX_FOREACH),
- mName(Name.data(), Name.size()), mParamPacketType(NULL),
- mOutType(NULL), numParams(0), mSignatureMetadata(0),
- mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL),
+ mName(Name.data(), Name.size()), mParamPacketType(nullptr),
+ mOutType(nullptr), numParams(0), mSignatureMetadata(0),
+ mOut(nullptr), mUsrData(nullptr), mSpecialParameterSignatureMetadata(0),
mResultType(clang::QualType()), mHasReturnType(false),
mIsKernelStyle(false), mDummyRoot(false) {
}
@@ -85,9 +86,9 @@
bool validateAndConstructKernelParams(RSContext *Context,
const clang::FunctionDecl *FD);
- bool validateIterationParameters(RSContext *Context,
- const clang::FunctionDecl *FD,
- size_t *IndexOfFirstIterator);
+ bool validateSpecialParameters(RSContext *Context,
+ const clang::FunctionDecl *FD,
+ size_t *IndexOfFirstSpecialParameter);
bool setSignatureMetadata(RSContext *Context,
const clang::FunctionDecl *FD);
@@ -110,11 +111,11 @@
}
inline bool hasOut() const {
- return (mOut != NULL);
+ return (mOut != nullptr);
}
inline bool hasUsrData() const {
- return (mUsrData != NULL);
+ return (mUsrData != nullptr);
}
inline bool hasReturn() const {
@@ -148,13 +149,13 @@
typedef RSExportRecordType::const_field_iterator const_param_iterator;
inline const_param_iterator params_begin() const {
- slangAssert((mParamPacketType != NULL) &&
+ slangAssert((mParamPacketType != nullptr) &&
"Get parameter from export foreach having no parameter!");
return mParamPacketType->fields_begin();
}
inline const_param_iterator params_end() const {
- slangAssert((mParamPacketType != NULL) &&
+ slangAssert((mParamPacketType != nullptr) &&
"Get parameter from export foreach having no parameter!");
return mParamPacketType->fields_end();
}
diff --git a/slang_rs_export_func.cpp b/slang_rs_export_func.cpp
index 5fc36f1..070270c 100644
--- a/slang_rs_export_func.cpp
+++ b/slang_rs_export_func.cpp
@@ -55,14 +55,14 @@
slangAssert(!Name.empty() && "Function must have a name");
if (!ValidateFuncDecl(Context, FD)) {
- return NULL;
+ return nullptr;
}
F = new RSExportFunc(Context, Name, FD);
// Initialize mParamPacketType
if (FD->getNumParams() <= 0) {
- F->mParamPacketType = NULL;
+ F->mParamPacketType = nullptr;
} else {
clang::ASTContext &Ctx = Context->getASTContext();
@@ -92,8 +92,8 @@
clang::SourceLocation(),
PVD->getIdentifier(),
PVD->getOriginalType(),
- NULL,
- /* BitWidth = */ NULL,
+ nullptr,
+ /* BitWidth = */ nullptr,
/* Mutable = */ false,
/* HasInit = */ clang::ICIS_NoInit);
RD->addDecl(FD);
@@ -107,11 +107,11 @@
RSExportType *ET =
RSExportType::Create(Context, T.getTypePtr());
- if (ET == NULL) {
+ if (ET == nullptr) {
fprintf(stderr, "Failed to export the function %s. There's at least one "
"parameter whose type is not supported by the "
"reflection\n", F->getName().c_str());
- return NULL;
+ return nullptr;
}
slangAssert((ET->getClass() == RSExportType::ExportClassRecord) &&
@@ -125,12 +125,12 @@
bool
RSExportFunc::checkParameterPacketType(llvm::StructType *ParamTy) const {
- if (ParamTy == NULL)
+ if (ParamTy == nullptr)
return !hasParam();
else if (!hasParam())
return false;
- slangAssert(mParamPacketType != NULL);
+ slangAssert(mParamPacketType != nullptr);
const RSExportRecordType *ERT = mParamPacketType;
// must have same number of elements
diff --git a/slang_rs_export_func.h b/slang_rs_export_func.h
index d680f52..3c0804d 100644
--- a/slang_rs_export_func.h
+++ b/slang_rs_export_func.h
@@ -56,7 +56,7 @@
mName(Name.data(), Name.size()),
mMangledName(),
mShouldMangle(false),
- mParamPacketType(NULL) {
+ mParamPacketType(nullptr) {
mShouldMangle = Context->getMangleContext().shouldMangleDeclName(FD);
@@ -74,12 +74,12 @@
typedef RSExportRecordType::const_field_iterator const_param_iterator;
inline const_param_iterator params_begin() const {
- slangAssert((mParamPacketType != NULL) &&
+ slangAssert((mParamPacketType != nullptr) &&
"Get parameter from export function having no parameter!");
return mParamPacketType->fields_begin();
}
inline const_param_iterator params_end() const {
- slangAssert((mParamPacketType != NULL) &&
+ slangAssert((mParamPacketType != nullptr) &&
"Get parameter from export function having no parameter!");
return mParamPacketType->fields_end();
}
@@ -98,7 +98,7 @@
// Check whether the given ParamsPacket type (in LLVM type) is "size
// equivalent" to the one obtained from getParamPacketType(). If the @Params
- // is NULL, means there must be no any parameters.
+ // is nullptr, means there must be no any parameters.
bool checkParameterPacketType(llvm::StructType *ParamTy) const;
}; // RSExportFunc
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index 4348ea0..8a8dbe0 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -59,31 +59,31 @@
{PrimitiveDataType, "UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true},
{PrimitiveDataType, "UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false},
- {PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false},
+ {PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", nullptr, nullptr, false},
- {PrimitiveDataType, "UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false},
- {PrimitiveDataType, "UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false},
- {PrimitiveDataType, "UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false},
+ {PrimitiveDataType, "UNSIGNED_5_6_5", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false},
+ {PrimitiveDataType, "UNSIGNED_5_5_5_1", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false},
+ {PrimitiveDataType, "UNSIGNED_4_4_4_4", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false},
- {MatrixDataType, "MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false},
- {MatrixDataType, "MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false},
- {MatrixDataType, "MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false},
+ {MatrixDataType, "MATRIX_2X2", nullptr, 4*32, "rsMatrix_2x2", "Matrix2f", nullptr, nullptr, false},
+ {MatrixDataType, "MATRIX_3X3", nullptr, 9*32, "rsMatrix_3x3", "Matrix3f", nullptr, nullptr, false},
+ {MatrixDataType, "MATRIX_4X4", nullptr, 16*32, "rsMatrix_4x4", "Matrix4f", nullptr, nullptr, false},
// RS object types are 32 bits in 32-bit RS, but 256 bits in 64-bit RS.
// This is handled specially by the GetSizeInBits() method.
- {ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false},
- {ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false},
- {ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false},
- {ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false},
- {ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false},
- {ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false},
- {ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false},
+ {ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", nullptr, nullptr, false},
+ {ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", nullptr, nullptr, false},
+ {ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", nullptr, nullptr, false},
+ {ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", nullptr, nullptr, false},
+ {ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", nullptr, nullptr, false},
+ {ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", nullptr, nullptr, false},
+ {ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", nullptr, nullptr, false},
- {ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false},
- {ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false},
- {ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false},
- {ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false},
- {ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false}
+ {ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", nullptr, nullptr, false},
+ {ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", nullptr, nullptr, false},
+ {ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", nullptr, nullptr, false},
+ {ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", nullptr, nullptr, false},
+ {ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", nullptr, nullptr, false}
};
const int kMaxVectorSize = 4;
@@ -201,7 +201,7 @@
if (ElementType->isArrayType()) {
ReportTypeError(Context, VD, TopLevelRecord,
"multidimensional arrays cannot be exported: '%0'");
- return NULL;
+ return nullptr;
} else if (ElementType->isExtVectorType()) {
const clang::ExtVectorType *EVT =
static_cast<const clang::ExtVectorType*>(ElementType);
@@ -211,19 +211,19 @@
if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) {
ReportTypeError(Context, VD, TopLevelRecord,
"vectors of non-primitive types cannot be exported: '%0'");
- return NULL;
+ return nullptr;
}
if (numElements == 3 && CAT->getSize() != 1) {
ReportTypeError(Context, VD, TopLevelRecord,
"arrays of width 3 vector types cannot be exported: '%0'");
- return NULL;
+ return nullptr;
}
}
if (TypeExportableHelper(ElementType, SPS, Context, VD,
- TopLevelRecord) == NULL) {
- return NULL;
+ TopLevelRecord) == nullptr) {
+ return nullptr;
} else {
return CAT;
}
@@ -235,7 +235,7 @@
return &BuiltinInfoTable[i];
}
}
- return NULL;
+ return nullptr;
}
static const clang::Type *TypeExportableHelper(
@@ -245,8 +245,8 @@
clang::VarDecl const *VD,
clang::RecordDecl const *TopLevelRecord) {
// Normalize first
- if ((T = GetCanonicalType(T)) == NULL)
- return NULL;
+ if ((T = GetCanonicalType(T)) == nullptr)
+ return nullptr;
if (SPS.count(T))
return T;
@@ -256,7 +256,7 @@
switch (T->getTypeClass()) {
case clang::Type::Builtin: {
const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI);
- return FindBuiltinType(BT->getKind()) == NULL ? NULL : T;
+ return FindBuiltinType(BT->getKind()) == nullptr ? nullptr : T;
}
case clang::Type::Record: {
if (RSExportPrimitiveType::GetRSSpecificType(T) != DataTypeUnknown) {
@@ -267,19 +267,19 @@
if (T->isUnionType()) {
ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(),
"unions cannot be exported: '%0'");
- return NULL;
+ return nullptr;
} else if (!T->isStructureType()) {
slangAssert(false && "Unknown type cannot be exported");
- return NULL;
+ return nullptr;
}
clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
- if (RD != NULL) {
+ if (RD != nullptr) {
RD = RD->getDefinition();
- if (RD == NULL) {
- ReportTypeError(Context, NULL, T->getAsStructureType()->getDecl(),
+ if (RD == nullptr) {
+ ReportTypeError(Context, nullptr, T->getAsStructureType()->getDecl(),
"struct is not defined in this module");
- return NULL;
+ return nullptr;
}
}
@@ -287,14 +287,14 @@
TopLevelRecord = RD;
}
if (RD->getName().empty()) {
- ReportTypeError(Context, NULL, RD,
+ ReportTypeError(Context, nullptr, RD,
"anonymous structures cannot be exported");
- return NULL;
+ return nullptr;
}
// Fast check
if (RD->hasFlexibleArrayMember() || RD->hasObjectMember())
- return NULL;
+ return nullptr;
// Insert myself into checking set
SPS.insert(T);
@@ -309,7 +309,7 @@
FT = GetCanonicalType(FT);
if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) {
- return NULL;
+ return nullptr;
}
// We don't support bit fields yet
@@ -320,7 +320,7 @@
FD->getLocation(),
"bit fields are not able to be exported: '%0.%1'")
<< RD->getName() << FD->getName();
- return NULL;
+ return nullptr;
}
}
@@ -330,7 +330,7 @@
if (TopLevelRecord) {
ReportTypeError(Context, VD, TopLevelRecord,
"structures containing pointers cannot be exported: '%0'");
- return NULL;
+ return nullptr;
}
const clang::PointerType *PT = static_cast<const clang::PointerType*>(CTI);
@@ -339,14 +339,14 @@
if (PointeeType->getTypeClass() == clang::Type::Pointer) {
ReportTypeError(Context, VD, TopLevelRecord,
"multiple levels of pointers cannot be exported: '%0'");
- return NULL;
+ return nullptr;
}
// We don't support pointer with array-type pointee or unsupported pointee
// type
if (PointeeType->isArrayType() ||
(TypeExportableHelper(PointeeType, SPS, Context, VD,
- TopLevelRecord) == NULL))
- return NULL;
+ TopLevelRecord) == nullptr))
+ return nullptr;
else
return T;
}
@@ -355,15 +355,15 @@
static_cast<const clang::ExtVectorType*>(CTI);
// Only vector with size 2, 3 and 4 are supported.
if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4)
- return NULL;
+ return nullptr;
// Check base element type
const clang::Type *ElementType = GetExtVectorElementType(EVT);
if ((ElementType->getTypeClass() != clang::Type::Builtin) ||
(TypeExportableHelper(ElementType, SPS, Context, VD,
- TopLevelRecord) == NULL))
- return NULL;
+ TopLevelRecord) == nullptr))
+ return nullptr;
else
return T;
}
@@ -381,25 +381,26 @@
}
default: {
slangAssert(false && "Unknown type cannot be validated");
- return NULL;
+ return nullptr;
}
}
}
// Return the type that can be used to create RSExportType, will always return
-// the canonical type
-// If the Type T is not exportable, this function returns NULL. DiagEngine is
-// used to generate proper Clang diagnostic messages when a
-// non-exportable type is detected. TopLevelRecord is used to capture the
-// highest struct (in the case of a nested hierarchy) for detecting other
-// types that cannot be exported (mostly pointers within a struct).
+// the canonical type.
+//
+// If the Type T is not exportable, this function returns nullptr. DiagEngine is
+// used to generate proper Clang diagnostic messages when a non-exportable type
+// is detected. TopLevelRecord is used to capture the highest struct (in the
+// case of a nested hierarchy) for detecting other types that cannot be exported
+// (mostly pointers within a struct).
static const clang::Type *TypeExportable(const clang::Type *T,
slang::RSContext *Context,
const clang::VarDecl *VD) {
llvm::SmallPtrSet<const clang::Type*, 8> SPS =
llvm::SmallPtrSet<const clang::Type*, 8>();
- return TypeExportableHelper(T, SPS, Context, VD, NULL);
+ return TypeExportableHelper(T, SPS, Context, VD, nullptr);
}
static bool ValidateRSObjectInVarDecl(slang::RSContext *Context,
@@ -414,7 +415,7 @@
// Only if we are not a pointer to an object.
const clang::Type *T = GetCanonicalType(VD->getType().getTypePtr());
if (T->getTypeClass() != clang::Type::Pointer) {
- ReportTypeError(Context, VD, NULL,
+ ReportTypeError(Context, VD, nullptr,
"arrays/structures containing RS object types "
"cannot be exported in target API < %1: '%0'",
SLANG_JB_TARGET_API);
@@ -452,7 +453,7 @@
clang::RecordDecl *UnionDecl,
unsigned int TargetAPI,
bool IsFilterscript) {
- if ((T = GetCanonicalType(T)) == NULL)
+ if ((T = GetCanonicalType(T)) == nullptr)
return true;
if (SPS.count(T))
@@ -463,7 +464,7 @@
switch (T->getTypeClass()) {
case clang::Type::Record: {
if (RSExportPrimitiveType::IsRSObjectType(T)) {
- clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL);
+ clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : nullptr);
if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType,
TargetAPI)) {
return false;
@@ -474,13 +475,13 @@
if (!UnionDecl) {
return true;
} else if (RSExportPrimitiveType::IsRSObjectType(T)) {
- ReportTypeError(Context, NULL, UnionDecl,
+ ReportTypeError(Context, nullptr, UnionDecl,
"unions containing RS object types are not allowed");
return false;
}
}
- clang::RecordDecl *RD = NULL;
+ clang::RecordDecl *RD = nullptr;
// Check internal struct
if (T->isUnionType()) {
@@ -493,9 +494,9 @@
return false;
}
- if (RD != NULL) {
+ if (RD != nullptr) {
RD = RD->getDefinition();
- if (RD == NULL) {
+ if (RD == nullptr) {
// FIXME
return true;
}
@@ -583,7 +584,7 @@
EVT->getNumElements() == 3 &&
ND &&
ND->getFormalLinkage() == clang::ExternalLinkage) {
- ReportTypeError(Context, ND, NULL,
+ ReportTypeError(Context, ND, nullptr,
"structs containing vectors of dimension 3 cannot "
"be exported at this API level: '%0'");
return false;
@@ -624,7 +625,7 @@
llvm::StringRef &TypeName,
RSContext *Context,
const clang::VarDecl *VD) {
- if ((T = TypeExportable(T, Context, VD)) == NULL) {
+ if ((T = TypeExportable(T, Context, VD)) == nullptr) {
return false;
}
// Get type name
@@ -650,7 +651,7 @@
llvm::SmallPtrSet<const clang::Type*, 8> SPS =
llvm::SmallPtrSet<const clang::Type*, 8>();
- return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, NULL, TargetAPI,
+ return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, nullptr, TargetAPI,
IsFilterscript);
return true;
}
@@ -668,16 +669,16 @@
clang::QualType T = DD->getType();
if (T.isNull())
- return NULL;
+ return nullptr;
else
return T.getTypePtr();
}
- return NULL;
+ return nullptr;
}
llvm::StringRef RSExportType::GetTypeName(const clang::Type* T) {
T = GetCanonicalType(T);
- if (T == NULL)
+ if (T == nullptr)
return llvm::StringRef();
const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr();
@@ -686,7 +687,7 @@
case clang::Type::Builtin: {
const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI);
BuiltinInfo *info = FindBuiltinType(BT->getKind());
- if (info != NULL) {
+ if (info != nullptr) {
return info->cname[0];
}
slangAssert(false && "Unknown data type of the builtin");
@@ -702,7 +703,7 @@
llvm::StringRef Name = RD->getName();
if (Name.empty()) {
- if (RD->getTypedefNameForAnonDecl() != NULL) {
+ if (RD->getTypedefNameForAnonDecl() != nullptr) {
Name = RD->getTypedefNameForAnonDecl()->getName();
}
@@ -712,7 +713,7 @@
RE = RD->redecls_end();
RI != RE;
RI++) {
- slangAssert(*RI != NULL && "cannot be NULL object");
+ slangAssert(*RI != nullptr && "cannot be NULL object");
Name = (*RI)->getName();
if (!Name.empty())
@@ -727,7 +728,7 @@
const clang::PointerType *P = static_cast<const clang::PointerType*>(CTI);
const clang::Type *PT = GetPointeeType(P);
llvm::StringRef PointeeName;
- if (NormalizeType(PT, PointeeName, NULL, NULL)) {
+ if (NormalizeType(PT, PointeeName, nullptr, nullptr)) {
char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ];
Name[0] = '*';
memcpy(Name + 1, PointeeName.data(), PointeeName.size());
@@ -768,7 +769,7 @@
const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr();
- RSExportType *ET = NULL;
+ RSExportType *ET = nullptr;
switch (T->getTypeClass()) {
case clang::Type::Record: {
DataType dt = RSExportPrimitiveType::GetRSSpecificType(TypeName);
@@ -848,10 +849,10 @@
RSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) {
llvm::StringRef TypeName;
- if (NormalizeType(T, TypeName, Context, NULL)) {
+ if (NormalizeType(T, TypeName, Context, nullptr)) {
return Create(Context, T, TypeName);
} else {
- return NULL;
+ return nullptr;
}
}
@@ -876,7 +877,7 @@
// Make a copy on Name since memory stored @Name is either allocated in
// ASTContext or allocated in GetTypeName which will be destroyed later.
mName(Name.data(), Name.size()),
- mLLVMType(NULL) {
+ mLLVMType(nullptr) {
// Don't cache the type whose name start with '<'. Those type failed to
// get their name since constructing their name in GetTypeName() requiring
// complicated work.
@@ -891,7 +892,7 @@
if (!RSExportable::keep())
return false;
// Invalidate converted LLVM type.
- mLLVMType = NULL;
+ mLLVMType = nullptr;
return true;
}
@@ -908,7 +909,7 @@
RSExportPrimitiveType::RSSpecificTypeMap;
bool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) {
- if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin))
+ if ((T != nullptr) && (T->getTypeClass() == clang::Type::Builtin))
return true;
else
return false;
@@ -921,8 +922,8 @@
if (RSSpecificTypeMap->empty()) {
for (int i = 0; i < MatrixAndObjectDataTypesCount; i++) {
- RSSpecificTypeMap->GetOrCreateValue(MatrixAndObjectDataTypes[i].name,
- MatrixAndObjectDataTypes[i].dataType);
+ (*RSSpecificTypeMap)[MatrixAndObjectDataTypes[i].name] =
+ MatrixAndObjectDataTypes[i].dataType;
}
}
@@ -935,7 +936,7 @@
DataType RSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) {
T = GetCanonicalType(T);
- if ((T == NULL) || (T->getTypeClass() != clang::Type::Record))
+ if ((T == nullptr) || (T->getTypeClass() != clang::Type::Record))
return DataTypeUnknown;
return GetRSSpecificType( RSExportType::GetTypeName(T) );
@@ -1029,7 +1030,7 @@
DataType
RSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) {
- if (T == NULL)
+ if (T == nullptr)
return DataTypeUnknown;
switch (T->getTypeClass()) {
@@ -1037,7 +1038,7 @@
const clang::BuiltinType *BT =
static_cast<const clang::BuiltinType*>(T->getCanonicalTypeInternal().getTypePtr());
BuiltinInfo *info = FindBuiltinType(BT->getKind());
- if (info != NULL) {
+ if (info != nullptr) {
return info->type;
}
// The size of type WChar depend on platform so we abandon the support
@@ -1068,7 +1069,7 @@
DataType DT = GetDataType(Context, T);
if ((DT == DataTypeUnknown) || TypeName.empty())
- return NULL;
+ return nullptr;
else
return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName,
DT, Normalized);
@@ -1077,11 +1078,11 @@
RSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context,
const clang::Type *T) {
llvm::StringRef TypeName;
- if (RSExportType::NormalizeType(T, TypeName, Context, NULL)
+ if (RSExportType::NormalizeType(T, TypeName, Context, nullptr)
&& IsPrimitiveType(T)) {
return Create(Context, T, TypeName);
} else {
- return NULL;
+ return nullptr;
}
}
@@ -1150,7 +1151,7 @@
}
}
- return NULL;
+ return nullptr;
}
bool RSExportPrimitiveType::equals(const RSExportable *E) const {
@@ -1162,7 +1163,7 @@
if (DT > DataTypeUnknown && DT < DataTypeMax) {
return &gReflectionTypes[DT];
} else {
- return NULL;
+ return nullptr;
}
}
@@ -1183,9 +1184,9 @@
Context->getASTContext().IntTy.getTypePtr());
}
- if (PointeeET == NULL) {
+ if (PointeeET == nullptr) {
// Error diagnostic is emitted for corresponding pointee type
- return NULL;
+ return nullptr;
}
return new RSExportPointerType(Context, TypeName, PointeeET);
@@ -1227,7 +1228,7 @@
return name;
BuiltinInfo *info = FindBuiltinType(BT->getKind());
- if (info != NULL) {
+ if (info != nullptr) {
int I = EVT->getNumElements() - 1;
if (I < kMaxVectorSize) {
name = info->cname[I];
@@ -1242,7 +1243,7 @@
const clang::ExtVectorType *EVT,
const llvm::StringRef &TypeName,
bool Normalized) {
- slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector);
+ slangAssert(EVT != nullptr && EVT->getTypeClass() == clang::Type::ExtVector);
const clang::Type *ElementType = GetExtVectorElementType(EVT);
DataType DT = RSExportPrimitiveType::GetDataType(Context, ElementType);
@@ -1254,7 +1255,7 @@
Normalized,
EVT->getNumElements());
else
- return NULL;
+ return nullptr;
}
llvm::Type *RSExportVectorType::convertToLLVMType() const {
@@ -1273,37 +1274,37 @@
const clang::RecordType *RT,
const llvm::StringRef &TypeName,
unsigned Dim) {
- slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record));
+ slangAssert((RT != nullptr) && (RT->getTypeClass() == clang::Type::Record));
slangAssert((Dim > 1) && "Invalid dimension of matrix");
// Check whether the struct rs_matrix is in our expected form (but assume it's
// correct if we're not sure whether it's correct or not)
const clang::RecordDecl* RD = RT->getDecl();
RD = RD->getDefinition();
- if (RD != NULL) {
+ if (RD != nullptr) {
// Find definition, perform further examination
if (RD->field_empty()) {
Context->ReportError(
RD->getLocation(),
"invalid matrix struct: must have 1 field for saving values: '%0'")
<< RD->getName();
- return NULL;
+ return nullptr;
}
clang::RecordDecl::field_iterator FIT = RD->field_begin();
const clang::FieldDecl *FD = *FIT;
const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
- if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) {
+ if ((FT == nullptr) || (FT->getTypeClass() != clang::Type::ConstantArray)) {
Context->ReportError(RD->getLocation(),
"invalid matrix struct: first field should"
" be an array with constant size: '%0'")
<< RD->getName();
- return NULL;
+ return nullptr;
}
const clang::ConstantArrayType *CAT =
static_cast<const clang::ConstantArrayType *>(FT);
const clang::Type *ElementType = GetConstantArrayElementType(CAT);
- if ((ElementType == NULL) ||
+ if ((ElementType == nullptr) ||
(ElementType->getTypeClass() != clang::Type::Builtin) ||
(static_cast<const clang::BuiltinType *>(ElementType)->getKind() !=
clang::BuiltinType::Float)) {
@@ -1311,7 +1312,7 @@
"invalid matrix struct: first field "
"should be a float array: '%0'")
<< RD->getName();
- return NULL;
+ return nullptr;
}
if (CAT->getSize() != Dim * Dim) {
@@ -1319,7 +1320,7 @@
"invalid matrix struct: first field "
"should be an array with size %0: '%1'")
<< (Dim * Dim) << (RD->getName());
- return NULL;
+ return nullptr;
}
FIT++;
@@ -1328,7 +1329,7 @@
"invalid matrix struct: must have "
"exactly 1 field: '%0'")
<< RD->getName();
- return NULL;
+ return nullptr;
}
}
@@ -1356,7 +1357,7 @@
RSExportConstantArrayType
*RSExportConstantArrayType::Create(RSContext *Context,
const clang::ConstantArrayType *CAT) {
- slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray);
+ slangAssert(CAT != nullptr && CAT->getTypeClass() == clang::Type::ConstantArray);
slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large");
@@ -1366,8 +1367,8 @@
const clang::Type *ElementType = GetConstantArrayElementType(CAT);
RSExportType *ElementET = RSExportType::Create(Context, ElementType);
- if (ElementET == NULL) {
- return NULL;
+ if (ElementET == nullptr) {
+ return nullptr;
}
return new RSExportConstantArrayType(Context,
@@ -1399,22 +1400,22 @@
const clang::RecordType *RT,
const llvm::StringRef &TypeName,
bool mIsArtificial) {
- slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record);
+ slangAssert(RT != nullptr && RT->getTypeClass() == clang::Type::Record);
const clang::RecordDecl *RD = RT->getDecl();
slangAssert(RD->isStruct());
RD = RD->getDefinition();
- if (RD == NULL) {
+ if (RD == nullptr) {
slangAssert(false && "struct is not defined in this module");
- return NULL;
+ return nullptr;
}
// Struct layout construct by clang. We rely on this for obtaining the
// alloc size of a struct and offset of every field in that struct.
const clang::ASTRecordLayout *RL =
&Context->getASTContext().getASTRecordLayout(RD);
- slangAssert((RL != NULL) &&
+ slangAssert((RL != nullptr) &&
"Failed to retrieve the struct layout from Clang.");
RSExportRecordType *ERT =
@@ -1436,13 +1437,13 @@
clang::FieldDecl *FD = *FI;
if (FD->isBitField()) {
- return NULL;
+ return nullptr;
}
// Type
RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD);
- if (ET != NULL) {
+ if (ET != nullptr) {
ERT->mFields.push_back(
new Field(ET, FD->getName(), ERT,
static_cast<size_t>(RL->getFieldOffset(Index) >> 3)));
@@ -1450,7 +1451,7 @@
Context->ReportError(RD->getLocation(),
"field type cannot be exported: '%0.%1'")
<< RD->getName() << FD->getName();
- return NULL;
+ return nullptr;
}
}
@@ -1475,10 +1476,10 @@
llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(),
FieldTypes,
mIsPacked);
- if (ST != NULL) {
+ if (ST != nullptr) {
return ST;
} else {
- return NULL;
+ return nullptr;
}
}
diff --git a/slang_rs_export_type.h b/slang_rs_export_type.h
index afd2db2..d9bad8c 100644
--- a/slang_rs_export_type.h
+++ b/slang_rs_export_type.h
@@ -35,8 +35,8 @@
inline const clang::Type* GetCanonicalType(const clang::Type* T) {
- if (T == NULL) {
- return NULL;
+ if (T == nullptr) {
+ return nullptr;
}
return T->getCanonicalTypeInternal().getTypePtr();
}
@@ -46,22 +46,22 @@
}
inline const clang::Type* GetExtVectorElementType(const clang::ExtVectorType *T) {
- if (T == NULL) {
- return NULL;
+ if (T == nullptr) {
+ return nullptr;
}
return GetCanonicalType(T->getElementType());
}
inline const clang::Type* GetPointeeType(const clang::PointerType *T) {
- if (T == NULL) {
- return NULL;
+ if (T == nullptr) {
+ return nullptr;
}
return GetCanonicalType(T->getPointeeType());
}
inline const clang::Type* GetConstantArrayElementType(const clang::ConstantArrayType *T) {
- if (T == NULL) {
- return NULL;
+ if (T == nullptr) {
+ return nullptr;
}
return GetCanonicalType(T->getElementType());
}
@@ -257,7 +257,7 @@
virtual unsigned getSize() const { return 1; }
inline llvm::Type *getLLVMType() const {
- if (mLLVMType == NULL)
+ if (mLLVMType == nullptr)
mLLVMType = convertToLLVMType();
return mLLVMType;
}
@@ -591,7 +591,7 @@
E = mFields.end();
I != E;
I++)
- if (*I != NULL)
+ if (*I != nullptr)
delete *I;
}
}; // RSExportRecordType
diff --git a/slang_rs_export_var.cpp b/slang_rs_export_var.cpp
index 3df28af..0d9e614 100644
--- a/slang_rs_export_var.cpp
+++ b/slang_rs_export_var.cpp
@@ -38,7 +38,7 @@
mNumInits(0) {
// mInit - Evaluate initializer expression
const clang::Expr *Initializer = VD->getAnyInitializer();
- if (Initializer != NULL) {
+ if (Initializer != nullptr) {
switch (ET->getClass()) {
case RSExportType::ExportClassPrimitive:
case RSExportType::ExportClassVector: {
diff --git a/slang_rs_exportable.cpp b/slang_rs_exportable.cpp
index 53c1fbb..4a843ab 100644
--- a/slang_rs_exportable.cpp
+++ b/slang_rs_exportable.cpp
@@ -22,12 +22,12 @@
if (isKeep())
return false;
// Invalidate associated Context.
- mContext = NULL;
+ mContext = nullptr;
return true;
}
bool RSExportable::equals(const RSExportable *E) const {
- return ((E == NULL) ? false : (mK == E->mK));
+ return ((E == nullptr) ? false : (mK == E->mK));
}
} // namespace slang
diff --git a/slang_rs_exportable.h b/slang_rs_exportable.h
index 8b51182..0871be3 100644
--- a/slang_rs_exportable.h
+++ b/slang_rs_exportable.h
@@ -50,7 +50,7 @@
// responsibility is then transferred to the object who invoked this function.
// Return false if the exportable is kept or failed to keep.
virtual bool keep();
- inline bool isKeep() const { return (mContext == NULL); }
+ inline bool isKeep() const { return (mContext == nullptr); }
virtual bool equals(const RSExportable *E) const;
diff --git a/slang_rs_object_ref_count.cpp b/slang_rs_object_ref_count.cpp
index f0ac22d..47db22f 100644
--- a/slang_rs_object_ref_count.cpp
+++ b/slang_rs_object_ref_count.cpp
@@ -42,8 +42,8 @@
void RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) {
for (unsigned i = 0; i < DataTypeMax; i++) {
- RSSetObjectFD[i] = NULL;
- RSClearObjectFD[i] = NULL;
+ RSSetObjectFD[i] = nullptr;
+ RSClearObjectFD[i] = nullptr;
}
clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
@@ -151,7 +151,7 @@
}
slangAssert(Once <= 1);
- // When S is NULL, we are appending to the end of the CompoundStmt.
+ // When S is nullptr, we are appending to the end of the CompoundStmt.
if (!S) {
slangAssert(Once == 0);
std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
@@ -218,7 +218,7 @@
// the replacement. It also finishes up by appending the destructor to the
// current outermost CompoundStmt.
void InsertDestructors() {
- clang::Stmt *S = NULL;
+ clang::Stmt *S = nullptr;
clang::SourceManager &SM = mCtx.getSourceManager();
std::list<clang::Stmt *> StmtList;
StmtList.push_back(mDtorStmt);
@@ -244,7 +244,7 @@
clang::CompoundStmt *CS =
llvm::dyn_cast<clang::CompoundStmt>(mOuterStmt);
slangAssert(CS);
- AppendAfterStmt(mCtx, CS, NULL, StmtList);
+ AppendAfterStmt(mCtx, CS, nullptr, StmtList);
}
void VisitStmt(clang::Stmt *S);
@@ -358,7 +358,7 @@
"Should not be destroying arrays with this function");
clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T);
- slangAssert((ClearObjectFD != NULL) &&
+ slangAssert((ClearObjectFD != nullptr) &&
"rsClearObject doesn't cover all RS object types");
clang::QualType ClearObjectFDType = ClearObjectFD->getType();
@@ -391,14 +391,14 @@
ClearObjectFD->getLocation(),
ClearObjectFDType,
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Expr *RSClearObjectFP =
clang::ImplicitCastExpr::Create(C,
C.getPointerType(ClearObjectFDType),
clang::CK_FunctionToPointerDecay,
RefRSClearObjectFD,
- NULL,
+ nullptr,
clang::VK_RValue);
llvm::SmallVector<clang::Expr*, 1> ArgList;
@@ -445,11 +445,11 @@
// Actually extract out the base RS object type for use later
BaseType = BaseType->getArrayElementTypeNoTypeQual();
- clang::Stmt *StmtArray[2] = {NULL};
+ clang::Stmt *StmtArray[2] = {nullptr};
int StmtCtr = 0;
if (NumArrayElements <= 0) {
- return NULL;
+ return nullptr;
}
// Example destructor loop for "rs_font fontArr[10];"
@@ -463,7 +463,7 @@
// (BinaryOperator 'int' '<'
// (DeclRefExpr 'int' Var='rsIntIter')
// (IntegerLiteral 'int' 10)
- // NULL << CondVar >>
+ // nullptr << CondVar >>
// (UnaryOperator 'int' postfix '++'
// (DeclRefExpr 'int' Var='rsIntIter'))
// (CallExpr 'void'
@@ -505,7 +505,7 @@
Loc,
C.IntTy,
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
@@ -551,7 +551,7 @@
C.getPointerType(BaseType->getCanonicalTypeInternal()),
clang::CK_ArrayToPointerDecay,
RefRSArr,
- NULL,
+ nullptr,
clang::VK_RValue);
clang::Expr *RefRSArrPtrSubscript =
@@ -564,7 +564,7 @@
DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType);
- clang::Stmt *RSClearObjectCall = NULL;
+ clang::Stmt *RSClearObjectCall = nullptr;
if (BaseType->isArrayType()) {
RSClearObjectCall =
ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc);
@@ -579,7 +579,7 @@
new(C) clang::ForStmt(C,
Init,
Cond,
- NULL, // no condVar
+ nullptr, // no condVar
Inc,
RSClearObjectCall,
Loc,
@@ -667,7 +667,7 @@
unsigned StmtCount = 0;
clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy];
for (unsigned i = 0; i < FieldsToDestroy; i++) {
- StmtArray[i] = NULL;
+ StmtArray[i] = nullptr;
}
// Populate StmtArray by creating a destructor for each RS object field
@@ -700,7 +700,7 @@
FD,
FoundDecl,
clang::DeclarationNameInfo(),
- NULL,
+ nullptr,
OrigType->getCanonicalTypeInternal(),
clang::VK_RValue,
clang::OK_Ordinary);
@@ -733,7 +733,7 @@
FD,
FoundDecl,
clang::DeclarationNameInfo(),
- NULL,
+ nullptr,
OrigType->getCanonicalTypeInternal(),
clang::VK_RValue,
clang::OK_Ordinary);
@@ -770,7 +770,7 @@
clang::SourceLocation Loc) {
const clang::Type *T = DstExpr->getType().getTypePtr();
clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T);
- slangAssert((SetObjectFD != NULL) &&
+ slangAssert((SetObjectFD != nullptr) &&
"rsSetObject doesn't cover all RS object types");
clang::QualType SetObjectFDType = SetObjectFD->getType();
@@ -787,14 +787,14 @@
Loc,
SetObjectFDType,
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Expr *RSSetObjectFP =
clang::ImplicitCastExpr::Create(C,
C.getPointerType(SetObjectFDType),
clang::CK_FunctionToPointerDecay,
RefRSSetObjectFD,
- NULL,
+ nullptr,
clang::VK_RValue);
llvm::SmallVector<clang::Expr*, 2> ArgList;
@@ -828,7 +828,7 @@
clang::Expr *SrcArr,
clang::SourceLocation StartLoc,
clang::SourceLocation Loc) {
- clang::DeclContext *DC = NULL;
+ clang::DeclContext *DC = nullptr;
const clang::Type *BaseType = DstArr->getType().getTypePtr();
slangAssert(BaseType->isArrayType());
@@ -836,11 +836,11 @@
// Actually extract out the base RS object type for use later
BaseType = BaseType->getArrayElementTypeNoTypeQual();
- clang::Stmt *StmtArray[2] = {NULL};
+ clang::Stmt *StmtArray[2] = {nullptr};
int StmtCtr = 0;
if (NumArrayElements <= 0) {
- return NULL;
+ return nullptr;
}
// Create helper variable for iterating through elements
@@ -872,7 +872,7 @@
Loc,
C.IntTy,
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
@@ -916,7 +916,7 @@
C.getPointerType(BaseType->getCanonicalTypeInternal()),
clang::CK_ArrayToPointerDecay,
DstArr,
- NULL,
+ nullptr,
clang::VK_RValue);
clang::Expr *DstArrPtrSubscript =
@@ -932,7 +932,7 @@
C.getPointerType(BaseType->getCanonicalTypeInternal()),
clang::CK_ArrayToPointerDecay,
SrcArr,
- NULL,
+ nullptr,
clang::VK_RValue);
clang::Expr *SrcArrPtrSubscript =
@@ -945,7 +945,7 @@
DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType);
- clang::Stmt *RSSetObjectCall = NULL;
+ clang::Stmt *RSSetObjectCall = nullptr;
if (BaseType->isArrayType()) {
RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript,
SrcArrPtrSubscript,
@@ -964,7 +964,7 @@
new(C) clang::ForStmt(C,
Init,
Cond,
- NULL, // no condVar
+ nullptr, // no condVar
Inc,
RSSetObjectCall,
Loc,
@@ -996,7 +996,7 @@
unsigned StmtCount = 0;
clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet];
for (unsigned i = 0; i < FieldsToSet; i++) {
- StmtArray[i] = NULL;
+ StmtArray[i] = nullptr;
}
clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
@@ -1026,7 +1026,7 @@
FD,
FoundDecl,
clang::DeclarationNameInfo(),
- NULL,
+ nullptr,
OrigType->getCanonicalTypeInternal(),
clang::VK_RValue,
clang::OK_Ordinary);
@@ -1040,7 +1040,7 @@
FD,
FoundDecl,
clang::DeclarationNameInfo(),
- NULL,
+ nullptr,
OrigType->getCanonicalTypeInternal(),
clang::VK_RValue,
clang::OK_Ordinary);
@@ -1104,7 +1104,7 @@
clang::SourceLocation Loc = AS->getExprLoc();
clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc();
- clang::Stmt *UpdatedStmt = NULL;
+ clang::Stmt *UpdatedStmt = nullptr;
if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) {
// By definition, this is a struct assignment if we get here
@@ -1148,7 +1148,7 @@
Loc,
T->getCanonicalTypeInternal(),
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Stmt *RSSetObjectOps =
CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc);
@@ -1160,7 +1160,7 @@
}
clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT);
- slangAssert((SetObjectFD != NULL) &&
+ slangAssert((SetObjectFD != nullptr) &&
"rsSetObject doesn't cover all RS object types");
clang::QualType SetObjectFDType = SetObjectFD->getType();
@@ -1177,14 +1177,14 @@
Loc,
SetObjectFDType,
clang::VK_RValue,
- NULL);
+ nullptr);
clang::Expr *RSSetObjectFP =
clang::ImplicitCastExpr::Create(C,
C.getPointerType(SetObjectFDType),
clang::CK_FunctionToPointerDecay,
RefRSSetObjectFD,
- NULL,
+ nullptr,
clang::VK_RValue);
const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
@@ -1197,7 +1197,7 @@
Loc,
T->getCanonicalTypeInternal(),
clang::VK_RValue,
- NULL);
+ nullptr);
llvm::SmallVector<clang::Expr*, 2> ArgList;
ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar,
@@ -1258,7 +1258,7 @@
Loc,
T->getCanonicalTypeInternal(),
clang::VK_RValue,
- NULL);
+ nullptr);
if (T->isArrayType()) {
return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc);
@@ -1330,7 +1330,7 @@
DataType DT,
clang::ASTContext &C,
const clang::SourceLocation &Loc) {
- clang::Expr *Res = NULL;
+ clang::Expr *Res = nullptr;
switch (DT) {
case DataTypeIsStruct:
case DataTypeRSElement:
@@ -1354,7 +1354,7 @@
C.NullPtrTy,
clang::CK_IntegralToPointer,
Int0,
- NULL,
+ nullptr,
clang::VK_RValue);
llvm::SmallVector<clang::Expr*, 1>InitList;
@@ -1441,7 +1441,7 @@
if (D->getKind() == clang::Decl::Var) {
clang::VarDecl *VD = static_cast<clang::VarDecl*>(D);
DataType DT = DataTypeUnknown;
- clang::Expr *InitExpr = NULL;
+ clang::Expr *InitExpr = nullptr;
if (InitializeRSObject(VD, &DT, &InitExpr)) {
// We need to zero-init all RS object types (including matrices), ...
getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr);
@@ -1505,7 +1505,7 @@
clang::FunctionProtoType::ExtProtoInfo EPI;
clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy,
llvm::ArrayRef<clang::QualType>(), EPI);
- clang::FunctionDecl *FD = NULL;
+ clang::FunctionDecl *FD = nullptr;
// Generate rsClearObject() call chains for every global variable
// (whether static or extern).
@@ -1517,7 +1517,7 @@
if (CountRSObjectTypes(mCtx, VD->getType().getTypePtr(), loc)) {
if (!FD) {
// Only create FD if we are going to use it.
- FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, NULL,
+ FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, nullptr,
clang::SC_None);
}
// Make sure to create any helpers within the function's DeclContext,
@@ -1530,7 +1530,7 @@
// Nothing needs to be destroyed, so don't emit a dtor.
if (StmtList.empty()) {
- return NULL;
+ return nullptr;
}
clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc);
diff --git a/slang_rs_object_ref_count.h b/slang_rs_object_ref_count.h
index ca25891..eb200b8 100644
--- a/slang_rs_object_ref_count.h
+++ b/slang_rs_object_ref_count.h
@@ -118,7 +118,7 @@
return RSSetObjectFD[DT];
} else {
slangAssert(false && "incorrect type");
- return NULL;
+ return nullptr;
}
}
@@ -132,7 +132,7 @@
return RSClearObjectFD[DT];
} else {
slangAssert(false && "incorrect type");
- return NULL;
+ return nullptr;
}
}
diff --git a/slang_rs_reflect_utils.cpp b/slang_rs_reflect_utils.cpp
index 66facab..c67a1a8 100644
--- a/slang_rs_reflect_utils.cpp
+++ b/slang_rs_reflect_utils.cpp
@@ -22,10 +22,11 @@
#include <iomanip>
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "os_sep.h"
#include "slang_assert.h"
-#include "slang_utils.h"
namespace slang {
@@ -169,7 +170,7 @@
}
FILE *pfin = fopen(filename.c_str(), "rb");
- if (pfin == NULL) {
+ if (pfin == nullptr) {
fprintf(stderr, "Error: could not read file %s\n", filename.c_str());
return false;
}
@@ -261,9 +262,10 @@
const BitCodeAccessorContext &context) {
string output_path =
ComputePackagedPath(context.reflectPath, context.packageName);
- if (!SlangUtils::CreateDirectoryWithParents(llvm::StringRef(output_path),
- NULL)) {
- fprintf(stderr, "Error: could not create dir %s\n", output_path.c_str());
+ if (std::error_code EC = llvm::sys::fs::create_directories(
+ llvm::sys::path::parent_path(output_path))) {
+ fprintf(stderr, "Error: could not create dir %s: %s\n",
+ output_path.c_str(), EC.message().c_str());
return false;
}
@@ -348,9 +350,9 @@
// Create the parent directories.
if (!outDirectory.empty()) {
- std::string errorMsg;
- if (!SlangUtils::CreateDirectoryWithParents(outDirectory, &errorMsg)) {
- fprintf(stderr, "Error: %s\n", errorMsg.c_str());
+ if (std::error_code EC = llvm::sys::fs::create_directories(
+ llvm::sys::path::parent_path(outDirectory))) {
+ fprintf(stderr, "Error: %s\n", EC.message().c_str());
return false;
}
}
@@ -365,7 +367,7 @@
}
// Write the license.
- if (optionalLicense != NULL) {
+ if (optionalLicense != nullptr) {
*this << *optionalLicense;
} else {
*this << gApacheLicenseNote;
diff --git a/slang_rs_reflect_utils.h b/slang_rs_reflect_utils.h
index dc6b50c..1cbc098 100644
--- a/slang_rs_reflect_utils.h
+++ b/slang_rs_reflect_utils.h
@@ -111,7 +111,7 @@
* - opening the stream,
* - writing out the license,
* - writing a message that this file has been auto-generated.
- * If optionalLicense is NULL, a default license is used.
+ * If optionalLicense is nullptr, a default license is used.
*/
bool startFile(const std::string &outPath, const std::string &outFileName,
const std::string &sourceFileName,
diff --git a/slang_rs_reflection.cpp b/slang_rs_reflection.cpp
index 9f5ccd0..dfa6e75 100644
--- a/slang_rs_reflection.cpp
+++ b/slang_rs_reflection.cpp
@@ -37,7 +37,6 @@
#include "slang_rs_export_func.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"
-#include "slang_utils.h"
#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
@@ -115,7 +114,7 @@
return MatrixTypeJavaNameMap[EMT->getDim() - 2];
slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
- return NULL;
+ return nullptr;
}
static const char *GetVectorAccessor(unsigned Index) {
@@ -170,7 +169,7 @@
return PrimitiveTypePackerAPINameMap[EPT->getType()];
slangAssert(false && "GetPackerAPIName : Unknown primitive data type");
- return NULL;
+ return nullptr;
}
static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
@@ -358,7 +357,7 @@
// Generate a simple constructor with only a single parameter (the rest
// can be inferred from information we already have).
mOut.indent() << "// Constructor\n";
- startFunction(AM_Public, false, NULL, getClassName(), 1, "RenderScript",
+ startFunction(AM_Public, false, nullptr, getClassName(), 1, "RenderScript",
"rs");
if (getEmbedBitcodeInJava()) {
@@ -380,7 +379,7 @@
endFunction();
// Alternate constructor (legacy) with 3 original parameters.
- startFunction(AM_Public, false, NULL, getClassName(), 3, "RenderScript",
+ startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
"rs", "Resources", "resources", "int", "id");
// Call constructor of super class
mOut.indent() << "super(rs, resources, id);\n";
@@ -425,7 +424,7 @@
for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
BI != EI; BI++) {
- if (*BI != NULL) {
+ if (*BI != nullptr) {
genTypeInstanceFromPointer(*BI);
}
}
@@ -626,6 +625,16 @@
}
}
+ if (mRSContext->getTargetAPI() >= SLANG_DEVELOPMENT_TARGET_API) {
+ startFunction(AM_Public, false, "Script.InvokeID",
+ "getInvokeID_" + EF->getName(), 0);
+
+ mOut.indent() << "return createInvokeID(" << RS_EXPORT_FUNC_INDEX_PREFIX
+ << EF->getName() << ");\n";
+
+ endFunction();
+ }
+
startFunction(AM_Public, false, "void",
"invoke_" + EF->getName(/*Mangle=*/false),
// We are using un-mangled name since Java
@@ -640,7 +649,7 @@
std::string FieldPackerName = EF->getName() + "_fp";
if (genCreateFieldPacker(ERT, FieldPackerName.c_str()))
- genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
+ genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
mOut.indent() << "invoke(" << RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName()
<< ", " << FieldPackerName << ");\n";
@@ -764,7 +773,7 @@
startFunction(AM_Public, false, "void", "forEach_" + EF->getName(), Args);
if (InTypes.size() == 1) {
- if (InTypes.front() != NULL) {
+ if (InTypes.front() != nullptr) {
genTypeCheck(InTypes.front(), "ain");
}
@@ -773,7 +782,7 @@
for (RSExportForEach::InTypeIter BI = InTypes.begin(), EI = InTypes.end();
BI != EI; BI++, ++Index) {
- if (*BI != NULL) {
+ if (*BI != nullptr) {
genTypeCheck(*BI, ("ain_" + Ins[Index]->getName()).str().c_str());
}
}
@@ -804,7 +813,7 @@
std::string FieldPackerName = EF->getName() + "_fp";
if (ERT) {
if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
- genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
+ genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
}
}
mOut.indent() << "forEach(" << RS_EXPORT_FOREACH_INDEX_PREFIX
@@ -1291,7 +1300,7 @@
size_t FieldStoreSize = T->getStoreSize();
size_t FieldAllocSize = T->getAllocSize();
- if (VarName != NULL)
+ if (VarName != nullptr)
FieldName = VarName + ("." + F->getName());
else
FieldName = F->getName();
@@ -1376,7 +1385,7 @@
mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME " == null) ";
mOut << RS_TYPE_ITEM_BUFFER_NAME << " = new " << RS_TYPE_ITEM_CLASS_NAME
<< "[getType().getX() /* count */];\n";
- if (Index != NULL) {
+ if (Index != nullptr) {
mOut.indent() << "if (" << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index
<< "] == null) ";
mOut << RS_TYPE_ITEM_BUFFER_NAME << "[" << Index << "] = new "
@@ -1495,7 +1504,7 @@
endFunction();
// private with element
- startFunction(AM_Private, false, NULL, getClassName(), 1, "RenderScript",
+ startFunction(AM_Private, false, nullptr, getClassName(), 1, "RenderScript",
RenderScriptVar);
mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
mOut.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME << " = null;\n";
@@ -1503,7 +1512,7 @@
endFunction();
// 1D without usage
- startFunction(AM_Public, false, NULL, getClassName(), 2, "RenderScript",
+ startFunction(AM_Public, false, nullptr, getClassName(), 2, "RenderScript",
RenderScriptVar, "int", "count");
mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
@@ -1514,7 +1523,7 @@
endFunction();
// 1D with usage
- startFunction(AM_Public, false, NULL, getClassName(), 3, "RenderScript",
+ startFunction(AM_Public, false, nullptr, getClassName(), 3, "RenderScript",
RenderScriptVar, "int", "count", "int", "usages");
mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << " = null;\n";
@@ -1615,7 +1624,7 @@
startFunction(AM_PublicSynchronized, false, "void", "set", 3,
RS_TYPE_ITEM_CLASS_NAME, "i", "int", "index", "boolean",
"copyNow");
- genNewItemBufferIfNull(NULL);
+ genNewItemBufferIfNull(nullptr);
mOut.indent() << RS_TYPE_ITEM_BUFFER_NAME << "[index] = i;\n";
mOut.indent() << "if (copyNow) ";
@@ -2025,7 +2034,7 @@
mOut << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
<< ClassName;
- if (SuperClassName != NULL)
+ if (SuperClassName != nullptr)
mOut << " extends " << SuperClassName;
mOut.startBlock();
diff --git a/slang_rs_reflection.h b/slang_rs_reflection.h
index 0c2b773..097a380 100644
--- a/slang_rs_reflection.h
+++ b/slang_rs_reflection.h
@@ -247,7 +247,7 @@
inline const char *getLastError() const {
if (mLastError.empty())
- return NULL;
+ return nullptr;
else
return mLastError.c_str();
}
diff --git a/slang_rs_reflection_cpp.cpp b/slang_rs_reflection_cpp.cpp
index 0840d37..ee1b4bc 100644
--- a/slang_rs_reflection_cpp.cpp
+++ b/slang_rs_reflection_cpp.cpp
@@ -34,7 +34,6 @@
#include "slang_rs_export_func.h"
#include "slang_rs_reflect_utils.h"
#include "slang_version.h"
-#include "slang_utils.h"
#include "slang_rs_reflection_cpp.h"
@@ -56,7 +55,7 @@
return MatrixTypeCNameMap[EMT->getDim() - 2];
slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension");
- return NULL;
+ return nullptr;
}
static std::string GetTypeName(const RSExportType *ET, bool Brackets = true) {
@@ -304,7 +303,7 @@
bool RSReflectionCpp::genEncodedBitCode() {
FILE *pfin = fopen(mBitCodeFilePath.c_str(), "rb");
- if (pfin == NULL) {
+ if (pfin == nullptr) {
fprintf(stderr, "Error: could not read file %s\n",
mBitCodeFilePath.c_str());
return false;
@@ -431,7 +430,7 @@
std::string FieldPackerName = ef->getName() + "_fp";
if (ERT) {
if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
- genPackVarOfType(ERT, NULL, FieldPackerName.c_str());
+ genPackVarOfType(ERT, nullptr, FieldPackerName.c_str());
}
}
mOut.indent() << "forEach(" << slot << ", ";
@@ -470,7 +469,7 @@
if (params) {
param_len = params->getAllocSize();
if (genCreateFieldPacker(params, "__fp")) {
- genPackVarOfType(params, NULL, "__fp");
+ genPackVarOfType(params, nullptr, "__fp");
}
}
@@ -605,7 +604,7 @@
void RSReflectionCpp::genGetterAndSetter(const RSExportVectorType *EVT,
const RSExportVar *EV) {
- slangAssert(EVT != NULL);
+ slangAssert(EVT != nullptr);
RSReflectionTypeData rtd;
EVT->convertToRTD(&rtd);
@@ -767,7 +766,7 @@
size_t FieldStoreSize = T->getStoreSize();
size_t FieldAllocSize = T->getAllocSize();
- if (VarName != NULL)
+ if (VarName != nullptr)
FieldName = VarName + ("." + F->getName());
else
FieldName = F->getName();
diff --git a/slang_utils.cpp b/slang_utils.cpp
deleted file mode 100644
index 45d1b93..0000000
--- a/slang_utils.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "slang_utils.h"
-
-#include <string>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/FileSystem.h"
-
-namespace slang {
-
-bool SlangUtils::CreateDirectoryWithParents(llvm::StringRef Dir,
- std::string* Error) {
- std::error_code EC = llvm::sys::fs::create_directories(Dir);
- if (EC) {
- Error->assign(EC.message());
- return false;
- }
- return true;
-}
-
-} // namespace slang
diff --git a/slang_utils.h b/slang_utils.h
deleted file mode 100644
index 9a123e3..0000000
--- a/slang_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _COMPILE_SLANG_SLANG_UTILS_H_ // NOLINT
-#define _COMPILE_SLANG_SLANG_UTILS_H_
-
-#include <string>
-
-namespace llvm {
- class StringRef;
-}
-
-namespace slang {
-
-class SlangUtils {
- private:
- SlangUtils() {}
-
- public:
- static bool CreateDirectoryWithParents(llvm::StringRef Dir,
- std::string* Error);
-};
-} // namespace slang
-
-#endif // _COMPILE_SLANG_SLANG_UTILS_H_ NOLINT
diff --git a/slang_version.h b/slang_version.h
index b11d185..f3b59a7 100644
--- a/slang_version.h
+++ b/slang_version.h
@@ -38,6 +38,7 @@
SLANG_JB_MR1_TARGET_API = 17,
SLANG_JB_MR2_TARGET_API = 18,
SLANG_KK_TARGET_API = 19,
+ SLANG_23_TARGET_API = 23,
SLANG_MAXIMUM_TARGET_API = RS_VERSION,
SLANG_DEVELOPMENT_TARGET_API = RS_DEVELOPMENT_API
};
diff --git a/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs b/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs
new file mode 100644
index 0000000..34a0a7c
--- /dev/null
+++ b/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs
@@ -0,0 +1,7 @@
+// -target-api 22
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL good(int in, rs_kernel_context ctxt) {
+ return 0;
+}
diff --git a/tests/F_ctxt_wrong_api/stderr.txt.expect b/tests/F_ctxt_wrong_api/stderr.txt.expect
new file mode 100644
index 0000000..74d70f7
--- /dev/null
+++ b/tests/F_ctxt_wrong_api/stderr.txt.expect
@@ -0,0 +1 @@
+F_ctxt_wrong_api.rs:5:28: error: unknown type name 'rs_kernel_context'
diff --git a/tests/F_ctxt_wrong_api/stdout.txt.expect b/tests/F_ctxt_wrong_api/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_ctxt_wrong_api/stdout.txt.expect
diff --git a/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs b/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs
new file mode 100644
index 0000000..7226094
--- /dev/null
+++ b/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs
@@ -0,0 +1,11 @@
+// -target-api 23
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL good(int in, rs_kernel_context ctxt, uint32_t x) {
+ return 0;
+}
+
+int RS_KERNEL bad(int in, uint32_t x, rs_kernel_context ctxt) {
+ return 0;
+}
diff --git a/tests/F_ctxt_wrong_place/stderr.txt.expect b/tests/F_ctxt_wrong_place/stderr.txt.expect
new file mode 100644
index 0000000..60c2b70
--- /dev/null
+++ b/tests/F_ctxt_wrong_place/stderr.txt.expect
@@ -0,0 +1 @@
+F_ctxt_wrong_place.rs:9:57: error: In compute kernel bad(), parameter 'ctxt' must be defined before parameter 'x'.
diff --git a/tests/F_ctxt_wrong_place/stdout.txt.expect b/tests/F_ctxt_wrong_place/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_ctxt_wrong_place/stdout.txt.expect
diff --git a/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs b/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs
new file mode 100644
index 0000000..358dae4
--- /dev/null
+++ b/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs
@@ -0,0 +1,15 @@
+// -target-api 23
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL good1(int in, rs_kernel_context ctxt) {
+ return 0;
+}
+
+int RS_KERNEL good2(int in, const rs_kernel_context ctxt) {
+ return 0;
+}
+
+int RS_KERNEL bad3(int in, const rs_kernel_context *ctxt) {
+ return 0;
+}
diff --git a/tests/F_ctxt_wrong_type/stderr.txt.expect b/tests/F_ctxt_wrong_type/stderr.txt.expect
new file mode 100644
index 0000000..54cf641
--- /dev/null
+++ b/tests/F_ctxt_wrong_type/stderr.txt.expect
@@ -0,0 +1 @@
+F_ctxt_wrong_type.rs:13:53: error: Parameter 'ctxt' must be of type 'rs_kernel_context'. It is of type 'const rs_kernel_context *'.
diff --git a/tests/F_ctxt_wrong_type/stdout.txt.expect b/tests/F_ctxt_wrong_type/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_ctxt_wrong_type/stdout.txt.expect
diff --git a/tests/F_incompatible_handles/incompatible_handles.rs b/tests/F_incompatible_handles/incompatible_handles.rs
new file mode 100644
index 0000000..e7ff6c2
--- /dev/null
+++ b/tests/F_incompatible_handles/incompatible_handles.rs
@@ -0,0 +1,8 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void foo() {
+ rs_allocation a;
+ rs_mesh m;
+ a = m;
+}
diff --git a/tests/F_incompatible_handles/stderr.txt.expect b/tests/F_incompatible_handles/stderr.txt.expect
new file mode 100644
index 0000000..64759c6
--- /dev/null
+++ b/tests/F_incompatible_handles/stderr.txt.expect
@@ -0,0 +1 @@
+incompatible_handles.rs:7:5: error: assigning to 'rs_allocation' from incompatible type 'rs_mesh'
diff --git a/tests/F_incompatible_handles/stdout.txt.expect b/tests/F_incompatible_handles/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_incompatible_handles/stdout.txt.expect
diff --git a/tests/F_multi_in_target_version/stderr.txt.expect b/tests/F_multi_in_target_version/stderr.txt.expect
index a9376b5..56eae17 100644
--- a/tests/F_multi_in_target_version/stderr.txt.expect
+++ b/tests/F_multi_in_target_version/stderr.txt.expect
@@ -1 +1 @@
-multi_in_target_version.rs:5:43: error: Invalid parameter 'in1' for compute kernel root(). Kernels targeting SDK levels 11-21 may not use multiple input parameters.
+multi_in_target_version.rs:5:43: error: Invalid parameter 'in1' for compute kernel root(). Kernels targeting SDK levels 11-23 may not use multiple input parameters.
diff --git a/tests/F_root_compute_int_in/stderr.txt.expect b/tests/F_root_compute_int_in/stderr.txt.expect
index 9cd6e25..cf6eabe 100644
--- a/tests/F_root_compute_int_in/stderr.txt.expect
+++ b/tests/F_root_compute_int_in/stderr.txt.expect
@@ -1,2 +1,2 @@
-root_compute_int_in.rs:4:21: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'in' is of type: 'const int'
+root_compute_int_in.rs:4:21: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'in' is of type: 'const int'
root_compute_int_in.rs:4:6: error: Compute kernel root() must have at least one parameter for in or out
diff --git a/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
index 835e708..04c7735 100644
--- a/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
+++ b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
@@ -1 +1 @@
-root_compute_non_ptr_usrData.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'usrData' is of type: 'const int'
+root_compute_non_ptr_usrData.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'const int'
diff --git a/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
index 84a150f..ba7eecb 100644
--- a/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
+++ b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
@@ -1,5 +1,6 @@
-root_compute_non_uint32_t_xyzar.rs:5:17: error: Parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'
-root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'
-root_compute_non_uint32_t_xyzar.rs:5:36: error: In compute kernel root(), parameter 'z' cannot appear after the 'x' and 'y' parameters
-root_compute_non_uint32_t_xyzar.rs:5:45: error: In compute kernel root(), parameter 'ar' cannot appear after the 'x' and 'y' parameters
-root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameter 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'
+root_compute_non_uint32_t_xyzar.rs:5:17: error: Parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
+root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
+root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
+root_compute_non_uint32_t_xyzar.rs:5:36: error: Parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
+root_compute_non_uint32_t_xyzar.rs:5:36: error: Parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
+root_compute_non_uint32_t_xyzar.rs:5:45: error: In compute kernel root(), parameter 'ar' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
diff --git a/tests/F_root_compute_non_uint32_t_xyzwar/root_compute_non_uint32_t_xyzwar.rs b/tests/F_root_compute_non_uint32_t_xyzwar/root_compute_non_uint32_t_xyzwar.rs
new file mode 100644
index 0000000..b3a00ad
--- /dev/null
+++ b/tests/F_root_compute_non_uint32_t_xyzwar/root_compute_non_uint32_t_xyzwar.rs
@@ -0,0 +1,7 @@
+// -target-api 23
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+void root(const int *ain, int *aout, const void *usrData,
+ short x, float y, double z, long w, uchar ar) {
+}
diff --git a/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect b/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect
new file mode 100644
index 0000000..bdd564b
--- /dev/null
+++ b/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect
@@ -0,0 +1,7 @@
+root_compute_non_uint32_t_xyzwar.rs:6:17: error: Parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
+root_compute_non_uint32_t_xyzwar.rs:6:26: error: Parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
+root_compute_non_uint32_t_xyzwar.rs:6:26: error: Parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
+root_compute_non_uint32_t_xyzwar.rs:6:36: error: Parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
+root_compute_non_uint32_t_xyzwar.rs:6:36: error: Parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
+root_compute_non_uint32_t_xyzwar.rs:6:44: error: In compute kernel root(), parameter 'w' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_non_uint32_t_xyzwar.rs:6:53: error: In compute kernel root(), parameter 'ar' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
diff --git a/tests/F_root_compute_non_uint32_t_xyzwar/stdout.txt.expect b/tests/F_root_compute_non_uint32_t_xyzwar/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_root_compute_non_uint32_t_xyzwar/stdout.txt.expect
diff --git a/tests/F_root_compute_really_bad/stderr.txt.expect b/tests/F_root_compute_really_bad/stderr.txt.expect
index ec826f7..8d9589c 100644
--- a/tests/F_root_compute_really_bad/stderr.txt.expect
+++ b/tests/F_root_compute_really_bad/stderr.txt.expect
@@ -1,21 +1,21 @@
root_compute_really_bad.rs:4:5: error: Compute kernel root() is required to return a void type
-root_compute_really_bad.rs:5:31: error: In compute kernel root(), parameter 'x' should be defined before parameter 'y'
-root_compute_really_bad.rs:6:19: error: In compute kernel root(), parameter 'extra1' cannot appear after the 'x' and 'y' parameters
-root_compute_really_bad.rs:6:36: error: In compute kernel root(), parameter 'extra2' cannot appear after the 'x' and 'y' parameters
-root_compute_really_bad.rs:4:14: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'ain' is of type: 'int'
-root_compute_really_bad.rs:4:23: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'aout' is of type: 'int'
-root_compute_really_bad.rs:4:33: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'usrData' is of type: 'int'
-root_compute_really_bad.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'x1' is of type: 'float'
-root_compute_really_bad.rs:4:59: error: Compute kernel root() cannot have non-pointer parameters besides 'x' and 'y'. Parameter 'y1' is of type: 'double'
+root_compute_really_bad.rs:5:31: error: In compute kernel root(), parameter 'x' must be defined before parameter 'y'.
+root_compute_really_bad.rs:6:19: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_really_bad.rs:6:36: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_really_bad.rs:4:14: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'ain' is of type: 'int'
+root_compute_really_bad.rs:4:23: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'aout' is of type: 'int'
+root_compute_really_bad.rs:4:33: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'int'
+root_compute_really_bad.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'x1' is of type: 'float'
+root_compute_really_bad.rs:4:59: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'y1' is of type: 'double'
root_compute_really_bad.rs:4:5: error: Compute kernel root() must have at least one parameter for in or out
root_compute_really_bad.rs:10:44: error: Compute kernel root2() can only have one non-const pointer parameter. Parameters 'ain' and 'usrData' are both non-const.
root_compute_really_bad.rs:10:66: error: Unexpected parameter 'x1' for compute kernel root2()
root_compute_really_bad.rs:11:26: error: Unexpected parameter 'y1' for compute kernel root2()
-root_compute_really_bad.rs:16:38: error: In compute kernel root_kernel(), parameter 'x' should be defined before parameter 'y'
-root_compute_really_bad.rs:16:50: error: In compute kernel root_kernel(), parameter 'extra1' cannot appear after the 'x' and 'y' parameters
-root_compute_really_bad.rs:16:67: error: In compute kernel root_kernel(), parameter 'extra2' cannot appear after the 'x' and 'y' parameters
-root_compute_really_bad.rs:15:31: error: Invalid parameter 'aout' for compute kernel root_kernel(). Kernels targeting SDK levels 11-21 may not use multiple input parameters.
+root_compute_really_bad.rs:16:38: error: In compute kernel root_kernel(), parameter 'x' must be defined before parameter 'y'.
+root_compute_really_bad.rs:16:50: error: In compute kernel root_kernel(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_really_bad.rs:16:67: error: In compute kernel root_kernel(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_really_bad.rs:15:31: error: Invalid parameter 'aout' for compute kernel root_kernel(). Kernels targeting SDK levels 11-23 may not use multiple input parameters.
root_compute_really_bad.rs:15:31: error: Compute kernel root_kernel() cannot have parameter 'aout' of pointer type: 'int *'
-root_compute_really_bad.rs:15:41: error: Invalid parameter 'usrData' for compute kernel root_kernel(). Kernels targeting SDK levels 11-21 may not use multiple input parameters.
-root_compute_really_bad.rs:15:56: error: Invalid parameter 'x1' for compute kernel root_kernel(). Kernels targeting SDK levels 11-21 may not use multiple input parameters.
-root_compute_really_bad.rs:15:67: error: Invalid parameter 'y1' for compute kernel root_kernel(). Kernels targeting SDK levels 11-21 may not use multiple input parameters.
+root_compute_really_bad.rs:15:41: error: Invalid parameter 'usrData' for compute kernel root_kernel(). Kernels targeting SDK levels 11-23 may not use multiple input parameters.
+root_compute_really_bad.rs:15:56: error: Invalid parameter 'x1' for compute kernel root_kernel(). Kernels targeting SDK levels 11-23 may not use multiple input parameters.
+root_compute_really_bad.rs:15:67: error: Invalid parameter 'y1' for compute kernel root_kernel(). Kernels targeting SDK levels 11-23 may not use multiple input parameters.
diff --git a/tests/F_root_compute_too_many_args/stderr.txt.expect b/tests/F_root_compute_too_many_args/stderr.txt.expect
index 56d081b..dbb0500 100644
--- a/tests/F_root_compute_too_many_args/stderr.txt.expect
+++ b/tests/F_root_compute_too_many_args/stderr.txt.expect
@@ -1,2 +1,2 @@
-root_compute_too_many_args.rs:6:20: error: In compute kernel root(), parameter 'extra1' cannot appear after the 'x' and 'y' parameters
-root_compute_too_many_args.rs:6:37: error: In compute kernel root(), parameter 'extra2' cannot appear after the 'x' and 'y' parameters
+root_compute_too_many_args.rs:6:20: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_too_many_args.rs:6:37: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
diff --git a/tests/F_set_target_api_10/stderr.txt.expect b/tests/F_set_target_api_10/stderr.txt.expect
index cbe60d0..605ee83 100644
--- a/tests/F_set_target_api_10/stderr.txt.expect
+++ b/tests/F_set_target_api_10/stderr.txt.expect
@@ -1 +1 @@
-error: target API level '10' is out of range ('11' - '21')
+error: target API level '10' is out of range ('11' - '23')
diff --git a/tests/F_set_target_api_9000/stderr.txt.expect b/tests/F_set_target_api_9000/stderr.txt.expect
index 91bb723..b5bcdff 100644
--- a/tests/F_set_target_api_9000/stderr.txt.expect
+++ b/tests/F_set_target_api_9000/stderr.txt.expect
@@ -1 +1 @@
-error: target API level '9000' is out of range ('11' - '21')
+error: target API level '9000' is out of range ('11' - '23')
diff --git a/tests/F_too_many_inputs/F_too_many_inputs.rs b/tests/F_too_many_inputs/F_too_many_inputs.rs
new file mode 100644
index 0000000..248ee4f
--- /dev/null
+++ b/tests/F_too_many_inputs/F_too_many_inputs.rs
@@ -0,0 +1,11 @@
+// -target-api 0
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL good(int in0, int in1, int in2, int in3, int in4, int in5, int in6, int in7) {
+ return 0;
+}
+
+int RS_KERNEL bad(int in0, int in1, int in2, int in3, int in4, int in5, int in6, int in7, int in8) {
+ return 0;
+}
diff --git a/tests/F_too_many_inputs/stderr.txt.expect b/tests/F_too_many_inputs/stderr.txt.expect
new file mode 100644
index 0000000..02e3347
--- /dev/null
+++ b/tests/F_too_many_inputs/stderr.txt.expect
@@ -0,0 +1 @@
+F_too_many_inputs.rs:9:95: error: Invalid parameter 'in8' for compute kernel bad(). Kernels targeting SDK levels 11-23 may not use more than 8 input parameters.
diff --git a/tests/F_too_many_inputs/stdout.txt.expect b/tests/F_too_many_inputs/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_too_many_inputs/stdout.txt.expect
diff --git a/tests/F_z_wrong_api/F_z_wrong_api.rs b/tests/F_z_wrong_api/F_z_wrong_api.rs
new file mode 100644
index 0000000..42b08a2
--- /dev/null
+++ b/tests/F_z_wrong_api/F_z_wrong_api.rs
@@ -0,0 +1,7 @@
+// -target-api 22
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL bad(int in, uint32_t x, uint32_t y, uint32_t z) {
+ return 0;
+}
diff --git a/tests/F_z_wrong_api/stderr.txt.expect b/tests/F_z_wrong_api/stderr.txt.expect
new file mode 100644
index 0000000..9553acd
--- /dev/null
+++ b/tests/F_z_wrong_api/stderr.txt.expect
@@ -0,0 +1 @@
+F_z_wrong_api.rs:5:60: error: Compute kernel bad() targeting SDK levels 11-22 may not use parameter 'z'.
diff --git a/tests/F_z_wrong_api/stdout.txt.expect b/tests/F_z_wrong_api/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_z_wrong_api/stdout.txt.expect
diff --git a/tests/P_warnings_rsSetElementAt/stderr.txt.expect b/tests/P_warnings_rsSetElementAt/stderr.txt.expect
index 71b7aab..d003f5e 100644
--- a/tests/P_warnings_rsSetElementAt/stderr.txt.expect
+++ b/tests/P_warnings_rsSetElementAt/stderr.txt.expect
@@ -10,3 +10,4 @@
setelementat.rs:30:5: warning: untyped rsSetElementAt() can reduce performance. Use rsSetElementAt_int() instead.
setelementat.rs:31:5: warning: untyped rsSetElementAt() can reduce performance. Use rsSetElementAt_uint() instead.
setelementat.rs:32:5: warning: untyped rsSetElementAt() can reduce performance. Use rsSetElementAt_long() instead.
+setelementat.rs:33:5: warning: untyped rsSetElementAt() can reduce performance. Use rsSetElementAt_ulong() instead.