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
30b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/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.
78b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
79b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR) OPT_##ID,
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  LastOption
82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION
83b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
84b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = {
86b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
87b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR)   \
8843730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  { NAME, HELPTEXT, METAVAR, Option::KIND##Class, PARAM, FLAGS, \
89b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OPT_##GROUP, OPT_##ALIAS },
90b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
91b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
92b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
93b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable {
94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
95b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptTable()
96b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      : OptTable(RSCCInfoTable,
97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
101b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() {
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return new RSCCOptTable();
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions {
108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The include search paths
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mIncludePaths;
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output directory, if any.
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDir;
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output type
116e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::OutputType mOutputType;
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mAllowRSPrefix : 1;
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
120b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target triple to compile for.
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mTriple;
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
123b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target CPU to generate code for.
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mCPU;
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The list of target specific features to enable or disable -- this should
127b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // be a list of strings starting with by '+' or '-'.
128b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mFeatures;
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPathBase;
131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
132b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPackageName;
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1340a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines  std::string mRSPackageName;
1350a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
136e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::BitCodeStorageType mBitcodeStorage;
137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mOutputDep : 1;
139b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
140b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDepDir;
141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mAdditionalDepTargets;
143b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
144b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowHelp : 1;  // Show the -help text.
145b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowVersion : 1;  // Show the -version text.
146b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1472e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines  unsigned int mTargetAPI;
1482e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
149c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Enable emission of debugging symbols
150c460b37ffb50819a32c2a8967754b6f784b28263mkopec  unsigned mDebugEmission : 1;
151c460b37ffb50819a32c2a8967754b6f784b28263mkopec
152c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // The optimization level used in CodeGen, and encoded in emitted bitcode
153c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::CodeGenOpt::Level mOptimizationLevel;
154c460b37ffb50819a32c2a8967754b6f784b28263mkopec
155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions() {
156e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mOutputType = slang::Slang::OT_Bitcode;
157b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
158b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mTriple = "armv7-none-linux-gnueabi";
159b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mCPU = "";
160b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    slangAssert(mFeatures.empty());
16118ca8cfc2b9e60e4aa4b4269e2b02c5f6f245822Stephen Hines    mFeatures.push_back("+long64");
162e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mBitcodeStorage = slang::BCST_APK_RESOURCE;
163b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mOutputDep = 0;
164b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowHelp = 0;
165b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowVersion = 0;
1662e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    mTargetAPI = RS_VERSION;
167c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mDebugEmission = 0;
168c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
169b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
170b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
171b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
172b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments -
173b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
174b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           llvm::SmallVectorImpl<const char*> &Inputs,
175b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           RSCCOptions &Opts,
1769207a2e495c8363606861e4f034504ec5c153dabLogan Chien                           clang::DiagnosticsEngine &DiagEngine) {
177b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (ArgVector.size() > 1) {
178b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgBegin = ArgVector.data() + 1;
179b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgEnd = ArgVector.data() + ArgVector.size();
180b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    unsigned MissingArgIndex, MissingArgCount;
181b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<InputArgList> Args(
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Check for missing argument error.
186b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (MissingArgCount)
1879207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_missing_argument)
188b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << Args->getArgString(MissingArgIndex) << MissingArgCount;
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1908f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::DiagnosticOptions DiagOpts;
1918f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
1928f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
1938f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::ProcessWarningOptions(DiagEngine, DiagOpts);
1948f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines
195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Issue errors on unknown arguments.
196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        ie = Args->filtered_end(); it != ie; ++it)
1989207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
199b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << (*it)->getAsString(*Args);
200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
201b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
202b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        it != ie; ++it) {
203b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      const Arg *A = *it;
204b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (A->getOption().getKind() == Option::InputClass)
205b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Inputs.push_back(A->getValue(*Args));
206b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
207b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
209b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
210b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDir = Args->getLastArgValue(OPT_o);
211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_M: {
215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
216e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
217b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_MD: {
220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
221e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
222190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott          break;
223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2256e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in M group!");
226b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
228b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
229b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
232b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_asm: {
233e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
234b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_llvm: {
237e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_bc: {
241e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
243b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_nothing: {
245e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
248b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in output type group!");
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
253b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
254e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (Opts.mOutputDep &&
255e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
256e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
2579207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
259b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
260b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
261b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPathBase =
264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_path_base);
265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPackageName =
266b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_package_name);
267b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2680a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines    Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);
2690a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
270b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::StringRef BitcodeStorageValue =
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_bitcode_storage);
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (BitcodeStorageValue == "ar")
273e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (BitcodeStorageValue == "jc")
275e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (!BitcodeStorageValue.empty())
2779207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_invalid_value)
278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << OptParser->getOptionName(OPT_bitcode_storage)
279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << BitcodeStorageValue;
280b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2815c25c5159c0a5be9af992679067790716626da7bStephen Hines    if (Args->hasArg(OPT_reflect_cpp)) {
2825c25c5159c0a5be9af992679067790716626da7bStephen Hines      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
2835c25c5159c0a5be9af992679067790716626da7bStephen Hines    }
2845c25c5159c0a5be9af992679067790716626da7bStephen Hines
285b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDepDir =
286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAdditionalDepTargets =
288b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getAllArgValues(OPT_additional_dep_target);
289b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowHelp = Args->hasArg(OPT_help);
291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowVersion = Args->hasArg(OPT_version);
292c460b37ffb50819a32c2a8967754b6f784b28263mkopec    Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
293c460b37ffb50819a32c2a8967754b6f784b28263mkopec
294c460b37ffb50819a32c2a8967754b6f784b28263mkopec    size_t OptLevel = Args->getLastArgIntValue(OPT_optimization_level,
295c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                               3,
296c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                               DiagEngine);
297c460b37ffb50819a32c2a8967754b6f784b28263mkopec
298c460b37ffb50819a32c2a8967754b6f784b28263mkopec    Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None
299c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                            : llvm::CodeGenOpt::Aggressive;
3002e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
3012e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api,
3022e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                               RS_VERSION,
3039207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                               DiagEngine);
304b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
305b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
306b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
307b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
308b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
309b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
310b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
311e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
312b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       std::set<std::string> &SavedStrings) {
313e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
314b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
315b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
316b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
317b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
318b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Append '/' to Opts.mOutputDir if not presents
319b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
3208d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
3218d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
323e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
326e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
327e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
328e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
329e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
330e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
331b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
332e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
333e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
336b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
337e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
339b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
340b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
341e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
342b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
343b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
344b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
345e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
346b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
347b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
348b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
349e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
350b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
351b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
353e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
3556e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
357b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
358b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
359b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SaveStringInSet(SavedStrings, OutputFile);
360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
361b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
362ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
363ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
364ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
365ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
366ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
367ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
368ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
369ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Built " << __DATE__ << " (" << __TIME__ ").\n";
370ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
371ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << SLANG_MAXIMUM_TARGET_API;
372ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
373ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS
374ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << " with assertions";
375ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif
376ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << ".\n";
377ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  return;
378ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines}
3798f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str
3808f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str
381ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines
382b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) {
383b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::set<std::string> SavedStrings;
384b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 256> ArgVector;
385b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions Opts;
386b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 16> Inputs;
387b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string Argv0;
388b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
389b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  atexit(llvm::llvm_shutdown);
390b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
391b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ExpandArgv(argc, argv, ArgVector, SavedStrings);
392b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
393b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Argv0
3946f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien  Argv0 = llvm::sys::path::stem(ArgVector[0]);
395b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
396b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Setup diagnostic engine
3978f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer();
398be27482cdeaf08576bc39b72a15d35d13014a636Logan
399be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
400be27482cdeaf08576bc39b72a15d35d13014a636Logan    new clang::DiagnosticIDs());
401be27482cdeaf08576bc39b72a15d35d13014a636Logan
4029207a2e495c8363606861e4f034504ec5c153dabLogan Chien  clang::DiagnosticsEngine DiagEngine(DiagIDs, DiagClient, true);
4039207a2e495c8363606861e4f034504ec5c153dabLogan Chien
404e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::GlobalInitialization();
405b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
4069207a2e495c8363606861e4f034504ec5c153dabLogan Chien  ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
407b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
408b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Exits when there's any error occurred during parsing the arguments
4098f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  if (DiagEngine.hasErrorOccurred()) {
4108f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
411b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
4128f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  }
413b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
414b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
415b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
416b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
417b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines                      "Renderscript source compiler");
418b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
419b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
420b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
421b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
422ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines    llvm_rs_cc_VersionPrinter();
423b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
424b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
425b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
426b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // No input file
427b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
4289207a2e495c8363606861e4f034504ec5c153dabLogan Chien    DiagEngine.Report(clang::diag::err_drv_no_input_files);
4298f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
430b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
431b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
432b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
433cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Prepare input data for RS compiler.
434cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > IOFiles;
435cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > DepFiles;
436cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
437e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
438641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
4398f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine,
4408f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines                 DiagClient);
441b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
442b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0, e = Inputs.size(); i != e; i++) {
443cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *InputFile = Inputs[i];
444cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *OutputFile =
445cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DetermineOutputFile(Opts.mOutputDir, InputFile,
446cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            Opts.mOutputType, SavedStrings);
447cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
448b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Opts.mOutputDep) {
449cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      const char *BCOutputFile, *DepOutputFile;
450e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
451e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Bitcode)
452e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang        BCOutputFile = OutputFile;
453e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      else
454e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
455e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           InputFile,
456e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           slang::Slang::OT_Bitcode,
457e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           SavedStrings);
458cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
459e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency)
460cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DepOutputFile = OutputFile;
461cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      else
462e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
463e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            InputFile,
464e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            slang::Slang::OT_Dependency,
465e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            SavedStrings);
466cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
467cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
468b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
469cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
470cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
471cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
472cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
473cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Let's rock!
474d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  int CompileFailed = !Compiler->compile(IOFiles,
475d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         DepFiles,
476d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mIncludePaths,
477d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAdditionalDepTargets,
478d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputType,
479d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mBitcodeStorage,
480d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAllowRSPrefix,
481d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputDep,
4822e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                         Opts.mTargetAPI,
483c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mDebugEmission,
484c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mOptimizationLevel,
485d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mJavaReflectionPathBase,
4860a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mJavaReflectionPackageName,
4870a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mRSPackageName);
4885c25c5159c0a5be9af992679067790716626da7bStephen Hines
489c632be206ac4fe49a5db05cfa54942d774329dbeStephen Hines  Compiler->reset();
490d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines
491d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  return CompileFailed;
492b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
493b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
494b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
495b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
496b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
497b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
498b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
499b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings) {
500b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *FName = Arg + 1;
501be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
502be27482cdeaf08576bc39b72a15d35d13014a636Logan  if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
503be27482cdeaf08576bc39b72a15d35d13014a636Logan    // Unable to open the file
504b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
505b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return;
506b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
507b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
508b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *Buf = MemBuf->getBufferStart();
509b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  char InQuote = ' ';
510b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string CurArg;
511b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
512b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (const char *P = Buf; ; ++P) {
513b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
514b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (!CurArg.empty()) {
515b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        if (CurArg[0] != '@') {
516b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
517b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        } else {
518b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
519b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
520b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
521b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg = "";
522b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
523b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P == '\0')
524b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        break;
525b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
526b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        continue;
527b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
528b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
529b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (isspace(*P)) {
530b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote != ' ')
531b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
532b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
533b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
534b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
535b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '"' || *P == '\'') {
536b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote == *P)
537b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = ' ';
538b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else if (InQuote == ' ')
539b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = *P;
540b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
541b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
542b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
543b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
544b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
545b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\\') {
546b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ++P;
547b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P != '\0')
548b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
549b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
550b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
551b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    CurArg.push_back(*P);
552b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
553b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
554b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
555b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
556b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
557b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
558b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings) {
559b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0; i < argc; ++i) {
560b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char *Arg = argv[i];
561b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Arg[0] != '@') {
562b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
563b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
564b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
565b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
566b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
567b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
568b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
569