llvm-rs-cc.cpp revision 5c25c5159c0a5be9af992679067790716626da7b
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, 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"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
466e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
478f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h"
48e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h"
49e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
50b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
51b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// Class under clang::driver used are enumerated here.
52e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::arg_iterator;
53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::options::DriverOption;
54b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Arg;
55b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::ArgList;
56b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::InputArgList;
57b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Option;
58b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::OptTable;
59b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
60b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from
61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in
62b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main().
63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings,
64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                          llvm::StringRef S) {
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SavedStrings.insert(S).first->c_str();
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings);
70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
71b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings);
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoenum {
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  OPT_INVALID = 0,  // This is not an option ID.
76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
77b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR) OPT_##ID,
78b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
79b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  LastOption
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
83b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = {
84b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR)   \
86b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
87b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OPT_##GROUP, OPT_##ALIAS },
88b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
89b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
90b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
91b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable {
92b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
93b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptTable()
94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      : OptTable(RSCCInfoTable,
95b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
96b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() {
100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return new RSCCOptTable();
101b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions {
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The include search paths
108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mIncludePaths;
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output directory, if any.
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDir;
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output type
114e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::OutputType mOutputType;
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mAllowRSPrefix : 1;
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
118b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target triple to compile for.
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mTriple;
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
121b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target CPU to generate code for.
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mCPU;
123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The list of target specific features to enable or disable -- this should
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // be a list of strings starting with by '+' or '-'.
126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mFeatures;
127b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
128b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPathBase;
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPackageName;
131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
132e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::BitCodeStorageType mBitcodeStorage;
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
134b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mOutputDep : 1;
135b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
136b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDepDir;
137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mAdditionalDepTargets;
139b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
140b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowHelp : 1;  // Show the -help text.
141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowVersion : 1;  // Show the -version text.
142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1432e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines  unsigned int mTargetAPI;
1442e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
145b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions() {
146e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mOutputType = slang::Slang::OT_Bitcode;
147b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
148b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mTriple = "armv7-none-linux-gnueabi";
149b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mCPU = "";
150b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    slangAssert(mFeatures.empty());
15118ca8cfc2b9e60e4aa4b4269e2b02c5f6f245822Stephen Hines    mFeatures.push_back("+long64");
152e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mBitcodeStorage = slang::BCST_APK_RESOURCE;
153b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mOutputDep = 0;
154b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowHelp = 0;
155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowVersion = 0;
1562e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    mTargetAPI = RS_VERSION;
157b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
158b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
159b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
160b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments -
161b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
162b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           llvm::SmallVectorImpl<const char*> &Inputs,
163b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           RSCCOptions &Opts,
1649207a2e495c8363606861e4f034504ec5c153dabLogan Chien                           clang::DiagnosticsEngine &DiagEngine) {
165b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (ArgVector.size() > 1) {
166b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgBegin = ArgVector.data() + 1;
167b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgEnd = ArgVector.data() + ArgVector.size();
168b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    unsigned MissingArgIndex, MissingArgCount;
169b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
170b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<InputArgList> Args(
171b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
172b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
173b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Check for missing argument error.
174b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (MissingArgCount)
1759207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_missing_argument)
176b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << Args->getArgString(MissingArgIndex) << MissingArgCount;
177b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1788f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::DiagnosticOptions DiagOpts;
1798f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
1808f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
1818f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::ProcessWarningOptions(DiagEngine, DiagOpts);
1828f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Issue errors on unknown arguments.
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        ie = Args->filtered_end(); it != ie; ++it)
1869207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
187b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << (*it)->getAsString(*Args);
188b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
190b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        it != ie; ++it) {
191b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      const Arg *A = *it;
192b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (A->getOption().getKind() == Option::InputClass)
193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Inputs.push_back(A->getValue(*Args));
194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
198b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDir = Args->getLastArgValue(OPT_o);
199b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
201b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
202b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_M: {
203b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
204e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
205b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
206b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
207b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_MD: {
208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
209e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
210190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott          break;
211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2136e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in M group!");
214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
217b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_asm: {
221e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_llvm: {
225e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
226b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
228b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_bc: {
229e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
232b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_nothing: {
233e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
234b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in output type group!");
238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
241b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
242e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (Opts.mOutputDep &&
243e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
244e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
2459207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
248b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
249b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPathBase =
252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_path_base);
253b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPackageName =
254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_package_name);
255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
256b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::StringRef BitcodeStorageValue =
257b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_bitcode_storage);
258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (BitcodeStorageValue == "ar")
259e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
260b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (BitcodeStorageValue == "jc")
261e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (!BitcodeStorageValue.empty())
2639207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_invalid_value)
264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << OptParser->getOptionName(OPT_bitcode_storage)
265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << BitcodeStorageValue;
266b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2675c25c5159c0a5be9af992679067790716626da7bStephen Hines    if (Args->hasArg(OPT_reflect_cpp)) {
2685c25c5159c0a5be9af992679067790716626da7bStephen Hines      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
2695c25c5159c0a5be9af992679067790716626da7bStephen Hines    }
2705c25c5159c0a5be9af992679067790716626da7bStephen Hines
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDepDir =
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAdditionalDepTargets =
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getAllArgValues(OPT_additional_dep_target);
275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowHelp = Args->hasArg(OPT_help);
277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowVersion = Args->hasArg(OPT_version);
2782e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
2792e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api,
2802e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                               RS_VERSION,
2819207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                               DiagEngine);
282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
284b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
285b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
288b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
289e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       std::set<std::string> &SavedStrings) {
291e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
293b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
294b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
295b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
296b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Append '/' to Opts.mOutputDir if not presents
297b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
2988d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
2998d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
300b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
301e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
302b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
304e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
305e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
306e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
307e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
308e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
309b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
310e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
311e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
312b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
313b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
314b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
315e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
316b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
317b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
318b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
319e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
320b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
321b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
323e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
327e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
329b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
331e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
3336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
336b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
337b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SaveStringInSet(SavedStrings, OutputFile);
338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
339b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
340ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
341ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
342ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
343ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
344ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
345ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
346ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
347ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Built " << __DATE__ << " (" << __TIME__ ").\n";
348ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
349ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << SLANG_MAXIMUM_TARGET_API;
350ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
351ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS
352ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << " with assertions";
353ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif
354ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << ".\n";
355ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  return;
356ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines}
3578f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str
3588f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str
359ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines
360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) {
361b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::set<std::string> SavedStrings;
362b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 256> ArgVector;
363b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions Opts;
364b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 16> Inputs;
365b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string Argv0;
366b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
367b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  atexit(llvm::llvm_shutdown);
368b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
369b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ExpandArgv(argc, argv, ArgVector, SavedStrings);
370b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
371b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Argv0
3726f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien  Argv0 = llvm::sys::path::stem(ArgVector[0]);
373b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
374b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Setup diagnostic engine
3758f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer();
376be27482cdeaf08576bc39b72a15d35d13014a636Logan
377be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
378be27482cdeaf08576bc39b72a15d35d13014a636Logan    new clang::DiagnosticIDs());
379be27482cdeaf08576bc39b72a15d35d13014a636Logan
3809207a2e495c8363606861e4f034504ec5c153dabLogan Chien  clang::DiagnosticsEngine DiagEngine(DiagIDs, DiagClient, true);
3819207a2e495c8363606861e4f034504ec5c153dabLogan Chien
382e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::GlobalInitialization();
383b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
3849207a2e495c8363606861e4f034504ec5c153dabLogan Chien  ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
385b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
386b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Exits when there's any error occurred during parsing the arguments
3878f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  if (DiagEngine.hasErrorOccurred()) {
3888f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
389b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
3908f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  }
391b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
392b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
393b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
394b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
395b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines                      "Renderscript source compiler");
396b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
397b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
398b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
399b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
400ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines    llvm_rs_cc_VersionPrinter();
401b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
402b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
403b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
404b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // No input file
405b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
4069207a2e495c8363606861e4f034504ec5c153dabLogan Chien    DiagEngine.Report(clang::diag::err_drv_no_input_files);
4078f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
408b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
409b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
410b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
411cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Prepare input data for RS compiler.
412cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > IOFiles;
413cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > DepFiles;
414cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
415e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
416641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
4178f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine,
4188f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines                 DiagClient);
419b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
420b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0, e = Inputs.size(); i != e; i++) {
421cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *InputFile = Inputs[i];
422cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *OutputFile =
423cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DetermineOutputFile(Opts.mOutputDir, InputFile,
424cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            Opts.mOutputType, SavedStrings);
425cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
426b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Opts.mOutputDep) {
427cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      const char *BCOutputFile, *DepOutputFile;
428e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
429e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Bitcode)
430e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang        BCOutputFile = OutputFile;
431e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      else
432e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
433e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           InputFile,
434e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           slang::Slang::OT_Bitcode,
435e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           SavedStrings);
436cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
437e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency)
438cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DepOutputFile = OutputFile;
439cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      else
440e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
441e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            InputFile,
442e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            slang::Slang::OT_Dependency,
443e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            SavedStrings);
444cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
445cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
446b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
447cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
448cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
449cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
450cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
451cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Let's rock!
452d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  int CompileFailed = !Compiler->compile(IOFiles,
453d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         DepFiles,
454d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mIncludePaths,
455d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAdditionalDepTargets,
456d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputType,
457d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mBitcodeStorage,
458d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAllowRSPrefix,
459d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputDep,
4602e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                         Opts.mTargetAPI,
461d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mJavaReflectionPathBase,
462d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mJavaReflectionPackageName);
4635c25c5159c0a5be9af992679067790716626da7bStephen Hines
464c632be206ac4fe49a5db05cfa54942d774329dbeStephen Hines  Compiler->reset();
465d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines
466d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  return CompileFailed;
467b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
468b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
469b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
470b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
471b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
472b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
473b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
474b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings) {
475b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *FName = Arg + 1;
476be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
477be27482cdeaf08576bc39b72a15d35d13014a636Logan  if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
478be27482cdeaf08576bc39b72a15d35d13014a636Logan    // Unable to open the file
479b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
480b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return;
481b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
482b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
483b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *Buf = MemBuf->getBufferStart();
484b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  char InQuote = ' ';
485b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string CurArg;
486b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
487b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (const char *P = Buf; ; ++P) {
488b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
489b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (!CurArg.empty()) {
490b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        if (CurArg[0] != '@') {
491b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
492b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        } else {
493b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
494b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
495b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
496b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg = "";
497b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
498b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P == '\0')
499b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        break;
500b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
501b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        continue;
502b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
503b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
504b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (isspace(*P)) {
505b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote != ' ')
506b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
507b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
508b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
509b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
510b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '"' || *P == '\'') {
511b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote == *P)
512b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = ' ';
513b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else if (InQuote == ' ')
514b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = *P;
515b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
516b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
517b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
518b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
519b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
520b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\\') {
521b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ++P;
522b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P != '\0')
523b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
524b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
525b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
526b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    CurArg.push_back(*P);
527b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
528b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
529b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
530b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
531b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
532b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
533b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings) {
534b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0; i < argc; ++i) {
535b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char *Arg = argv[i];
536b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Arg[0] != '@') {
537b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
538b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
539b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
540b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
541b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
542b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
543b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
544