18b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines/*
28b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * Copyright 2014, The Android Open Source Project
38b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines *
48b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
58b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * you may not use this file except in compliance with the License.
68b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * You may obtain a copy of the License at
78b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines *
88b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
98b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines *
108b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * Unless required by applicable law or agreed to in writing, software
118b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
128b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * See the License for the specific language governing permissions and
148b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines * limitations under the License.
158b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines */
168b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
178b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Basic/DiagnosticOptions.h"
188b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Driver/DriverDiagnostic.h"
198b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Driver/Options.h"
208b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Frontend/Utils.h"
218b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
228b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "llvm/Option/Arg.h"
238b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "llvm/Option/ArgList.h"
248b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "llvm/Option/Option.h"
258b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "llvm/Option/OptTable.h"
265309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet#include "llvm/Support/CommandLine.h"
278b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
288b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "rs_cc_options.h"
298b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "slang.h"
308b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "slang_assert.h"
318b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
328b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <cstdlib>
338b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <string>
348b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <utility>
358b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <vector>
368b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
378b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesenum {
388b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  OPT_INVALID = 0,  // This is not an option ID.
398b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE)
408b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
418b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)                                             \
428b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  OPT_##ID,
438b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
448b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  LastOption
458b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
468b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
478b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
488b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
498b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
508b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
518b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)
528b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
538b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
548b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
558b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
568b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesstatic const llvm::opt::OptTable::Info RSCCInfoTable[] = {
578b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE)
588b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
598b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)                                              \
608b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  {                                                                            \
618b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
628b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS                      \
638b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  }                                                                            \
648b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  ,
658b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
668b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
678b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
688b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
698b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
708b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesnamespace {
718b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
728b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesclass RSCCOptTable : public llvm::opt::OptTable {
738b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines public:
748b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  RSCCOptTable()
758f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      : OptTable(llvm::makeArrayRef(RSCCInfoTable)) {}
768b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
778b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines}
788b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
795309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletnamespace slang {
805309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
815309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletllvm::opt::OptTable *createRSCCOptTable() { return new RSCCOptTable(); }
825309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
835309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet// This function is similar to
845309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet// clang/lib/Frontend/CompilerInvocation::CreateFromArgs.
855309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletbool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn,
865309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                    llvm::SmallVectorImpl<const char *> &Inputs,
875309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                    RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts,
881906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar                    llvm::StringSaver &StringSaver) {
895309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // We use a different diagnostic engine for argument parsing from the rest of
905309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // the work.  This mimics what's done in clang.  I believe it is so the
915309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // argument parsing errors are well formatted while the full errors can be
925309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // influenced by command line arguments.
935309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> ArgumentParseDiagOpts(
945309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      new clang::DiagnosticOptions());
955309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
965309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      new clang::DiagnosticIDs());
975309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  DiagnosticBuffer DiagsBuffer;
985309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*ArgumentParseDiagOpts,
995309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                      &DiagsBuffer, false);
1005309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1015309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Populate a vector with the command line arguments, expanding command files
1025309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // that have been included via the '@' argument.
1035309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::SmallVector<const char *, 256> ArgVector;
1048f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  // Skip over the command name, or we will mistakenly process it as a source file.
1058f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  ArgVector.append(ArgsIn.slice(1).begin(), ArgsIn.end());
1065309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::cl::ExpandResponseFiles(StringSaver, llvm::cl::TokenizeGNUCommandLine,
1075309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                ArgVector, false);
1085309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1095309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  std::unique_ptr<llvm::opt::OptTable> OptParser(createRSCCOptTable());
1105309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  unsigned MissingArgIndex = 0;
1115309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  unsigned MissingArgCount = 0;
1128f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  llvm::opt::InputArgList Args =
1138f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      OptParser->ParseArgs(ArgVector, MissingArgIndex, MissingArgCount);
1145309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1155309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Check for missing argument error.
1165309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (MissingArgCount) {
1175309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    DiagEngine.Report(clang::diag::err_drv_missing_argument)
1188f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar        << Args.getArgString(MissingArgIndex) << MissingArgCount;
1195309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
1208b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1215309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Issue errors on unknown arguments.
1228f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  for (llvm::opt::arg_iterator it = Args.filtered_begin(OPT_UNKNOWN),
1238f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                               ie = Args.filtered_end();
1245309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet       it != ie; ++it) {
1255309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    DiagEngine.Report(clang::diag::err_drv_unknown_argument)
1268f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar        << (*it)->getAsString(Args);
1275309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
1285309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1298f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  DiagOpts.IgnoreWarnings = Args.hasArg(OPT_w);
1308f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  DiagOpts.Warnings = Args.getAllArgValues(OPT_W);
1315309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
132670ba1d5f33d0914e63732da0c9423f8069ac313Stephen Hines  // Always turn off warnings for empty initializers, since we really want to
133670ba1d5f33d0914e63732da0c9423f8069ac313Stephen Hines  // employ/encourage this extension for zero-initialization of structures.
134670ba1d5f33d0914e63732da0c9423f8069ac313Stephen Hines  DiagOpts.Warnings.push_back("no-gnu-empty-initializer");
135670ba1d5f33d0914e63732da0c9423f8069ac313Stephen Hines
1368f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  for (llvm::opt::ArgList::const_iterator it = Args.begin(), ie = Args.end();
1375309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet       it != ie; ++it) {
1385309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    const llvm::opt::Arg *A = *it;
1395309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    if (A->getOption().getKind() == llvm::opt::Option::InputClass)
1405309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Inputs.push_back(A->getValue());
1415309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
1425309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1438f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mIncludePaths = Args.getAllArgValues(OPT_I);
1445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1458f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mBitcodeOutputDir = Args.getLastArgValue(OPT_o);
1465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1478f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  if (const llvm::opt::Arg *A = Args.getLastArg(OPT_M_Group)) {
1485309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    switch (A->getOption().getID()) {
1495309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_M: {
1505309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mEmitDependency = true;
1515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_Dependency;
1525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
1545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_MD: {
1555309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mEmitDependency = true;
1565309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_Bitcode;
1575309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1585309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
15921c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang    case OPT_MP: {
16021c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      Opts.mEmitDependency = true;
16121c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      Opts.mOutputType = Slang::OT_Bitcode;
16221c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      Opts.mEmitPhonyDependency = true;
16321c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      break;
16421c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang    }
1655309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    default: { slangAssert(false && "Invalid option in M group!"); }
1668b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
1675309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
1688b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1698f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  if (const llvm::opt::Arg *A = Args.getLastArg(OPT_Output_Type_Group)) {
1705309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    switch (A->getOption().getID()) {
1715309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_emit_asm: {
1725309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_Assembly;
1735309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1745309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
1755309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_emit_llvm: {
1765309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_LLVMAssembly;
1775309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1788b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
1795309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_emit_bc: {
1805309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_Bitcode;
1815309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1825309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
1835309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    case OPT_emit_nothing: {
1845309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mOutputType = Slang::OT_Nothing;
1855309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      break;
1865309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
1875309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    default: { slangAssert(false && "Invalid option in output type group!"); }
1885309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
1895309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
1908b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1915309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (Opts.mEmitDependency && ((Opts.mOutputType != Slang::OT_Bitcode) &&
1925309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                               (Opts.mOutputType != Slang::OT_Dependency)))
1935309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
1948f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar        << Args.getLastArg(OPT_M_Group)->getAsString(Args)
1958f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar        << Args.getLastArg(OPT_Output_Type_Group)->getAsString(Args);
1965309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1978f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mAllowRSPrefix = Args.hasArg(OPT_allow_rs_prefix);
1985309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
1995309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  Opts.mJavaReflectionPathBase =
2008f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      Args.getLastArgValue(OPT_java_reflection_path_base);
2015309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  Opts.mJavaReflectionPackageName =
2028f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      Args.getLastArgValue(OPT_java_reflection_package_name);
2035309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2048f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mRSPackageName = Args.getLastArgValue(OPT_rs_package_name);
2055309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2065309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::StringRef BitcodeStorageValue =
2078f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      Args.getLastArgValue(OPT_bitcode_storage);
2085309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (BitcodeStorageValue == "ar")
2095309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    Opts.mBitcodeStorage = BCST_APK_RESOURCE;
2105309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  else if (BitcodeStorageValue == "jc")
2115309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    Opts.mBitcodeStorage = BCST_JAVA_CODE;
2125309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  else if (!BitcodeStorageValue.empty())
2135309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    DiagEngine.Report(clang::diag::err_drv_invalid_value)
2145309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        << OptParser->getOptionName(OPT_bitcode_storage) << BitcodeStorageValue;
2155309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2168f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  llvm::opt::Arg *lastBitwidthArg = Args.getLastArg(OPT_m32, OPT_m64);
2178f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  if (Args.hasArg(OPT_reflect_cpp)) {
2185309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    Opts.mBitcodeStorage = BCST_CPP_CODE;
2195309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // mJavaReflectionPathBase can be set for C++ reflected builds.
2205309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // Set it to the standard mBitcodeOutputDir (via -o) by default.
2215309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    if (Opts.mJavaReflectionPathBase.empty()) {
2225309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir;
2235309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    }
2245984fc03b6189f19f3721423b92469e4908a49efStephen Hines
2255309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // Check for bitwidth arguments.
2265309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    if (lastBitwidthArg) {
2275309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      if (lastBitwidthArg->getOption().matches(OPT_m32)) {
2285309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        Opts.mBitWidth = 32;
2295309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      } else {
2305309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        Opts.mBitWidth = 64;
2315984fc03b6189f19f3721423b92469e4908a49efStephen Hines      }
2328b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
2335309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  } else if (lastBitwidthArg) {
2342770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      // -m32/-m64 are forbidden for non-C++ reflection paths for non-eng builds
2352770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      // (they would make it too easy for a developer to accidentally create and
2362770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      // release an APK that has 32-bit or 64-bit bitcode but not both).
2372770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#ifdef __ENABLE_INTERNAL_OPTIONS
2382770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      if (lastBitwidthArg->getOption().matches(OPT_m32)) {
2392770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross        Opts.mBitWidth = 32;
2402770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      } else {
2412770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross        Opts.mBitWidth = 64;
2422770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      }
2432770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      Opts.mEmit3264 = false;
2442770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#else
2452770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      DiagEngine.Report(
2462770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross          DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
2472770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross                                     "cannot use -m32/-m64 without specifying "
2482770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross                                     "C++ reflection (-reflect-c++)"));
2492770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#endif
2505309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
2518b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  Opts.mDependencyOutputDir =
2538f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      Args.getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir);
2548f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mAdditionalDepTargets = Args.getAllArgValues(OPT_additional_dep_target);
2558b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2568f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mShowHelp = Args.hasArg(OPT_help);
2578f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mShowVersion = Args.hasArg(OPT_version);
2588f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mDebugEmission = Args.hasArg(OPT_emit_g);
2598f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mVerbose = Args.hasArg(OPT_verbose);
2608f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  Opts.mASTPrint = Args.hasArg(OPT_ast_print);
2612770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
2622770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  // Delegate options
2632770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
2642770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  std::vector<std::string> DelegatedStrings;
2652770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  for (int Opt : std::vector<unsigned>{OPT_debug, OPT_print_after_all, OPT_print_before_all}) {
2668f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar    if (Args.hasArg(Opt)) {
2672770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      // TODO: Don't assume that the option begins with "-"; determine this programmatically instead.
2682770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      DelegatedStrings.push_back(std::string("-") + std::string(OptParser->getOptionName(Opt)));
2692770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      slangAssert(OptParser->getOptionKind(Opt) == llvm::opt::Option::FlagClass);
2702770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    }
2712770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  }
2722770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if (DelegatedStrings.size()) {
2732770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    std::vector<const char *> DelegatedCStrs;
2742770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    DelegatedCStrs.push_back(*ArgVector.data()); // program name
2752770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    std::for_each(DelegatedStrings.cbegin(), DelegatedStrings.cend(),
2762770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross                  [&DelegatedCStrs](const std::string &String) { DelegatedCStrs.push_back(String.c_str()); });
2772770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    llvm::cl::ParseCommandLineOptions(DelegatedCStrs.size(), DelegatedCStrs.data());
2782770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  }
2798b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2805309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
2819ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
2825309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  size_t OptLevel =
2838f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      clang::getLastArgIntValue(Args, OPT_optimization_level, 3, DiagEngine);
2848b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2855309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  Opts.mOptimizationLevel =
2865309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive;
2878b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2885309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  Opts.mTargetAPI =
2898f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      clang::getLastArgIntValue(Args, OPT_target_api, RS_VERSION, DiagEngine);
290c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
2915309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (Opts.mTargetAPI == 0) {
2925309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    Opts.mTargetAPI = UINT_MAX;
2935309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
294dd22d5ca3040cda08cd5702f9d0872c2db8da22fStephen Hines
2952770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if ((Opts.mTargetAPI < 21) || (Opts.mBitcodeStorage == BCST_CPP_CODE))
2962770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    Opts.mEmit3264 = false;
2972770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if (Opts.mEmit3264)
2985309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    Opts.mBitcodeStorage = BCST_JAVA_CODE;
2995309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
3005309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (DiagEngine.hasErrorOccurred()) {
3015309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    llvm::errs() << DiagsBuffer.str();
3025309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    return false;
3035309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  }
3045309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
3055309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  return true;
3065309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet}
3078b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines}
308