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 178b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Basic/DiagnosticOptions.h" 18b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/DriverDiagnostic.h" 19a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "clang/Driver/Options.h" 20b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/TextDiagnosticPrinter.h" 218f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "clang/Frontend/Utils.h" 22b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h" 24be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h" 25b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 26a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/OptTable.h" 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/CommandLine.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h" 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h" 30be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h" 31ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#include "llvm/Support/raw_ostream.h" 32c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h" 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 348b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "rs_cc_options.h" 35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h" 366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 378f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h" 38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h" 39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h" 40b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 418b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <list> 428b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <set> 438b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <string> 44b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 45b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from 46b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in 47b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main(). 48b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings, 49b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::StringRef S) { 50b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return SavedStrings.insert(S).first->c_str(); 51b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 52b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg, 53b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 54b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings); 55b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv, 56b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 57b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings); 58b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 59b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir, 609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const std::string &PathSuffix, 61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *InputFile, 62e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::OutputType OutputType, 63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 64e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (OutputType == slang::Slang::OT_Nothing) 65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return "/dev/null"; 66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string OutputFile(OutputDir); 68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 697f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines // Append '/' to Opts.mBitcodeOutputDir if not presents 70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (!OutputFile.empty() && 718d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR) 728d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael OutputFile.append(1, OS_PATH_SEPARATOR); 73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (!PathSuffix.empty()) { 759ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines OutputFile.append(PathSuffix); 769ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines OutputFile.append(1, OS_PATH_SEPARATOR); 779ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 789ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 79e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (OutputType == slang::Slang::OT_Dependency) { 80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // The build system wants the .d file name stem to be exactly the same as 81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // the source .rs file, instead of the .bc file. 82e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile)); 83e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 84e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines OutputFile.append( 85e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile)); 86e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } 87b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 88e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines switch (OutputType) { 89e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Dependency: { 90b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".d"); 91b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 92b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Assembly: { 94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".S"); 95b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 96b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 97e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_LLVMAssembly: { 98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".ll"); 99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 101e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Object: { 102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".o"); 103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 105e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Bitcode: { 106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputFile.append(".bc"); 107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 109e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines case slang::Slang::OT_Nothing: 110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao default: { 1116e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Invalid output type!"); 112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return SaveStringInSet(SavedStrings, OutputFile); 116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 1189ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinestypedef std::list<std::pair<const char*, const char*> > NamePairList; 1199ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1209ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines/* 1219ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Compile the Inputs. 1229ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 1239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Returns 0 on success and nonzero on failure. 1249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 1259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles - list of (foo.rs, foo.bc) pairs of input/output files. 1269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32 - list of input/output pairs for 32-bit compilation. 1279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Inputs - input filenames. 1289ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Opts - options controlling compilation. 1299ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagEngine - Clang diagnostic engine (for creating diagnostics). 1309ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagClient - Slang diagnostic consumer (collects and displays diagnostics). 1319ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * SavedStrings - expanded strings copied from argv source input files. 1329ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 1339ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * We populate IOFiles dynamically while working through the list of Inputs. 1349ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * On any 64-bit compilation, we pass back in the 32-bit pairs of files as 1359ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32. This allows the 64-bit compiler to later bundle up both the 1369ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 32-bit and 64-bit bitcode outputs to be included in the final reflected 1379ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * source code that is emitted. 1389ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines */ 1399ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic int compileFiles(NamePairList *IOFiles, NamePairList *IOFiles32, 1409ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts, 1419ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines clang::DiagnosticsEngine *DiagEngine, slang::DiagnosticBuffer *DiagClient, 1429ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines std::set<std::string> *SavedStrings) { 1439ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines NamePairList DepFiles; 1449ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines std::string PathSuffix = ""; 1452d504fd03c66be56ac3b4bb62c78cc72c75dd8b6Stephen Hines bool CompileSecondTimeFor64Bit = false; 1469ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1479ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // In our mixed 32/64-bit path, we need to suffix our files differently for 1489ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // both 32-bit and 64-bit versions. 1499ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (Opts.mEmit3264) { 1509ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (Opts.mBitWidth == 64) { 1519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines PathSuffix = "bc64"; 1522d504fd03c66be56ac3b4bb62c78cc72c75dd8b6Stephen Hines CompileSecondTimeFor64Bit = true; 1539ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } else { 1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines PathSuffix = "bc32"; 1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines for (int i = 0, e = Inputs.size(); i != e; i++) { 1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const char *InputFile = Inputs[i]; 1609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1619ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const char *BCOutputFile = DetermineOutputFile(Opts.mBitcodeOutputDir, 1629ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines PathSuffix, InputFile, 1639ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines slang::Slang::OT_Bitcode, 1649ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *SavedStrings); 1659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const char *OutputFile = BCOutputFile; 1669ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1679ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (Opts.mEmitDependency) { 1689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // The dependency file is always emitted without a PathSuffix. 1699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // Collisions between 32-bit and 64-bit files don't make a difference, 1709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // because they share the same sources/dependencies. 1719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const char *DepOutputFile = 1729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DetermineOutputFile(Opts.mDependencyOutputDir, "", InputFile, 1739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines slang::Slang::OT_Dependency, *SavedStrings); 1749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (Opts.mOutputType == slang::Slang::OT_Dependency) { 1759ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines OutputFile = DepOutputFile; 1769ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1779ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1789ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile)); 1799ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1809ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1819ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines IOFiles->push_back(std::make_pair(InputFile, OutputFile)); 1829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1847ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines std::unique_ptr<slang::SlangRS> Compiler(new slang::SlangRS()); 1859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines Compiler->init(Opts.mBitWidth, DiagEngine, DiagClient); 1869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines int CompileFailed = !Compiler->compile(*IOFiles, *IOFiles32, DepFiles, Opts); 1872d504fd03c66be56ac3b4bb62c78cc72c75dd8b6Stephen Hines // We suppress warnings (via reset) if we are doing a second compilation. 1882d504fd03c66be56ac3b4bb62c78cc72c75dd8b6Stephen Hines Compiler->reset(CompileSecondTimeFor64Bit); 1899ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return CompileFailed; 1909ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines} 1919ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 192ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s 193ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s) 194ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() { 195ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines llvm::raw_ostream &OS = llvm::outs(); 196ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << "llvm-rs-cc: Renderscript compiler\n" 197ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << " (http://developer.android.com/guide/topics/renderscript)\n" 198ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << " based on LLVM (http://llvm.org):\n"; 199ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " Built " << __DATE__ << " (" << __TIME__ ").\n"; 200ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " Target APIs: " << SLANG_MINIMUM_TARGET_API << " - " 201ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines << SLANG_MAXIMUM_TARGET_API; 202ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << "\n Build type: " << wrap_str(TARGET_BUILD_VARIANT); 203ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS 204ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << " with assertions"; 205ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif 206ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines OS << ".\n"; 207ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines} 2088f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str 2098f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str 210ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines 211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) { 212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> SavedStrings; 213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVector<const char*, 256> ArgVector; 2148b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines slang::RSCCOptions Opts; 215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVector<const char*, 16> Inputs; 216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string Argv0; 217b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2189ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgv(argc, argv, ArgVector, SavedStrings); 221b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Argv0 2236f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien Argv0 = llvm::sys::path::stem(ArgVector[0]); 224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 225b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Setup diagnostic engine 2268f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer(); 227be27482cdeaf08576bc39b72a15d35d13014a636Logan 228be27482cdeaf08576bc39b72a15d35d13014a636Logan llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs( 229be27482cdeaf08576bc39b72a15d35d13014a636Logan new clang::DiagnosticIDs()); 230be27482cdeaf08576bc39b72a15d35d13014a636Logan 23123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( 23223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines new clang::DiagnosticOptions()); 23323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, DiagClient, true); 2349207a2e495c8363606861e4f034504ec5c153dabLogan Chien 235e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines slang::Slang::GlobalInitialization(); 236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2378b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines slang::ParseArguments(ArgVector, Inputs, Opts, DiagEngine); 238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // Exits when there's any error occurred during parsing the arguments 2408f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines if (DiagEngine.hasErrorOccurred()) { 2418f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines llvm::errs() << DiagClient->str(); 242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 1; 2438f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines } 244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 245b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Opts.mShowHelp) { 2467ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines std::unique_ptr<llvm::opt::OptTable> OptTbl(slang::createRSCCOptTable()); 247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(), 248b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines "Renderscript source compiler"); 249b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 0; 250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Opts.mShowVersion) { 253ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines llvm_rs_cc_VersionPrinter(); 254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 0; 255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 256b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 257b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao // No input file 258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Inputs.empty()) { 2599207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report(clang::diag::err_drv_no_input_files); 2608f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines llvm::errs() << DiagClient->str(); 261b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return 1; 262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 264cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang // Prepare input data for RS compiler. 2659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines NamePairList IOFiles64; 2669ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines NamePairList IOFiles32; 267b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 2689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines int CompileFailed = compileFiles(&IOFiles32, &IOFiles32, Inputs, Opts, 2699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines &DiagEngine, DiagClient, &SavedStrings); 270cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 2719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // Handle the 64-bit case too! 2729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (Opts.mEmit3264 && !CompileFailed) { 2739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines Opts.mBitWidth = 64; 2749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines CompileFailed = compileFiles(&IOFiles64, &IOFiles32, Inputs, Opts, 2759ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines &DiagEngine, DiagClient, &SavedStrings); 276cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang } 277cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 278d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines return CompileFailed; 279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 280b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 281b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao/////////////////////////////////////////////////////////////////////////////// 282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf - 284b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg, 285b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *FName = Arg + 1; 2887ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr = 2897ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines llvm::MemoryBuffer::getFile(FName); 2907ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines if (MBOrErr.getError()) { 291be27482cdeaf08576bc39b72a15d35d13014a636Logan // Unable to open the file 292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, Arg)); 293b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return; 294b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 2957ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines std::unique_ptr<llvm::MemoryBuffer> MemBuf = std::move(MBOrErr.get()); 296b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 297b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *Buf = MemBuf->getBufferStart(); 298b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao char InQuote = ' '; 299b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string CurArg; 300b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 301b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (const char *P = Buf; ; ++P) { 302b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\0' || (isspace(*P) && InQuote == ' ')) { 303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (!CurArg.empty()) { 304b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (CurArg[0] != '@') { 305b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg)); 306b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } else { 307b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings); 308b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 309b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 310b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg = ""; 311b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 312b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\0') 313b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao break; 314b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else 315b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 316b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 317b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 318b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (isspace(*P)) { 319b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (InQuote != ' ') 320b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 321b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 323b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '"' || *P == '\'') { 325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (InQuote == *P) 326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao InQuote = ' '; 327b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else if (InQuote == ' ') 328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao InQuote = *P; 329b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao else 330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 331b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 333b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P == '\\') { 335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ++P; 336b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (*P != '\0') 337b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 339b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 340b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CurArg.push_back(*P); 341b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 342b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 343b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 344b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf - 345b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv, 346b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao llvm::SmallVectorImpl<const char*> &ArgVector, 347b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::set<std::string> &SavedStrings) { 348b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao for (int i = 0; i < argc; ++i) { 349b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const char *Arg = argv[i]; 350b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (Arg[0] != '@') { 351b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg))); 352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao continue; 353b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 355b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ExpandArgsFromBuf(Arg, ArgVector, SavedStrings); 356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao } 357b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao} 358