llvm-rs-cc.cpp revision 23c4358f12bd9d0ba7166eceebd683db95a41b3f
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
20a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines * Copyright 2010-2012, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
17e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <cstdlib>
18e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list>
19b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <set>
20b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <string>
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utility>
22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
23b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
24b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/Arg.h"
25b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/ArgList.h"
26b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/DriverDiagnostic.h"
27b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/Option.h"
28b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/OptTable.h"
29b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
3023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Basic/DiagnosticOptions.h"
31b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/TextDiagnosticPrinter.h"
328f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "clang/Frontend/Utils.h"
33b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h"
35be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h"
36be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/OwningPtr.h"
37b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/CommandLine.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
41be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h"
42ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#include "llvm/Support/raw_ostream.h"
43be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/system_error.h"
44c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h"
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
488f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h"
49e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs.h"
50e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
51b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
52b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// Class under clang::driver used are enumerated here.
53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::arg_iterator;
54e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing clang::driver::options::DriverOption;
55b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Arg;
56b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::ArgList;
57b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::InputArgList;
58b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::Option;
59b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaousing clang::driver::OptTable;
6043730fe3c839af391efe6bdf56b0479860121924Shih-wei Liaousing namespace clang::driver::options;
61b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
62b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from
63b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in
64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// main().
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic inline const char *SaveStringInSet(std::set<std::string> &SavedStrings,
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                          llvm::StringRef S) {
67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SavedStrings.insert(S).first->c_str();
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
70b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
71b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings);
72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings);
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoenum {
77b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  OPT_INVALID = 0,  // This is not an option ID.
7823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE)
7923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR) OPT_##ID,
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
82b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  LastOption
83b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#undef OPTION
8423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
85b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
86b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
8723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
8823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
8923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines               HELPTEXT, METAVAR)
9023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "RSCCOptions.inc"
9123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION
9223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
9323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines
94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const OptTable::Info RSCCInfoTable[] = {
9523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define PREFIX(NAME, VALUE)
9623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao               HELPTEXT, METAVAR)   \
9823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
9923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    FLAGS, OPT_##GROUP, OPT_##ALIAS },
100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "RSCCOptions.inc"
10123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef OPTION
10223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#undef PREFIX
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptTable : public OptTable {
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptTable()
108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      : OptTable(RSCCInfoTable,
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei LiaoOptTable *createRSCCOptTable() {
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return new RSCCOptTable();
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoclass RSCCOptions {
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao public:
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The include search paths
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mIncludePaths;
123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output directory, if any.
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDir;
126b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
127b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The output type
128e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::OutputType mOutputType;
129b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
130b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mAllowRSPrefix : 1;
131b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
132b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target triple to compile for.
133b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mTriple;
134b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
135b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines  // The name of the target CPU to generate code for.
136b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mCPU;
137b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
138b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // The list of target specific features to enable or disable -- this should
139b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // be a list of strings starting with by '+' or '-'.
140b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mFeatures;
141b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
142b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPathBase;
143b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
144b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mJavaReflectionPackageName;
145b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1460a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines  std::string mRSPackageName;
1470a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
148e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::BitCodeStorageType mBitcodeStorage;
149b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
150b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mOutputDep : 1;
151b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
152b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string mOutputDepDir;
153b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
154b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::vector<std::string> mAdditionalDepTargets;
155b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
156b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowHelp : 1;  // Show the -help text.
157b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  unsigned mShowVersion : 1;  // Show the -version text.
158b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1592e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines  unsigned int mTargetAPI;
1602e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
161c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Enable emission of debugging symbols
162c460b37ffb50819a32c2a8967754b6f784b28263mkopec  unsigned mDebugEmission : 1;
163c460b37ffb50819a32c2a8967754b6f784b28263mkopec
164c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // The optimization level used in CodeGen, and encoded in emitted bitcode
165c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::CodeGenOpt::Level mOptimizationLevel;
166c460b37ffb50819a32c2a8967754b6f784b28263mkopec
167b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions() {
168e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mOutputType = slang::Slang::OT_Bitcode;
169b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
170b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mTriple = "armv7-none-linux-gnueabi";
171b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    mCPU = "";
172b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines    slangAssert(mFeatures.empty());
17318ca8cfc2b9e60e4aa4b4269e2b02c5f6f245822Stephen Hines    mFeatures.push_back("+long64");
174e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    mBitcodeStorage = slang::BCST_APK_RESOURCE;
175b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mOutputDep = 0;
176b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowHelp = 0;
177b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mShowVersion = 0;
1782e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    mTargetAPI = RS_VERSION;
179c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mDebugEmission = 0;
180c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
181b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao};
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ParseArguments -
185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
186b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           llvm::SmallVectorImpl<const char*> &Inputs,
187b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                           RSCCOptions &Opts,
1889207a2e495c8363606861e4f034504ec5c153dabLogan Chien                           clang::DiagnosticsEngine &DiagEngine) {
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (ArgVector.size() > 1) {
190b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgBegin = ArgVector.data() + 1;
191b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char **ArgEnd = ArgVector.data() + ArgVector.size();
192b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    unsigned MissingArgIndex, MissingArgCount;
193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<InputArgList> Args(
195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
197b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Check for missing argument error.
198b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (MissingArgCount)
1999207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_missing_argument)
200b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << Args->getArgString(MissingArgIndex) << MissingArgCount;
201b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2028f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::DiagnosticOptions DiagOpts;
2038f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
2048f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
2058f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    clang::ProcessWarningOptions(DiagEngine, DiagOpts);
2068f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines
207b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // Issue errors on unknown arguments.
208b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
209b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        ie = Args->filtered_end(); it != ie; ++it)
2109207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
211b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        << (*it)->getAsString(*Args);
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
213b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
214b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        it != ie; ++it) {
215b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      const Arg *A = *it;
216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (A->getOption().getKind() == Option::InputClass)
21723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines        Inputs.push_back(A->getValue());
218b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
219b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
220b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
221b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
222b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mOutputDir = Args->getLastArgValue(OPT_o);
223b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
224b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
225b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
226b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_M: {
227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
228e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
229b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
230b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
231b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_MD: {
232b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          Opts.mOutputDep = 1;
233e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
234190ac89717c8be2e838a7be513566fba6d1467a5Patrick Scott          break;
235b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
236b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in M group!");
238b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
240b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
241b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
243b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      switch (A->getOption().getID()) {
244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_asm: {
245e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
247b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
248b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_llvm: {
249e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
251b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
252b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_bc: {
253e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
254b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
255b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
256b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        case OPT_emit_nothing: {
257e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
258b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          break;
259b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
260b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        default: {
2616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines          slangAssert(false && "Invalid option in output type group!");
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
263b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
264b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
266e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (Opts.mOutputDep &&
267e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
268e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
2699207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
270b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPathBase =
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_path_base);
277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    Opts.mJavaReflectionPackageName =
278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_java_reflection_package_name);
279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2800a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines    Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);
2810a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines
282b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::StringRef BitcodeStorageValue =
283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        Args->getLastArgValue(OPT_bitcode_storage);
284b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (BitcodeStorageValue == "ar")
285e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (BitcodeStorageValue == "jc")
287e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
288b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    else if (!BitcodeStorageValue.empty())
2899207a2e495c8363606861e4f034504ec5c153dabLogan Chien      DiagEngine.Report(clang::diag::err_drv_invalid_value)
290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << OptParser->getOptionName(OPT_bitcode_storage)
291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          << BitcodeStorageValue;
292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2935c25c5159c0a5be9af992679067790716626da7bStephen Hines    if (Args->hasArg(OPT_reflect_cpp)) {
2945c25c5159c0a5be9af992679067790716626da7bStephen Hines      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
295b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray      // mJavaReflectionPathBase isn't set for C++ reflected builds
296b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray      // set it to mOutputDir so we can use the path sanely from
297b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray      // RSReflectionBase later on
298b2fbbb91bd9d86e2dd56b2d102752e8c51aaafdfTim Murray      Opts.mJavaReflectionPathBase = Opts.mOutputDir;
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
310c460b37ffb50819a32c2a8967754b6f784b28263mkopec    size_t OptLevel = Args->getLastArgIntValue(OPT_optimization_level,
311c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                               3,
312c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                               DiagEngine);
313c460b37ffb50819a32c2a8967754b6f784b28263mkopec
314c460b37ffb50819a32c2a8967754b6f784b28263mkopec    Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None
315c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                            : llvm::CodeGenOpt::Aggressive;
3162e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines
3172e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines    Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api,
3182e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                               RS_VERSION,
3199207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                               DiagEngine);
320b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
321b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
322b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
323b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
324b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
325b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
326b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
327e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
328b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       std::set<std::string> &SavedStrings) {
329e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
330b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
331b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
332b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
333b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
334b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Append '/' to Opts.mOutputDir if not presents
335b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
3368d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
3378d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
338b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
339e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
340b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
341b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
342e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
343e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
344e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
345e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
346e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
347b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
348e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
349e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
350b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
351b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
353e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
354b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
355b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
356b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
357e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
358b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
359b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
360b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
361e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
362b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
363b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
364b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
365e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
366b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
367b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
368b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
369e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
370b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
3716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
372b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
373b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
374b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
375b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return SaveStringInSet(SavedStrings, OutputFile);
376b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
377b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
378ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
379ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
380ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
381ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
382ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
383ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
384ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
385ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Built " << __DATE__ << " (" << __TIME__ ").\n";
386ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
387ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << SLANG_MAXIMUM_TARGET_API;
388ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
389ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS
390ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << " with assertions";
391ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif
392ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << ".\n";
393ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  return;
394ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines}
3958f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str
3968f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str
397ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines
398b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaoint main(int argc, const char **argv) {
399b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::set<std::string> SavedStrings;
400b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 256> ArgVector;
401b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RSCCOptions Opts;
402b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  llvm::SmallVector<const char*, 16> Inputs;
403b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string Argv0;
404b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
405b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  atexit(llvm::llvm_shutdown);
406b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
407b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  ExpandArgv(argc, argv, ArgVector, SavedStrings);
408b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
409b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Argv0
4106f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien  Argv0 = llvm::sys::path::stem(ArgVector[0]);
411b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
412b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Setup diagnostic engine
4138f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer();
414be27482cdeaf08576bc39b72a15d35d13014a636Logan
415be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
416be27482cdeaf08576bc39b72a15d35d13014a636Logan    new clang::DiagnosticIDs());
417be27482cdeaf08576bc39b72a15d35d13014a636Logan
41823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
41923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    new clang::DiagnosticOptions());
42023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, DiagClient, true);
4219207a2e495c8363606861e4f034504ec5c153dabLogan Chien
422e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  slang::Slang::GlobalInitialization();
423b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
4249207a2e495c8363606861e4f034504ec5c153dabLogan Chien  ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
425b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
426b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // Exits when there's any error occurred during parsing the arguments
4278f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  if (DiagEngine.hasErrorOccurred()) {
4288f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
429b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
4308f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  }
431b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
432b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
433b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
434b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
435b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines                      "Renderscript source compiler");
436b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
437b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
438b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
439b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
440ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines    llvm_rs_cc_VersionPrinter();
441b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
442b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
443b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
444b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  // No input file
445b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
4469207a2e495c8363606861e4f034504ec5c153dabLogan Chien    DiagEngine.Report(clang::diag::err_drv_no_input_files);
4478f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines    llvm::errs() << DiagClient->str();
448b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
449b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
450b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
451cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Prepare input data for RS compiler.
452cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > IOFiles;
453cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  std::list<std::pair<const char*, const char*> > DepFiles;
454cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
455e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  llvm::OwningPtr<slang::SlangRS> Compiler(new slang::SlangRS());
456641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
4578f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  Compiler->init(Opts.mTriple, Opts.mCPU, Opts.mFeatures, &DiagEngine,
4588f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines                 DiagClient);
459b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
460b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0, e = Inputs.size(); i != e; i++) {
461cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *InputFile = Inputs[i];
462cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    const char *OutputFile =
463cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DetermineOutputFile(Opts.mOutputDir, InputFile,
464cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang                            Opts.mOutputType, SavedStrings);
465cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
466b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Opts.mOutputDep) {
467cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      const char *BCOutputFile, *DepOutputFile;
468e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
469e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Bitcode)
470e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang        BCOutputFile = OutputFile;
471e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      else
472e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
473e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           InputFile,
474e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           slang::Slang::OT_Bitcode,
475e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                           SavedStrings);
476cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
477e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency)
478cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang        DepOutputFile = OutputFile;
479cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      else
480e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir,
481e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            InputFile,
482e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            slang::Slang::OT_Dependency,
483e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                            SavedStrings);
484cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
485cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
486b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
487cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
488cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
489cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
490cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
491cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  // Let's rock!
492d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  int CompileFailed = !Compiler->compile(IOFiles,
493d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         DepFiles,
494d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mIncludePaths,
495d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAdditionalDepTargets,
496d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputType,
497d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mBitcodeStorage,
498d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mAllowRSPrefix,
499d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mOutputDep,
5002e35b136cc2434080fcd682d2f95e53a87675dd4Stephen Hines                                         Opts.mTargetAPI,
501c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mDebugEmission,
502c460b37ffb50819a32c2a8967754b6f784b28263mkopec                                         Opts.mOptimizationLevel,
503d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines                                         Opts.mJavaReflectionPathBase,
5040a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mJavaReflectionPackageName,
5050a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines                                         Opts.mRSPackageName);
5065c25c5159c0a5be9af992679067790716626da7bStephen Hines
507c632be206ac4fe49a5db05cfa54942d774329dbeStephen Hines  Compiler->reset();
508d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines
509d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  return CompileFailed;
510b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
511b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
512b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao///////////////////////////////////////////////////////////////////////////////
513b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
514b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
515b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgsFromBuf(const char *Arg,
516b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              llvm::SmallVectorImpl<const char*> &ArgVector,
517b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::set<std::string> &SavedStrings) {
518b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *FName = Arg + 1;
519be27482cdeaf08576bc39b72a15d35d13014a636Logan  llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
520be27482cdeaf08576bc39b72a15d35d13014a636Logan  if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
521be27482cdeaf08576bc39b72a15d35d13014a636Logan    // Unable to open the file
522b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
523b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return;
524b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
525b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
526b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const char *Buf = MemBuf->getBufferStart();
527b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  char InQuote = ' ';
528b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string CurArg;
529b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
530b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (const char *P = Buf; ; ++P) {
531b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
532b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (!CurArg.empty()) {
533b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        if (CurArg[0] != '@') {
534b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
535b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        } else {
536b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
537b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        }
538b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
539b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg = "";
540b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      }
541b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P == '\0')
542b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        break;
543b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
544b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        continue;
545b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
546b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
547b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (isspace(*P)) {
548b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote != ' ')
549b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
550b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
551b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
552b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
553b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '"' || *P == '\'') {
554b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (InQuote == *P)
555b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = ' ';
556b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else if (InQuote == ' ')
557b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        InQuote = *P;
558b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      else
559b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
560b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
561b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
562b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
563b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (*P == '\\') {
564b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ++P;
565b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      if (*P != '\0')
566b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao        CurArg.push_back(*P);
567b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
568b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
569b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    CurArg.push_back(*P);
570b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
571b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
572b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
573b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao// ExpandArgsFromBuf -
574b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic void ExpandArgv(int argc, const char **argv,
575b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       llvm::SmallVectorImpl<const char*> &ArgVector,
576b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                       std::set<std::string> &SavedStrings) {
577b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  for (int i = 0; i < argc; ++i) {
578b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    const char *Arg = argv[i];
579b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    if (Arg[0] != '@') {
580b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
581b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      continue;
582b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
583b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
584b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
585b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
586b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
587