llvm-rs-cc.cpp revision 23c4358f12bd9d0ba7166eceebd683db95a41b3f
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 20a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 17e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <cstdlib> 18e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 19b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <set> 20b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <string> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utility> 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector> 23b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 24b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/Arg.h" 25b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/ArgList.h" 26b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/DriverDiagnostic.h" 27b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/Option.h" 28b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/OptTable.h" 29b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 3023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Basic/DiagnosticOptions.h" 31b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/TextDiagnosticPrinter.h" 328f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "clang/Frontend/Utils.h" 33b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h" 35be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h" 36be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/OwningPtr.h" 37b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/CommandLine.h" 39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h" 40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h" 41be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h" 42ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#include "llvm/Support/raw_ostream.h" 43be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/system_error.h" 44c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h" 45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h" 476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 488f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h" 49e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h" 50e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h" 51b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 52b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// Class under clang::driver used are enumerated here. 53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::arg_iterator; 54e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::options::DriverOption; 55b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Arg; 56b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::ArgList; 57b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::InputArgList; 58b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Option; 59b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::OptTable; 6043730fe3c839af391efe6bdf56b0479860121924Shih-wei Liaousing namespace clang::driver::options; 61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 62b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from 63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in 64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main(). 65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings, 66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::StringRef S) { 67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return SavedStrings.insert(S).first->c_str(); 68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg, 70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 71b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings); 72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv, 73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings); 75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoenum { 77b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OPT_INVALID = 0, // This is not an option ID. 7823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE) 7923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ 80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao HELPTEXT, METAVAR) OPT_##ID, 81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc" 82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao LastOption 83b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION 8423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX 85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}; 86b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 8723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 8823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ 8923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines HELPTEXT, METAVAR) 9023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "RSCCOptions.inc" 9123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION 9223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX 9323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines 94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = { 9523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE) 9623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ 97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao HELPTEXT, METAVAR) \ 9823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \ 9923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines FLAGS, OPT_##GROUP, OPT_##ALIAS }, 100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc" 10123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION 10223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX 103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}; 104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable { 106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public: 107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RSCCOptTable() 108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao : OptTable(RSCCInfoTable, 109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) { 110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}; 112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() { 114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return new RSCCOptTable(); 115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao/////////////////////////////////////////////////////////////////////////////// 118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions { 120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public: 121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The include search paths 122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::vector<std::string> mIncludePaths; 123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The output directory, if any. 125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mOutputDir; 126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 127b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The output type 128e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::OutputType mOutputType; 129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao unsigned mAllowRSPrefix : 1; 131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 132b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines // The name of the target triple to compile for. 133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mTriple; 134b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 135b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines // The name of the target CPU to generate code for. 136b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mCPU; 137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The list of target specific features to enable or disable -- this should 139b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // be a list of strings starting with by '+' or '-'. 140b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::vector<std::string> mFeatures; 141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mJavaReflectionPathBase; 143b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 144b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mJavaReflectionPackageName; 145b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 1460a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines std::string mRSPackageName; 1470a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines 148e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::BitCodeStorageType mBitcodeStorage; 149b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 150b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao unsigned mOutputDep : 1; 151b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 152b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string mOutputDepDir; 153b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 154b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::vector<std::string> mAdditionalDepTargets; 155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 156b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao unsigned mShowHelp : 1; // Show the -help text. 157b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao unsigned mShowVersion : 1; // Show the -version text. 158b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 1592e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines unsigned int mTargetAPI; 1602e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines 161c460b37ffb50819a32c2a8967754b6f784b28263mkopec // Enable emission of debugging symbols 162c460b37ffb50819a32c2a8967754b6f784b28263mkopec unsigned mDebugEmission : 1; 163c460b37ffb50819a32c2a8967754b6f784b28263mkopec 164c460b37ffb50819a32c2a8967754b6f784b28263mkopec // The optimization level used in CodeGen, and encoded in emitted bitcode 165c460b37ffb50819a32c2a8967754b6f784b28263mkopec llvm::CodeGenOpt::Level mOptimizationLevel; 166c460b37ffb50819a32c2a8967754b6f784b28263mkopec 167b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RSCCOptions() { 168e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines mOutputType = slang::Slang::OT_Bitcode; 169b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines // Triple/CPU/Features must be hard-coded to our chosen portable ABI. 170b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines mTriple = "armv7-none-linux-gnueabi"; 171b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines mCPU = ""; 172b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines slangAssert(mFeatures.empty()); 17318ca8cfc2b9e60e4aa4b4269e2b02c5f6f245822Stephen Hines mFeatures.push_back("+long64"); 174e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines mBitcodeStorage = slang::BCST_APK_RESOURCE; 175b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mOutputDep = 0; 176b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mShowHelp = 0; 177b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mShowVersion = 0; 1782e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines mTargetAPI = RS_VERSION; 179c460b37ffb50819a32c2a8967754b6f784b28263mkopec mDebugEmission = 0; 180c460b37ffb50819a32c2a8967754b6f784b28263mkopec mOptimizationLevel = llvm::CodeGenOpt::Aggressive; 181b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}; 183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments - 185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector, 186b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &Inputs, 187b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RSCCOptions &Opts, 1889207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine &DiagEngine) { 189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (ArgVector.size() > 1) { 190b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char **ArgBegin = ArgVector.data() + 1; 191b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char **ArgEnd = ArgVector.data() + ArgVector.size(); 192b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao unsigned MissingArgIndex, MissingArgCount; 193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable()); 194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::OwningPtr<InputArgList> Args( 195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount)); 196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Check for missing argument error. 198b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (MissingArgCount) 1999207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_missing_argument) 200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << Args->getArgString(MissingArgIndex) << MissingArgCount; 201b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2028f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines clang::DiagnosticOptions DiagOpts; 2038f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w); 2048f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines DiagOpts.Warnings = Args->getAllArgValues(OPT_W); 2058f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines clang::ProcessWarningOptions(DiagEngine, DiagOpts); 2068f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines 207b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Issue errors on unknown arguments. 208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), 209b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ie = Args->filtered_end(); it != ie; ++it) 2109207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_unknown_argument) 211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << (*it)->getAsString(*Args); 212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); 214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao it != ie; ++it) { 215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const Arg *A = *it; 216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (A->getOption().getKind() == Option::InputClass) 21723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines Inputs.push_back(A->getValue()); 218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mIncludePaths = Args->getAllArgValues(OPT_I); 221b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mOutputDir = Args->getLastArgValue(OPT_o); 223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (const Arg *A = Args->getLastArg(OPT_M_Group)) { 225b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao switch (A->getOption().getID()) { 226b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_M: { 227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mOutputDep = 1; 228e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_Dependency; 229b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_MD: { 232b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mOutputDep = 1; 233e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_Bitcode; 234190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott break; 235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao default: { 2376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Invalid option in M group!"); 238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 241b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) { 243b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao switch (A->getOption().getID()) { 244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_emit_asm: { 245e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_Assembly; 246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 248b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_emit_llvm: { 249e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_LLVMAssembly; 250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_emit_bc: { 253e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_Bitcode; 254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 256b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao case OPT_emit_nothing: { 257e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mOutputType = slang::Slang::OT_Nothing; 258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 259b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 260b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao default: { 2616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Invalid option in output type group!"); 262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 266e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang if (Opts.mOutputDep && 267e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ((Opts.mOutputType != slang::Slang::OT_Bitcode) && 268e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines (Opts.mOutputType != slang::Slang::OT_Dependency))) 2699207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with) 270b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << Args->getLastArg(OPT_M_Group)->getAsString(*Args) 271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args); 272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix); 274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mJavaReflectionPathBase = 276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Args->getLastArgValue(OPT_java_reflection_path_base); 277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mJavaReflectionPackageName = 278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Args->getLastArgValue(OPT_java_reflection_package_name); 279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2800a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name); 2810a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines 282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::StringRef BitcodeStorageValue = 283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Args->getLastArgValue(OPT_bitcode_storage); 284b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (BitcodeStorageValue == "ar") 285e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE; 286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else if (BitcodeStorageValue == "jc") 287e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Opts.mBitcodeStorage = slang::BCST_JAVA_CODE; 288b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else if (!BitcodeStorageValue.empty()) 2899207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_invalid_value) 290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << OptParser->getOptionName(OPT_bitcode_storage) 291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao << BitcodeStorageValue; 292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2935c25c5159c0a5be9af992679067790716626da7bStephen Hines if (Args->hasArg(OPT_reflect_cpp)) { 2945c25c5159c0a5be9af992679067790716626da7bStephen Hines Opts.mBitcodeStorage = slang::BCST_CPP_CODE; 295b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray // mJavaReflectionPathBase isn't set for C++ reflected builds 296b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray // set it to mOutputDir so we can use the path sanely from 297b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray // RSReflectionBase later on 298b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray Opts.mJavaReflectionPathBase = Opts.mOutputDir; 2995c25c5159c0a5be9af992679067790716626da7bStephen Hines } 3005c25c5159c0a5be9af992679067790716626da7bStephen Hines 301b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mOutputDepDir = 302b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir); 303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mAdditionalDepTargets = 304b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Args->getAllArgValues(OPT_additional_dep_target); 305b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 306b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mShowHelp = Args->hasArg(OPT_help); 307b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao Opts.mShowVersion = Args->hasArg(OPT_version); 308c460b37ffb50819a32c2a8967754b6f784b28263mkopec Opts.mDebugEmission = Args->hasArg(OPT_emit_g); 309c460b37ffb50819a32c2a8967754b6f784b28263mkopec 310c460b37ffb50819a32c2a8967754b6f784b28263mkopec size_t OptLevel = Args->getLastArgIntValue(OPT_optimization_level, 311c460b37ffb50819a32c2a8967754b6f784b28263mkopec 3, 312c460b37ffb50819a32c2a8967754b6f784b28263mkopec DiagEngine); 313c460b37ffb50819a32c2a8967754b6f784b28263mkopec 314c460b37ffb50819a32c2a8967754b6f784b28263mkopec Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None 315c460b37ffb50819a32c2a8967754b6f784b28263mkopec : llvm::CodeGenOpt::Aggressive; 3162e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines 3172e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api, 3182e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines RS_VERSION, 3199207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine); 320b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 321b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return; 323b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir, 326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *InputFile, 327e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::OutputType OutputType, 328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 329e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (OutputType == slang::Slang::OT_Nothing) 330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return "/dev/null"; 331b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string OutputFile(OutputDir); 333b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Append '/' to Opts.mOutputDir if not presents 335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (!OutputFile.empty() && 3368d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR) 3378d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael OutputFile.append(1, OS_PATH_SEPARATOR); 338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 339e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (OutputType == slang::Slang::OT_Dependency) { 340b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The build system wants the .d file name stem to be exactly the same as 341b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // the source .rs file, instead of the .bc file. 342e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile)); 343e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 344e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines OutputFile.append( 345e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile)); 346e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } 347b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 348e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines switch (OutputType) { 349e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Dependency: { 350b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".d"); 351b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 353e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Assembly: { 354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".S"); 355b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 357e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_LLVMAssembly: { 358b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".ll"); 359b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 361e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Object: { 362b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".o"); 363b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 364b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 365e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Bitcode: { 366b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".bc"); 367b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 368b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 369e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Nothing: 370b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao default: { 3716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Invalid output type!"); 372b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 373b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 374b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 375b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return SaveStringInSet(SavedStrings, OutputFile); 376b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 377b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 378ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s 379ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s) 380ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() { 381ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines llvm::raw_ostream &OS = llvm::outs(); 382ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << "llvm-rs-cc: Renderscript compiler\n" 383ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << " (http://developer.android.com/guide/topics/renderscript)\n" 384ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << " based on LLVM (http://llvm.org):\n"; 385ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " Built " << __DATE__ << " (" << __TIME__ ").\n"; 386ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " Target APIs: " << SLANG_MINIMUM_TARGET_API << " - " 387ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << SLANG_MAXIMUM_TARGET_API; 388ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << "\n Build type: " << wrap_str(TARGET_BUILD_VARIANT); 389ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS 390ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " with assertions"; 391ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif 392ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << ".\n"; 393ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines return; 394ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines} 3958f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str 3968f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str 397ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines 398b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) { 399b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> SavedStrings; 400b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVector<const char*, 256> ArgVector; 401b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RSCCOptions Opts; 402b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVector<const char*, 16> Inputs; 403b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string Argv0; 404b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 405b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao atexit(llvm::llvm_shutdown); 406b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 407b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgv(argc, argv, ArgVector, SavedStrings); 408b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 409b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Argv0 4106f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien Argv0 = llvm::sys::path::stem(ArgVector[0]); 411b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 412b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Setup diagnostic engine 4138f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer(); 414be27482cdeaf08576bc39b72a15d35d13014a636Logan 415be27482cdeaf08576bc39b72a15d35d13014a636Logan llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs( 416be27482cdeaf08576bc39b72a15d35d13014a636Logan new clang::DiagnosticIDs()); 417be27482cdeaf08576bc39b72a15d35d13014a636Logan 41823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( 41923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines new clang::DiagnosticOptions()); 42023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, DiagClient, true); 4219207a2e495c8363606861e4f034504ec5c153dabLogan Chien 422e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::GlobalInitialization(); 423b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 4249207a2e495c8363606861e4f034504ec5c153dabLogan Chien ParseArguments(ArgVector, Inputs, Opts, DiagEngine); 425b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 426b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Exits when there's any error occurred during parsing the arguments 4278f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines if (DiagEngine.hasErrorOccurred()) { 4288f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines llvm::errs() << DiagClient->str(); 429b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 1; 4308f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines } 431b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 432b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Opts.mShowHelp) { 433b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable()); 434b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(), 435b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines "Renderscript source compiler"); 436b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 0; 437b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 438b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 439b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Opts.mShowVersion) { 440ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines llvm_rs_cc_VersionPrinter(); 441b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 0; 442b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 443b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 444b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // No input file 445b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Inputs.empty()) { 4469207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_no_input_files); 4478f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines llvm::errs() << DiagClient->str(); 448b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 1; 449b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 450b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 451cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang // Prepare input data for RS compiler. 452cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang std::list<std::pair<const char*, const char*> > IOFiles; 453cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang std::list<std::pair<const char*, const char*> > DepFiles; 454cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 455e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS()); 456641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 4578f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine, 4588f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines DiagClient); 459b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 460b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (int i = 0, e = Inputs.size(); i != e; i++) { 461cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const char *InputFile = Inputs[i]; 462cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const char *OutputFile = 463cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang DetermineOutputFile(Opts.mOutputDir, InputFile, 464cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang Opts.mOutputType, SavedStrings); 465cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 466b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Opts.mOutputDep) { 467cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const char *BCOutputFile, *DepOutputFile; 468e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang 469e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (Opts.mOutputType == slang::Slang::OT_Bitcode) 470e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang BCOutputFile = OutputFile; 471e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang else 472e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir, 473e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines InputFile, 474e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::OT_Bitcode, 475e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines SavedStrings); 476cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 477e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (Opts.mOutputType == slang::Slang::OT_Dependency) 478cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang DepOutputFile = OutputFile; 479cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang else 480e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, 481e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines InputFile, 482e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::OT_Dependency, 483e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines SavedStrings); 484cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 485cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile)); 486b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 487cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 488cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang IOFiles.push_back(std::make_pair(InputFile, OutputFile)); 489cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang } 490cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 491cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang // Let's rock! 492d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines int CompileFailed = !Compiler->compile(IOFiles, 493d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines DepFiles, 494d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mIncludePaths, 495d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mAdditionalDepTargets, 496d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mOutputType, 497d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mBitcodeStorage, 498d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mAllowRSPrefix, 499d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mOutputDep, 5002e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines Opts.mTargetAPI, 501c460b37ffb50819a32c2a8967754b6f784b28263mkopec Opts.mDebugEmission, 502c460b37ffb50819a32c2a8967754b6f784b28263mkopec Opts.mOptimizationLevel, 503d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines Opts.mJavaReflectionPathBase, 5040a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines Opts.mJavaReflectionPackageName, 5050a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines Opts.mRSPackageName); 5065c25c5159c0a5be9af992679067790716626da7bStephen Hines 507c632be206ac4fe49a5db05cfa54942d774329dbeStephen Hines Compiler->reset(); 508d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines 509d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines return CompileFailed; 510b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 511b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 512b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao/////////////////////////////////////////////////////////////////////////////// 513b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 514b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf - 515b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg, 516b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 517b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 518b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *FName = Arg + 1; 519be27482cdeaf08576bc39b72a15d35d13014a636Logan llvm::OwningPtr<llvm::MemoryBuffer> MemBuf; 520be27482cdeaf08576bc39b72a15d35d13014a636Logan if (llvm::MemoryBuffer::getFile(FName, MemBuf)) { 521be27482cdeaf08576bc39b72a15d35d13014a636Logan // Unable to open the file 522b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); 523b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return; 524b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 525b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 526b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *Buf = MemBuf->getBufferStart(); 527b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao char InQuote = ' '; 528b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string CurArg; 529b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 530b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (const char *P = Buf; ; ++P) { 531b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { 532b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (!CurArg.empty()) { 533b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (CurArg[0] != '@') { 534b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); 535b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } else { 536b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); 537b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 538b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 539b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg = ""; 540b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 541b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\0') 542b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 543b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else 544b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 545b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 546b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 547b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (isspace(*P)) { 548b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (InQuote != ' ') 549b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 550b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 551b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 552b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 553b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '"' || *P == '\'') { 554b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (InQuote == *P) 555b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao InQuote = ' '; 556b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else if (InQuote == ' ') 557b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao InQuote = *P; 558b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else 559b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 560b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 561b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 562b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 563b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\\') { 564b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ++P; 565b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P != '\0') 566b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 567b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 568b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 569b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 570b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 571b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 572b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 573b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf - 574b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv, 575b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 576b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 577b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (int i = 0; i < argc; ++i) { 578b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *Arg = argv[i]; 579b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Arg[0] != '@') { 580b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); 581b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 582b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 583b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 584b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); 585b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 586b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 587