WebCLArguments::WebCLArguments(const std::string &inputSource, int argc, char const *argv[]) : preprocessorArgc_(0) , preprocessorArgv_(NULL) , validatorArgc_(0) , validatorArgv_(NULL) , matcherArgv_() , files_() , builtinDeclFilename_(NULL) , outputs_() { int inputDescriptor = -1; char const *inputFilename = createFullTemporaryFile(inputDescriptor, &inputSource[0], inputSource.size()); if (!inputFilename) return; files_.push_back(TemporaryFile(-1, inputFilename)); close(inputDescriptor); char const *buffer = reinterpret_cast<char const*>(kernel_endlfix_cl); size_t length = kernel_endlfix_cl_len; int headerDescriptor = -1; char const *headerFilename = createFullTemporaryFile(headerDescriptor, buffer, length); if (!headerFilename) return; files_.push_back(TemporaryFile(-1, headerFilename)); close(headerDescriptor); int builtinDeclDescriptor = -1; builtinDeclFilename_ = createEmptyTemporaryFile(builtinDeclDescriptor); if (!builtinDeclFilename_) return; files_.push_back(TemporaryFile(-1, builtinDeclFilename_)); close(builtinDeclDescriptor); // TODO: add -Dcl_khr_fp16 etc definitions to preprocessor options // based on extensions passed to clvValidate() char const *preprocessorInvocation[] = { "libclv", inputFilename, "--" }; const int preprocessorInvocationSize = sizeof(preprocessorInvocation) / sizeof(preprocessorInvocation[0]); char const *preprocessorOptions[] = { "-E", "-x", "cl", "-fno-builtin", "-ffreestanding" }; const int numPreprocessorOptions = sizeof(preprocessorOptions) / sizeof(preprocessorOptions[0]); char const *validatorInvocation[] = { "libclv", NULL, "--" }; const int validatorInvocationSize = sizeof(validatorInvocation) / sizeof(validatorInvocation[0]); char const *validatorOptions[] = { "-x", "cl", "-include", headerFilename, // has to be early (provides utility macros) "-include", builtinDeclFilename_ // has to be late (uses utility macros) }; const int numValidatorOptions = sizeof(validatorOptions) / sizeof(validatorOptions[0]); std::set<char const *> userDefines; for (int i = 0; i < argc; ++i) { char const *option = argv[i]; if (!std::string(option).substr(0, 2).compare("-D")) userDefines.insert(option); } preprocessorArgc_ = preprocessorInvocationSize + userDefines.size() + numPreprocessorOptions + 1; validatorArgc_ = validatorInvocationSize + argc + numValidatorOptions + 3; preprocessorArgv_ = new char const *[preprocessorArgc_]; if (!preprocessorArgv_) { std::cerr << "Internal error. Can't create argument list for preprocessor." << std::endl; return; } validatorArgv_ = new char const *[validatorArgc_]; if (!validatorArgv_) { std::cerr << "Internal error. Can't create argument list for validator." << std::endl; return; } // preprocessor arguments std::copy(preprocessorInvocation, preprocessorInvocation + preprocessorInvocationSize, preprocessorArgv_); std::copy(userDefines.begin(), userDefines.end(), preprocessorArgv_ + preprocessorInvocationSize); std::copy(preprocessorOptions, preprocessorOptions + numPreprocessorOptions, preprocessorArgv_ + preprocessorInvocationSize + userDefines.size()); preprocessorArgv_[preprocessorArgc_ - 1] = "-ferror-limit=0"; // validator arguments std::copy(validatorInvocation, validatorInvocation + validatorInvocationSize, validatorArgv_); std::copy(argv, argv + argc, validatorArgv_ + validatorInvocationSize); std::copy(validatorOptions, validatorOptions + numValidatorOptions, validatorArgv_ + validatorInvocationSize + argc); validatorArgv_[validatorArgc_ - 1] = "-ferror-limit=0"; validatorArgv_[validatorArgc_ - 2] = "-fno-builtin"; validatorArgv_[validatorArgc_ - 3] = "-ffreestanding"; }
WebCLArguments::WebCLArguments(int argc, char const *argv[]) : preprocessorArgc_(0) , preprocessorArgv_(NULL) , validatorArgc_(0) , validatorArgv_(NULL) , matcherArgv_() , files_() , outputs_() { char const *commandName = argv[0]; char const *inputFilename = argv[1]; const int userOptionOffset = 2; const int numUserOptions = argc - userOptionOffset; assert((argc >= userOptionOffset) && "Expected at least executable name and input file in argv."); char const *buffer = reinterpret_cast<char const*>(kernel_endlfix_cl); size_t length = kernel_endlfix_cl_len; int headerDescriptor = -1; char const *headerFilename = createFullTemporaryFile(headerDescriptor, buffer, length); if (!headerFilename) return; files_.push_back(TemporaryFile(-1, headerFilename)); close(headerDescriptor); char const *preprocessorInvocation[] = { commandName, inputFilename, "--" }; const int preprocessorInvocationSize = sizeof(preprocessorInvocation) / sizeof(preprocessorInvocation[0]); char const *preprocessorOptions[] = { "-E", "-x", "cl" }; const int numPreprocessorOptions = sizeof(preprocessorOptions) / sizeof(preprocessorOptions[0]); char const *validatorInvocation[] = { commandName, NULL, "--" }; const int validatorInvocationSize = sizeof(validatorInvocation) / sizeof(validatorInvocation[0]); char const *validatorOptions[] = { "-x", "cl", "-ffake-address-space-map", "-include", headerFilename }; const int numValidatorOptions = sizeof(validatorOptions) / sizeof(validatorOptions[0]); preprocessorArgc_ = preprocessorInvocationSize + numPreprocessorOptions; validatorArgc_ = validatorInvocationSize + numUserOptions + numValidatorOptions; preprocessorArgv_ = new char const *[preprocessorArgc_]; if (!preprocessorArgv_) { std::cerr << "Internal error. Can't create argument list for preprocessor." << std::endl; return; } validatorArgv_ = new char const *[validatorArgc_]; if (!validatorArgv_) { std::cerr << "Internal error. Can't create argument list for validator." << std::endl; return; } // preprocessor arguments std::copy(preprocessorInvocation, preprocessorInvocation + preprocessorInvocationSize, preprocessorArgv_); std::copy(preprocessorOptions, preprocessorOptions + numPreprocessorOptions, preprocessorArgv_ + preprocessorInvocationSize); // validator arguments std::copy(validatorInvocation, validatorInvocation + validatorInvocationSize, validatorArgv_); std::copy(argv + userOptionOffset, argv + userOptionOffset + numUserOptions, validatorArgv_ + validatorInvocationSize); std::copy(validatorOptions, validatorOptions + numValidatorOptions, validatorArgv_ + validatorInvocationSize + numUserOptions); }