Separate out option processing from llvm-rs-cc.cpp.
Change-Id: I8abcc6d91820d8e6963f6579a5c6bbb95d6e2c7c
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index 40209e0..338ebe1 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -14,17 +14,9 @@
* limitations under the License.
*/
-#include <cstdlib>
-#include <list>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
-
-#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
@@ -32,9 +24,6 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/Option.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
@@ -44,19 +33,16 @@
#include "llvm/Support/system_error.h"
#include "llvm/Target/TargetMachine.h"
+#include "rs_cc_options.h"
#include "slang.h"
#include "slang_assert.h"
#include "slang_diagnostic_buffer.h"
#include "slang_rs.h"
#include "slang_rs_reflect_utils.h"
-using clang::driver::options::DriverOption;
-using llvm::opt::arg_iterator;
-using llvm::opt::Arg;
-using llvm::opt::ArgList;
-using llvm::opt::InputArgList;
-using llvm::opt::Option;
-using llvm::opt::OptTable;
+#include <list>
+#include <set>
+#include <string>
// SaveStringInSet, ExpandArgsFromBuf and ExpandArgv are all copied from
// $(CLANG_ROOT)/tools/driver/driver.cpp for processing argc/argv passed in
@@ -72,256 +58,6 @@
llvm::SmallVectorImpl<const char*> &ArgVector,
std::set<std::string> &SavedStrings);
-enum {
- OPT_INVALID = 0, // This is not an option ID.
-#define PREFIX(NAME, VALUE)
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) OPT_##ID,
-#include "RSCCOptions.inc"
- LastOption
-#undef OPTION
-#undef PREFIX
-};
-
-#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR)
-#include "RSCCOptions.inc"
-#undef OPTION
-#undef PREFIX
-
-static const OptTable::Info RSCCInfoTable[] = {
-#define PREFIX(NAME, VALUE)
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
- FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "RSCCOptions.inc"
-#undef OPTION
-#undef PREFIX
-};
-
-class RSCCOptTable : public OptTable {
- public:
- RSCCOptTable()
- : OptTable(RSCCInfoTable,
- sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {
- }
-};
-
-OptTable *createRSCCOptTable() {
- return new RSCCOptTable();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-class RSCCOptions {
- public:
- // The include search paths
- std::vector<std::string> mIncludePaths;
-
- // The output directory, if any.
- std::string mOutputDir;
-
- // The output type
- slang::Slang::OutputType mOutputType;
-
- unsigned mAllowRSPrefix : 1;
-
- // The name of the target triple to compile for.
- std::string mTriple;
-
- // The name of the target CPU to generate code for.
- std::string mCPU;
-
- // The list of target specific features to enable or disable -- this should
- // be a list of strings starting with by '+' or '-'.
- std::vector<std::string> mFeatures;
-
- std::string mJavaReflectionPathBase;
-
- std::string mJavaReflectionPackageName;
-
- std::string mRSPackageName;
-
- slang::BitCodeStorageType mBitcodeStorage;
-
- unsigned mOutputDep : 1;
-
- std::string mOutputDepDir;
-
- std::vector<std::string> mAdditionalDepTargets;
-
- unsigned mShowHelp : 1; // Show the -help text.
- unsigned mShowVersion : 1; // Show the -version text.
-
- unsigned int mTargetAPI;
-
- // Enable emission of debugging symbols
- unsigned mDebugEmission : 1;
-
- // The optimization level used in CodeGen, and encoded in emitted bitcode
- llvm::CodeGenOpt::Level mOptimizationLevel;
-
- RSCCOptions() {
- mOutputType = slang::Slang::OT_Bitcode;
- // Triple/CPU/Features must be hard-coded to our chosen portable ABI.
- mTriple = "armv7-none-linux-gnueabi";
- mCPU = "";
- slangAssert(mFeatures.empty());
- mFeatures.push_back("+long64");
- mBitcodeStorage = slang::BCST_APK_RESOURCE;
- mOutputDep = 0;
- mShowHelp = 0;
- mShowVersion = 0;
- mTargetAPI = RS_VERSION;
- mDebugEmission = 0;
- mOptimizationLevel = llvm::CodeGenOpt::Aggressive;
- }
-};
-
-// ParseArguments -
-static void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
- llvm::SmallVectorImpl<const char*> &Inputs,
- RSCCOptions &Opts,
- clang::DiagnosticsEngine &DiagEngine) {
- if (ArgVector.size() > 1) {
- const char **ArgBegin = ArgVector.data() + 1;
- const char **ArgEnd = ArgVector.data() + ArgVector.size();
- unsigned MissingArgIndex, MissingArgCount;
- llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
- llvm::OwningPtr<InputArgList> Args(
- OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));
-
- // Check for missing argument error.
- if (MissingArgCount)
- DiagEngine.Report(clang::diag::err_drv_missing_argument)
- << Args->getArgString(MissingArgIndex) << MissingArgCount;
-
- clang::DiagnosticOptions DiagOpts;
- DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
- DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
- clang::ProcessWarningOptions(DiagEngine, DiagOpts);
-
- // Issue errors on unknown arguments.
- for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
- ie = Args->filtered_end(); it != ie; ++it)
- DiagEngine.Report(clang::diag::err_drv_unknown_argument)
- << (*it)->getAsString(*Args);
-
- for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
- it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().getKind() == Option::InputClass)
- Inputs.push_back(A->getValue());
- }
-
- Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
-
- Opts.mOutputDir = Args->getLastArgValue(OPT_o);
-
- if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
- switch (A->getOption().getID()) {
- case OPT_M: {
- Opts.mOutputDep = 1;
- Opts.mOutputType = slang::Slang::OT_Dependency;
- break;
- }
- case OPT_MD: {
- Opts.mOutputDep = 1;
- Opts.mOutputType = slang::Slang::OT_Bitcode;
- break;
- }
- default: {
- slangAssert(false && "Invalid option in M group!");
- }
- }
- }
-
- if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
- switch (A->getOption().getID()) {
- case OPT_emit_asm: {
- Opts.mOutputType = slang::Slang::OT_Assembly;
- break;
- }
- case OPT_emit_llvm: {
- Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
- break;
- }
- case OPT_emit_bc: {
- Opts.mOutputType = slang::Slang::OT_Bitcode;
- break;
- }
- case OPT_emit_nothing: {
- Opts.mOutputType = slang::Slang::OT_Nothing;
- break;
- }
- default: {
- slangAssert(false && "Invalid option in output type group!");
- }
- }
- }
-
- if (Opts.mOutputDep &&
- ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
- (Opts.mOutputType != slang::Slang::OT_Dependency)))
- DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
- << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
- << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
-
- Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);
-
- Opts.mJavaReflectionPathBase =
- Args->getLastArgValue(OPT_java_reflection_path_base);
- Opts.mJavaReflectionPackageName =
- Args->getLastArgValue(OPT_java_reflection_package_name);
-
- Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);
-
- llvm::StringRef BitcodeStorageValue =
- Args->getLastArgValue(OPT_bitcode_storage);
- if (BitcodeStorageValue == "ar")
- Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
- else if (BitcodeStorageValue == "jc")
- Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
- else if (!BitcodeStorageValue.empty())
- DiagEngine.Report(clang::diag::err_drv_invalid_value)
- << OptParser->getOptionName(OPT_bitcode_storage)
- << BitcodeStorageValue;
-
- if (Args->hasArg(OPT_reflect_cpp)) {
- Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
- // mJavaReflectionPathBase can be set for C++ reflected builds.
- // Set it to the standard mOutputDir (via -o) by default.
- if (Opts.mJavaReflectionPathBase.empty()) {
- Opts.mJavaReflectionPathBase = Opts.mOutputDir;
- }
- }
-
- Opts.mOutputDepDir =
- Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
- Opts.mAdditionalDepTargets =
- Args->getAllArgValues(OPT_additional_dep_target);
-
- Opts.mShowHelp = Args->hasArg(OPT_help);
- Opts.mShowVersion = Args->hasArg(OPT_version);
- Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
-
- size_t OptLevel = clang::getLastArgIntValue(*Args,
- OPT_optimization_level,
- 3,
- DiagEngine);
-
- Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None
- : llvm::CodeGenOpt::Aggressive;
-
- Opts.mTargetAPI = clang::getLastArgIntValue(*Args,
- OPT_target_api,
- RS_VERSION,
- DiagEngine);
- }
-}
-
static const char *DetermineOutputFile(const std::string &OutputDir,
const char *InputFile,
slang::Slang::OutputType OutputType,
@@ -397,7 +133,7 @@
int main(int argc, const char **argv) {
std::set<std::string> SavedStrings;
llvm::SmallVector<const char*, 256> ArgVector;
- RSCCOptions Opts;
+ slang::RSCCOptions Opts;
llvm::SmallVector<const char*, 16> Inputs;
std::string Argv0;
@@ -420,7 +156,7 @@
slang::Slang::GlobalInitialization();
- ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
+ slang::ParseArguments(ArgVector, Inputs, Opts, DiagEngine);
// Exits when there's any error occurred during parsing the arguments
if (DiagEngine.hasErrorOccurred()) {
@@ -429,7 +165,7 @@
}
if (Opts.mShowHelp) {
- llvm::OwningPtr<OptTable> OptTbl(createRSCCOptTable());
+ llvm::OwningPtr<llvm::opt::OptTable> OptTbl(slang::createRSCCOptTable());
OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
"Renderscript source compiler");
return 0;