llvm-rs-cc.cpp revision e639eb5caa2c386b4a60659a4929e8a6141a2cbe
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"
32b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h"
34b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/CommandLine.h"
36e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
37e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
38b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/System/Path.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
44b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
45b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// Class under clang::driver used are enumerated here.
46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::arg_iterator;
47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::options::DriverOption;
48b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Arg;
49b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::ArgList;
50b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::InputArgList;
51b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Option;
52b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::OptTable;
53b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
54b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from
55b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in
56b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main().
57b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings,
58b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                          llvm::StringRef S) {
59b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SavedStrings.insert(S).first->c_str();
60b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
62b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings);
64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings);
67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoenum {
69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  OPT_INVALID = 0,  // This is not an option ID.
70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
71b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR) OPT_##ID,
72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  LastOption
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
77b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = {
78b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
79b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR)   \
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OPT_##GROUP, OPT_##ALIAS },
82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
83b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
84b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable {
86b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
87b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptTable()
88b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      : OptTable(RSCCInfoTable,
89b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
90b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
91b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
92b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
93b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() {
94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return new RSCCOptTable();
95b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
96b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions {
100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
101b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The include search paths
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mIncludePaths;
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output directory, if any.
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDir;
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output type
108e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::OutputType mOutputType;
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mAllowRSPrefix : 1;
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // If given, the name of the target triple to compile for. If not given the
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // target will be selected to match the host.
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mTriple;
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // If given, the name of the target CPU to generate code for.
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mCPU;
118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The list of target specific features to enable or disable -- this should
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // be a list of strings starting with by '+' or '-'.
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mFeatures;
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPathBase;
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPackageName;
126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
127e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::BitCodeStorageType mBitcodeStorage;
128b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mOutputDep : 1;
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDepDir;
132b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mAdditionalDepTargets;
134b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
135b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowHelp : 1;  // Show the -help text.
136b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowVersion : 1;  // Show the -version text.
137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions() {
139e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mOutputType = slang::Slang::OT_Bitcode;
140e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mBitcodeStorage = slang::BCST_APK_RESOURCE;
141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mOutputDep = 0;
142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowHelp = 0;
143b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowVersion = 0;
144b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
145b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
146b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
147b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments -
148b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
149b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           llvm::SmallVectorImpl<const char*> &Inputs,
150b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           RSCCOptions &Opts,
151b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           clang::Diagnostic &Diags) {
152b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (ArgVector.size() > 1) {
153b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgBegin = ArgVector.data() + 1;
154b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgEnd = ArgVector.data() + ArgVector.size();
155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    unsigned MissingArgIndex, MissingArgCount;
156b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
157b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<InputArgList> Args(
158b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
159b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
160b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Check for missing argument error.
161b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (MissingArgCount)
162b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      Diags.Report(clang::diag::err_drv_missing_argument)
163b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << Args->getArgString(MissingArgIndex) << MissingArgCount;
164b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
165b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Issue errors on unknown arguments.
166b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
167b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        ie = Args->filtered_end(); it != ie; ++it)
168b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      Diags.Report(clang::diag::err_drv_unknown_argument)
169b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << (*it)->getAsString(*Args);
170b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
171b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
172b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        it != ie; ++it) {
173b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      const Arg *A = *it;
174b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (A->getOption().getKind() == Option::InputClass)
175b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Inputs.push_back(A->getValue(*Args));
176b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
177b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
178b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
179b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
180b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDir = Args->getLastArgValue(OPT_o);
181b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_M: {
185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
186e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
187b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
188b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_MD: {
190b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
191e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
192190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott          break;
193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          assert(false && "Invalid option in M group!");
196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
198b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
199b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
201b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
202b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_asm: {
203e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
204b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
205b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
206b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_llvm: {
207e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
209b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
210b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_bc: {
211e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_nothing: {
215e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
217b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          assert(false && "Invalid option in output type group!");
220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
221b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
224e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (Opts.mOutputDep &&
225e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
226e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      Diags.Report(clang::diag::err_drv_argument_not_allowed_with)
228b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
229b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
232b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
233603217c72ef310ea385f906662c7d6136d45f464Shih-wei Liao    Opts.mTriple = Args->getLastArgValue(OPT_triple,
234603217c72ef310ea385f906662c7d6136d45f464Shih-wei Liao                                         "armv7-none-linux-gnueabi");
235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mCPU = Args->getLastArgValue(OPT_target_cpu);
236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mFeatures = Args->getAllArgValues(OPT_target_feature);
237b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPathBase =
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_path_base);
240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPackageName =
241b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_package_name);
242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
243b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::StringRef BitcodeStorageValue =
244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_bitcode_storage);
245b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (BitcodeStorageValue == "ar")
246e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (BitcodeStorageValue == "jc")
248e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
249b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (!BitcodeStorageValue.empty())
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      Diags.Report(clang::diag::err_drv_invalid_value)
251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << OptParser->getOptionName(OPT_bitcode_storage)
252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << BitcodeStorageValue;
253b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDepDir =
255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
256b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAdditionalDepTargets =
257b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getAllArgValues(OPT_additional_dep_target);
258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
259b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowHelp = Args->hasArg(OPT_help);
260b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowVersion = Args->hasArg(OPT_version);
261b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
266b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
267b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
268e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
269b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       std::set<std::string> &SavedStrings) {
270e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Append '/' to Opts.mOutputDir if not presents
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      (OutputFile[OutputFile.size() - 1]) != '/')
278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OutputFile.append(1, '/');
279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
280e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
281b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
283e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
284e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
285e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
286e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
287e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
288b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
289e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
290e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
293b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
294e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
295b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
296b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
297b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
298e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
299b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
300b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
301b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
302e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
304b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
305b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
306e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
307b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
308b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
309b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
310e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
311b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
312b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      assert(false && "Invalid output type!");
313b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
314b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
315b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
316b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SaveStringInSet(SavedStrings, OutputFile);
317b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
318b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
319b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) {
320b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::set<std::string> SavedStrings;
321b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 256> ArgVector;
322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions Opts;
323b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 16> Inputs;
324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string Argv0;
325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  atexit(llvm::llvm_shutdown);
327b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ExpandArgv(argc, argv, ArgVector, SavedStrings);
329b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Argv0
331b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::sys::Path Path = llvm::sys::Path(ArgVector[0]);
332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  Argv0 = Path.getBasename();
333b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Setup diagnostic engine
335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  clang::TextDiagnosticPrinter *DiagClient =
336b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
337b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  DiagClient->setPrefix(Argv0);
338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  clang::Diagnostic Diags(DiagClient);
339b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
340e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::GlobalInitialization();
341b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
342b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ParseArguments(ArgVector, Inputs, Opts, Diags);
343b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
344b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Exits when there's any error occurred during parsing the arguments
345b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Diags.getNumErrors() > 0)
346b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
347b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
348b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
349b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
350b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
351b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                      "RenderScript source compiler");
352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
353b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
355b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::cl::PrintVersionMessage();
357b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
358b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
359b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // No input file
361b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
362b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Diags.Report(clang::diag::err_drv_no_input_files);
363b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
364b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
365b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
366cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Prepare input data for RS compiler.
367cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > IOFiles;
368cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > DepFiles;
369cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
370e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
371641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
372641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang  Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures);
373b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
374b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0, e = Inputs.size(); i != e; i++) {
375cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *InputFile = Inputs[i];
376cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *OutputFile =
377cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DetermineOutputFile(Opts.mOutputDir, InputFile,
378cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            Opts.mOutputType, SavedStrings);
379cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
380b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Opts.mOutputDep) {
381cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      const char *BCOutputFile, *DepOutputFile;
382e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
383e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Bitcode)
384e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang        BCOutputFile = OutputFile;
385e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      else
386e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
387e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           InputFile,
388e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           slang::Slang::OT_Bitcode,
389e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           SavedStrings);
390cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
391e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency)
392cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DepOutputFile = OutputFile;
393cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      else
394e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
395e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            InputFile,
396e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            slang::Slang::OT_Dependency,
397e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            SavedStrings);
398cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
399cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
400b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
401cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
402cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
403cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
404cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
405cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Let's rock!
406cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  if (!Compiler->compile(IOFiles,
407cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         DepFiles,
408cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mIncludePaths,
409cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mAdditionalDepTargets,
410cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mOutputType,
411cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mBitcodeStorage,
412cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mAllowRSPrefix,
413cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mOutputDep,
414cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mJavaReflectionPathBase,
415cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                         Opts.mJavaReflectionPackageName)) {
416cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    llvm::errs() << Compiler->getErrorMessage();
417cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    return 1;
418b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
419b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
420b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return 0;
421b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
422b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
423b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
424b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
425b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
426b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
427b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
428b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings) {
429b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *FName = Arg + 1;
430b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::MemoryBuffer *MemBuf = llvm::MemoryBuffer::getFile(FName);
431b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!MemBuf) {
432b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
433b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return;
434b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
435b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
436b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *Buf = MemBuf->getBufferStart();
437b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  char InQuote = ' ';
438b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string CurArg;
439b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
440b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (const char *P = Buf; ; ++P) {
441b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
442b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (!CurArg.empty()) {
443b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        if (CurArg[0] != '@') {
444b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
445b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        } else {
446b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
447b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
448b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
449b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg = "";
450b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
451b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P == '\0')
452b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        break;
453b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
454b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        continue;
455b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
456b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
457b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (isspace(*P)) {
458b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote != ' ')
459b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
460b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
461b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
462b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
463b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '"' || *P == '\'') {
464b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote == *P)
465b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = ' ';
466b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else if (InQuote == ' ')
467b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = *P;
468b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
469b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
470b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
471b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
472b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
473b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\\') {
474b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ++P;
475b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P != '\0')
476b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
477b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
478b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
479b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    CurArg.push_back(*P);
480b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
481b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  delete MemBuf;
482b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
483b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
484b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
485b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
486b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
487b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings) {
488b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0; i < argc; ++i) {
489b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char *Arg = argv[i];
490b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Arg[0] != '@') {
491b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
492b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
493b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
494b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
495b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
496b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
497b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
498