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"
268b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
278b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "rs_cc_options.h"
288b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "slang.h"
298b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "slang_assert.h"
308b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
318b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <cstdlib>
328b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <string>
338b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <utility>
348b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <vector>
358b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
368b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesenum {
378b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  OPT_INVALID = 0,  // This is not an option ID.
388b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE)
398b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
408b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)                                             \
418b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  OPT_##ID,
428b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
438b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  LastOption
448b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
458b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
468b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
478b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
488b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
498b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
508b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)
518b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
528b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
538b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
548b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
558b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesstatic const llvm::opt::OptTable::Info RSCCInfoTable[] = {
568b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define PREFIX(NAME, VALUE)
578b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
588b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines               HELPTEXT, METAVAR)                                              \
598b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  {                                                                            \
608b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
618b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS                      \
628b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  }                                                                            \
638b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  ,
648b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "RSCCOptions.inc"
658b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef OPTION
668b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#undef PREFIX
678b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
688b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
698b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesnamespace {
708b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
718b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesclass RSCCOptTable : public llvm::opt::OptTable {
728b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines public:
738b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  RSCCOptTable()
748b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      : OptTable(RSCCInfoTable,
758b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {}
768b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines};
778b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines}
788b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
798b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesllvm::opt::OptTable *slang::createRSCCOptTable() { return new RSCCOptTable(); }
808b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
818b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hinesvoid slang::ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector,
828b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                           llvm::SmallVectorImpl<const char *> &Inputs,
838b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                           slang::RSCCOptions &Opts,
848b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                           clang::DiagnosticsEngine &DiagEngine) {
858b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  if (ArgVector.size() > 1) {
868b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    const char **ArgBegin = ArgVector.data() + 1;
878b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    const char **ArgEnd = ArgVector.data() + ArgVector.size();
888b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    unsigned MissingArgIndex, MissingArgCount;
897ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines    std::unique_ptr<llvm::opt::OptTable> OptParser(slang::createRSCCOptTable());
907ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines    std::unique_ptr<llvm::opt::InputArgList> Args(OptParser->ParseArgs(
918b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
928b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
938b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    // Check for missing argument error.
948b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    if (MissingArgCount)
958b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      DiagEngine.Report(clang::diag::err_drv_missing_argument)
968b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << Args->getArgString(MissingArgIndex) << MissingArgCount;
978b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
988b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    clang::DiagnosticOptions DiagOpts;
998b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
1008b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
1018b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    clang::ProcessWarningOptions(DiagEngine, DiagOpts);
1028b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1038b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    // Issue errors on unknown arguments.
1048b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    for (llvm::opt::arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
1058b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                                 ie = Args->filtered_end();
1068b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines         it != ie; ++it)
1078b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
1088b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << (*it)->getAsString(*Args);
1098b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1108b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    for (llvm::opt::ArgList::const_iterator it = Args->begin(),
1118b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                                            ie = Args->end();
1128b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines         it != ie; ++it) {
1138b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      const llvm::opt::Arg *A = *it;
1148b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      if (A->getOption().getKind() == llvm::opt::Option::InputClass)
1158b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        Inputs.push_back(A->getValue());
1168b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
1178b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1188b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
1198b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1207f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines    Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o);
1218b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1228b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) {
1238b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      switch (A->getOption().getID()) {
1248b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_M: {
1257f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines          Opts.mEmitDependency = true;
1268b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_Dependency;
1278b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1288b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1298b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_MD: {
1307f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines          Opts.mEmitDependency = true;
1318b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
1328b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1338b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1348b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        default: { slangAssert(false && "Invalid option in M group!"); }
1358b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      }
1368b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
1378b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1388b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    if (const llvm::opt::Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
1398b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      switch (A->getOption().getID()) {
1408b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_emit_asm: {
1418b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_Assembly;
1428b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1438b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1448b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_emit_llvm: {
1458b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
1468b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1478b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1488b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_emit_bc: {
1498b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_Bitcode;
1508b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1518b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1528b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        case OPT_emit_nothing: {
1538b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          Opts.mOutputType = slang::Slang::OT_Nothing;
1548b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          break;
1558b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1568b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        default: {
1578b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          slangAssert(false && "Invalid option in output type group!");
1588b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        }
1598b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      }
1608b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
1618b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1627f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines    if (Opts.mEmitDependency &&
1637f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
1647f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines         (Opts.mOutputType != slang::Slang::OT_Dependency)))
1658b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
1668b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
1678b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
1688b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1698b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
1708b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1718b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mJavaReflectionPathBase =
1728b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        Args->getLastArgValue(OPT_java_reflection_path_base);
1738b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mJavaReflectionPackageName =
1748b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        Args->getLastArgValue(OPT_java_reflection_package_name);
1758b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1768b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);
1778b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1788b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    llvm::StringRef BitcodeStorageValue =
1798b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        Args->getLastArgValue(OPT_bitcode_storage);
1808b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    if (BitcodeStorageValue == "ar")
1818b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
1828b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    else if (BitcodeStorageValue == "jc")
1838b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
1848b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    else if (!BitcodeStorageValue.empty())
1858b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      DiagEngine.Report(clang::diag::err_drv_invalid_value)
1868b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << OptParser->getOptionName(OPT_bitcode_storage)
1878b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines          << BitcodeStorageValue;
1888b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
1895984fc03b6189f19f3721423b92469e4908a49efStephen Hines    llvm::opt::Arg *lastBitwidthArg = Args->getLastArg(OPT_m32, OPT_m64);
1908b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    if (Args->hasArg(OPT_reflect_cpp)) {
1918b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
1928b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      // mJavaReflectionPathBase can be set for C++ reflected builds.
1937f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines      // Set it to the standard mBitcodeOutputDir (via -o) by default.
1948b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      if (Opts.mJavaReflectionPathBase.empty()) {
1957f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines        Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir;
1968b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines      }
1975984fc03b6189f19f3721423b92469e4908a49efStephen Hines
1985984fc03b6189f19f3721423b92469e4908a49efStephen Hines      // Check for bitwidth arguments.
1995984fc03b6189f19f3721423b92469e4908a49efStephen Hines      if (lastBitwidthArg) {
2005984fc03b6189f19f3721423b92469e4908a49efStephen Hines        if (lastBitwidthArg->getOption().matches(OPT_m32)) {
2015984fc03b6189f19f3721423b92469e4908a49efStephen Hines          Opts.mBitWidth = 32;
2025984fc03b6189f19f3721423b92469e4908a49efStephen Hines        } else {
2035984fc03b6189f19f3721423b92469e4908a49efStephen Hines          Opts.mBitWidth = 64;
2045984fc03b6189f19f3721423b92469e4908a49efStephen Hines        }
2055984fc03b6189f19f3721423b92469e4908a49efStephen Hines      }
2065984fc03b6189f19f3721423b92469e4908a49efStephen Hines    } else if (lastBitwidthArg) {
2075984fc03b6189f19f3721423b92469e4908a49efStephen Hines      // -m32/-m64 are forbidden for non-C++ reflection paths.
2085984fc03b6189f19f3721423b92469e4908a49efStephen Hines      DiagEngine.Report(DiagEngine.getCustomDiagID(
2095984fc03b6189f19f3721423b92469e4908a49efStephen Hines          clang::DiagnosticsEngine::Error,
2105984fc03b6189f19f3721423b92469e4908a49efStephen Hines          "cannot use -m32/-m64 without specifying C++ reflection (-reflect-c++)"));
2118b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    }
2128b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2137f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines    Opts.mDependencyOutputDir =
2147f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines        Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir);
2158b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mAdditionalDepTargets =
2168b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        Args->getAllArgValues(OPT_additional_dep_target);
2178b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2188b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mShowHelp = Args->hasArg(OPT_help);
2198b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mShowVersion = Args->hasArg(OPT_version);
2208b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
221fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines    Opts.mVerbose = Args->hasArg(OPT_verbose);
2228b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
2249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
2258b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    size_t OptLevel =
2268b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine);
2278b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2288b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mOptimizationLevel =
2298b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines        OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive;
2308b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines
2318b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines    Opts.mTargetAPI = clang::getLastArgIntValue(*Args, OPT_target_api,
2328b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines                                                RS_VERSION, DiagEngine);
233c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
234c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (Opts.mTargetAPI == 0) {
235c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      Opts.mTargetAPI = UINT_MAX;
236c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
237dd22d5ca3040cda08cd5702f9d0872c2db8da22fStephen Hines
2385984fc03b6189f19f3721423b92469e4908a49efStephen Hines    Opts.mEmit3264 = (Opts.mTargetAPI >= 21) && (Opts.mBitcodeStorage != slang::BCST_CPP_CODE);
239dd22d5ca3040cda08cd5702f9d0872c2db8da22fStephen Hines    if (Opts.mEmit3264) {
240dd22d5ca3040cda08cd5702f9d0872c2db8da22fStephen Hines        Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
241dd22d5ca3040cda08cd5702f9d0872c2db8da22fStephen Hines    }
2428b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines  }
2438b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines}
244