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/DriverDiagnostic.h"
25a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "clang/Driver/Options.h"
26b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Basic/DiagnosticOptions.h"
28b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/TextDiagnosticPrinter.h"
298f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "clang/Frontend/Utils.h"
30b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h"
32be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h"
33be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/OwningPtr.h"
34b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
35a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/Arg.h"
36a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/ArgList.h"
37a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/Option.h"
38a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/OptTable.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/CommandLine.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
42be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h"
43ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#include "llvm/Support/raw_ostream.h"
44be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/system_error.h"
45c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h"
46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
486e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
498f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h"
50e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h"
51e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
52b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::options::DriverOption;
54a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::arg_iterator;
55a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::Arg;
56a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::ArgList;
57a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::InputArgList;
58a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::Option;
59a1f95ee8df425089100148a42954cf61dc285015Stephen Hinesusing llvm::opt::OptTable;
60b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from
62b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in
63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main().
64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings,
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                          llvm::StringRef S) {
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SavedStrings.insert(S).first->c_str();
67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings);
71b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings);
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoenum {
76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  OPT_INVALID = 0,  // This is not an option ID.
7723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE)
78a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
79b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR) OPT_##ID,
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  LastOption
82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION
8323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
84b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
8623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
87a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
8823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines               HELPTEXT, METAVAR)
8923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "RSCCOptions.inc"
9023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION
9123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
9223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines
93b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = {
9423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE)
95a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
96b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR)   \
9723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
98a1f95ee8df425089100148a42954cf61dc285015Stephen Hines    FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
10023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION
10123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable {
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptTable()
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      : OptTable(RSCCInfoTable,
108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() {
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return new RSCCOptTable();
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions {
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The include search paths
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mIncludePaths;
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output directory, if any.
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDir;
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output type
127e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::OutputType mOutputType;
128b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mAllowRSPrefix : 1;
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
131b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target triple to compile for.
132b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mTriple;
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
134b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target CPU to generate code for.
135b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mCPU;
136b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The list of target specific features to enable or disable -- this should
138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // be a list of strings starting with by '+' or '-'.
139b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mFeatures;
140b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPathBase;
142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
143b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPackageName;
144b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1450a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines  std::string mRSPackageName;
1460a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
147e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::BitCodeStorageType mBitcodeStorage;
148b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
149b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mOutputDep : 1;
150b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
151b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDepDir;
152b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
153b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mAdditionalDepTargets;
154b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowHelp : 1;  // Show the -help text.
156b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowVersion : 1;  // Show the -version text.
157b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1582e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines  unsigned int mTargetAPI;
1592e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
160c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Enable emission of debugging symbols
161c460b37ffb50819a32c2a8967754b6f784b28263mkopec  unsigned mDebugEmission : 1;
162c460b37ffb50819a32c2a8967754b6f784b28263mkopec
163c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // The optimization level used in CodeGen, and encoded in emitted bitcode
164c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::CodeGenOpt::Level mOptimizationLevel;
165c460b37ffb50819a32c2a8967754b6f784b28263mkopec
166b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions() {
167e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mOutputType = slang::Slang::OT_Bitcode;
168b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
169b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mTriple = "armv7-none-linux-gnueabi";
170b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mCPU = "";
171b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    slangAssert(mFeatures.empty());
17218ca8cfc2b9e60e4aa4b4269e2b02c5f6f245822Stephen Hines    mFeatures.push_back("+long64");
173e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mBitcodeStorage = slang::BCST_APK_RESOURCE;
174b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mOutputDep = 0;
175b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowHelp = 0;
176b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowVersion = 0;
1772e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    mTargetAPI = RS_VERSION;
178c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mDebugEmission = 0;
179c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
180b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
181b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments -
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           llvm::SmallVectorImpl<const char*> &Inputs,
186b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           RSCCOptions &Opts,
1879207a2e495c8363606861e4f034504ec5c153dabLogan Chien                           clang::DiagnosticsEngine &DiagEngine) {
188b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (ArgVector.size() > 1) {
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgBegin = ArgVector.data() + 1;
190b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgEnd = ArgVector.data() + ArgVector.size();
191b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    unsigned MissingArgIndex, MissingArgCount;
192b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<InputArgList> Args(
194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Check for missing argument error.
197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (MissingArgCount)
1989207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_missing_argument)
199b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << Args->getArgString(MissingArgIndex) << MissingArgCount;
200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2018f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::DiagnosticOptions DiagOpts;
2028f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
2038f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
2048f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::ProcessWarningOptions(DiagEngine, DiagOpts);
2058f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines
206b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Issue errors on unknown arguments.
207b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        ie = Args->filtered_end(); it != ie; ++it)
2099207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
210b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << (*it)->getAsString(*Args);
211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        it != ie; ++it) {
214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      const Arg *A = *it;
215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (A->getOption().getKind() == Option::InputClass)
21623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines        Inputs.push_back(A->getValue());
217b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
221b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDir = Args->getLastArgValue(OPT_o);
222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
225b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_M: {
226b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
227e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
228b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
229b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_MD: {
231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
232e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
233190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott          break;
234b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in M group!");
237b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
241b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
243b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_asm: {
244e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
245b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_llvm: {
248e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
249b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_bc: {
252e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
253b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_nothing: {
256e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
257b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
259b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in output type group!");
261b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
265e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (Opts.mOutputDep &&
266e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
267e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
2689207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
269b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
270b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPathBase =
275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_path_base);
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPackageName =
277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_package_name);
278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2790a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines    Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);
2800a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
281b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::StringRef BitcodeStorageValue =
282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_bitcode_storage);
283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (BitcodeStorageValue == "ar")
284e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
285b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (BitcodeStorageValue == "jc")
286e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (!BitcodeStorageValue.empty())
2889207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_invalid_value)
289b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << OptParser->getOptionName(OPT_bitcode_storage)
290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << BitcodeStorageValue;
291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2925c25c5159c0a5be9af992679067790716626da7bStephen Hines    if (Args->hasArg(OPT_reflect_cpp)) {
2935c25c5159c0a5be9af992679067790716626da7bStephen Hines      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
294ac71e8c3b3edca77a561377b1f24447a3c2ac3a5Stephen Hines      // mJavaReflectionPathBase can be set for C++ reflected builds.
295ac71e8c3b3edca77a561377b1f24447a3c2ac3a5Stephen Hines      // Set it to the standard mOutputDir (via -o) by default.
296ac71e8c3b3edca77a561377b1f24447a3c2ac3a5Stephen Hines      if (Opts.mJavaReflectionPathBase.empty()) {
297ac71e8c3b3edca77a561377b1f24447a3c2ac3a5Stephen Hines        Opts.mJavaReflectionPathBase = Opts.mOutputDir;
298ac71e8c3b3edca77a561377b1f24447a3c2ac3a5Stephen Hines      }
2995c25c5159c0a5be9af992679067790716626da7bStephen Hines    }
3005c25c5159c0a5be9af992679067790716626da7bStephen Hines
301b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDepDir =
302b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAdditionalDepTargets =
304b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getAllArgValues(OPT_additional_dep_target);
305b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
306b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowHelp = Args->hasArg(OPT_help);
307b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mShowVersion = Args->hasArg(OPT_version);
308c460b37ffb50819a32c2a8967754b6f784b28263mkopec    Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
309c460b37ffb50819a32c2a8967754b6f784b28263mkopec
310a1f95ee8df425089100148a42954cf61dc285015Stephen Hines    size_t OptLevel = clang::getLastArgIntValue(*Args,
311a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                OPT_optimization_level,
312a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                3,
313a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                DiagEngine);
314c460b37ffb50819a32c2a8967754b6f784b28263mkopec
315c460b37ffb50819a32c2a8967754b6f784b28263mkopec    Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None
316c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                            : llvm::CodeGenOpt::Aggressive;
3172e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
318a1f95ee8df425089100148a42954cf61dc285015Stephen Hines    Opts.mTargetAPI = clang::getLastArgIntValue(*Args,
319a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                OPT_target_api,
320a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                RS_VERSION,
321a1f95ee8df425089100148a42954cf61dc285015Stephen Hines                                                DiagEngine);
322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
323b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
327b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
329e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       std::set<std::string> &SavedStrings) {
331e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
333b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
336b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Append '/' to Opts.mOutputDir if not presents
337b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
3388d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
3398d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
340b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
341e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
342b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
343b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
344e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
345e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
346e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
347e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
348e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
349b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
350e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
351e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
353b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
355e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
357b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
358b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
359e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
361b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
362b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
363e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
364b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
365b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
366b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
367e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
368b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
369b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
370b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
371e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
372b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
3736e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
374b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
375b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
376b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
377b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SaveStringInSet(SavedStrings, OutputFile);
378b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
379b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
380ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
381ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
382ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
383ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
384ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
385ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
386ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
387ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Built " << __DATE__ << " (" << __TIME__ ").\n";
388ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
389ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << SLANG_MAXIMUM_TARGET_API;
390ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
391ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS
392ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << " with assertions";
393ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif
394ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << ".\n";
395ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  return;
396ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines}
3978f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str
3988f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str
399ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines
400b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) {
401b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::set<std::string> SavedStrings;
402b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 256> ArgVector;
403b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions Opts;
404b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 16> Inputs;
405b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string Argv0;
406b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
407b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  atexit(llvm::llvm_shutdown);
408b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
409b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ExpandArgv(argc, argv, ArgVector, SavedStrings);
410b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
411b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Argv0
4126f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien  Argv0 = llvm::sys::path::stem(ArgVector[0]);
413b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
414b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Setup diagnostic engine
4158f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer();
416be27482cdeaf08576bc39b72a15d35d13014a636Logan
417be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
418be27482cdeaf08576bc39b72a15d35d13014a636Logan    new clang::DiagnosticIDs());
419be27482cdeaf08576bc39b72a15d35d13014a636Logan
42023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
42123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    new clang::DiagnosticOptions());
42223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, DiagClient, true);
4239207a2e495c8363606861e4f034504ec5c153dabLogan Chien
424e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::GlobalInitialization();
425b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
4269207a2e495c8363606861e4f034504ec5c153dabLogan Chien  ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
427b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
428b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Exits when there's any error occurred during parsing the arguments
4298f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  if (DiagEngine.hasErrorOccurred()) {
4308f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
431b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
4328f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  }
433b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
434b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
435b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
436b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
437b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines                      "Renderscript source compiler");
438b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
439b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
440b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
441b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
442ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines    llvm_rs_cc_VersionPrinter();
443b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
444b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
445b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
446b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // No input file
447b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
4489207a2e495c8363606861e4f034504ec5c153dabLogan Chien    DiagEngine.Report(clang::diag::err_drv_no_input_files);
4498f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
450b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
451b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
452b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
453cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Prepare input data for RS compiler.
454cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > IOFiles;
455cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > DepFiles;
456cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
457e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
458641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
4598f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine,
4608f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines                 DiagClient);
461b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
462b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0, e = Inputs.size(); i != e; i++) {
463cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *InputFile = Inputs[i];
464cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *OutputFile =
465cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DetermineOutputFile(Opts.mOutputDir, InputFile,
466cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            Opts.mOutputType, SavedStrings);
467cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
468b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Opts.mOutputDep) {
469cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      const char *BCOutputFile, *DepOutputFile;
470e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
471e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Bitcode)
472e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang        BCOutputFile = OutputFile;
473e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      else
474e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
475e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           InputFile,
476e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           slang::Slang::OT_Bitcode,
477e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           SavedStrings);
478cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
479e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency)
480cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DepOutputFile = OutputFile;
481cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      else
482e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
483e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            InputFile,
484e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            slang::Slang::OT_Dependency,
485e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            SavedStrings);
486cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
487cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
488b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
489cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
490cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
491cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
492cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
493cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Let's rock!
494d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  int CompileFailed = !Compiler->compile(IOFiles,
495d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         DepFiles,
496d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mIncludePaths,
497d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAdditionalDepTargets,
498d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputType,
499d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mBitcodeStorage,
500d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAllowRSPrefix,
501d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputDep,
5022e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                         Opts.mTargetAPI,
503c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mDebugEmission,
504c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mOptimizationLevel,
505d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mJavaReflectionPathBase,
5060a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mJavaReflectionPackageName,
5070a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mRSPackageName);
5085c25c5159c0a5be9af992679067790716626da7bStephen Hines
509c632be206ac4fe49a5db05cfa54942d774329dbeStephen Hines  Compiler->reset();
510d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines
511d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  return CompileFailed;
512b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
513b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
514b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
515b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
516b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
517b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
518b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
519b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings) {
520b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *FName = Arg + 1;
521be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
522be27482cdeaf08576bc39b72a15d35d13014a636Logan  if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
523be27482cdeaf08576bc39b72a15d35d13014a636Logan    // Unable to open the file
524b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
525b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return;
526b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
527b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
528b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *Buf = MemBuf->getBufferStart();
529b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  char InQuote = ' ';
530b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string CurArg;
531b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
532b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (const char *P = Buf; ; ++P) {
533b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
534b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (!CurArg.empty()) {
535b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        if (CurArg[0] != '@') {
536b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
537b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        } else {
538b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
539b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
540b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
541b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg = "";
542b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
543b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P == '\0')
544b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        break;
545b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
546b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        continue;
547b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
548b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
549b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (isspace(*P)) {
550b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote != ' ')
551b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
552b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
553b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
554b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
555b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '"' || *P == '\'') {
556b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote == *P)
557b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = ' ';
558b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else if (InQuote == ' ')
559b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = *P;
560b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
561b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
562b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
563b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
564b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
565b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\\') {
566b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ++P;
567b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P != '\0')
568b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
569b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
570b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
571b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    CurArg.push_back(*P);
572b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
573b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
574b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
575b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
576b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
577b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
578b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings) {
579b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0; i < argc; ++i) {
580b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char *Arg = argv[i];
581b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Arg[0] != '@') {
582b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
583b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
584b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
585b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
586b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
587b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
588b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
589