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