aboutsummaryrefslogtreecommitdiffstats
path: root/rs_cc_options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rs_cc_options.cpp')
-rw-r--r--rs_cc_options.cpp320
1 files changed, 173 insertions, 147 deletions
diff --git a/rs_cc_options.cpp b/rs_cc_options.cpp
index ff37dd0..94d1453 100644
--- a/rs_cc_options.cpp
+++ b/rs_cc_options.cpp
@@ -23,6 +23,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Option/OptTable.h"
+#include "llvm/Support/CommandLine.h"
#include "rs_cc_options.h"
#include "slang.h"
@@ -76,168 +77,193 @@ class RSCCOptTable : public llvm::opt::OptTable {
};
}
-llvm::opt::OptTable *slang::createRSCCOptTable() { return new RSCCOptTable(); }
-
-void slang::ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector,
- llvm::SmallVectorImpl<const char *> &Inputs,
- slang::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;
- std::unique_ptr<llvm::opt::OptTable> OptParser(slang::createRSCCOptTable());
- std::unique_ptr<llvm::opt::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 (llvm::opt::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 (llvm::opt::ArgList::const_iterator it = Args->begin(),
- ie = Args->end();
- it != ie; ++it) {
- const llvm::opt::Arg *A = *it;
- if (A->getOption().getKind() == llvm::opt::Option::InputClass)
- Inputs.push_back(A->getValue());
- }
+namespace slang {
+
+llvm::opt::OptTable *createRSCCOptTable() { return new RSCCOptTable(); }
+
+// This function is similar to
+// clang/lib/Frontend/CompilerInvocation::CreateFromArgs.
+bool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn,
+ llvm::SmallVectorImpl<const char *> &Inputs,
+ RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts,
+ llvm::cl::StringSaver &StringSaver) {
+ // We use a different diagnostic engine for argument parsing from the rest of
+ // the work. This mimics what's done in clang. I believe it is so the
+ // argument parsing errors are well formatted while the full errors can be
+ // influenced by command line arguments.
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> ArgumentParseDiagOpts(
+ new clang::DiagnosticOptions());
+ llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
+ new clang::DiagnosticIDs());
+ DiagnosticBuffer DiagsBuffer;
+ clang::DiagnosticsEngine DiagEngine(DiagIDs, &*ArgumentParseDiagOpts,
+ &DiagsBuffer, false);
+
+ // Populate a vector with the command line arguments, expanding command files
+ // that have been included via the '@' argument.
+ llvm::SmallVector<const char *, 256> ArgVector;
+ ArgVector.append(ArgsIn.begin(), ArgsIn.end());
+ llvm::cl::ExpandResponseFiles(StringSaver, llvm::cl::TokenizeGNUCommandLine,
+ ArgVector, false);
+
+ std::unique_ptr<llvm::opt::OptTable> OptParser(createRSCCOptTable());
+ unsigned MissingArgIndex = 0;
+ unsigned MissingArgCount = 0;
+ std::unique_ptr<llvm::opt::InputArgList> Args(
+ OptParser->ParseArgs(ArgVector.begin() + 1, ArgVector.end(),
+ MissingArgIndex, MissingArgCount));
+
+ // Check for missing argument error.
+ if (MissingArgCount) {
+ DiagEngine.Report(clang::diag::err_drv_missing_argument)
+ << Args->getArgString(MissingArgIndex) << MissingArgCount;
+ }
- Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
-
- Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o);
-
- if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) {
- switch (A->getOption().getID()) {
- case OPT_M: {
- Opts.mEmitDependency = true;
- Opts.mOutputType = slang::Slang::OT_Dependency;
- break;
- }
- case OPT_MD: {
- Opts.mEmitDependency = true;
- Opts.mOutputType = slang::Slang::OT_Bitcode;
- break;
- }
- default: { slangAssert(false && "Invalid option in M group!"); }
- }
+ // Issue errors on unknown arguments.
+ for (llvm::opt::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);
+ }
+
+ DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
+ DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
+
+ for (llvm::opt::ArgList::const_iterator it = Args->begin(), ie = Args->end();
+ it != ie; ++it) {
+ const llvm::opt::Arg *A = *it;
+ if (A->getOption().getKind() == llvm::opt::Option::InputClass)
+ Inputs.push_back(A->getValue());
+ }
+
+ Opts.mIncludePaths = Args->getAllArgValues(OPT_I);
+
+ Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o);
+
+ if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) {
+ switch (A->getOption().getID()) {
+ case OPT_M: {
+ Opts.mEmitDependency = true;
+ Opts.mOutputType = Slang::OT_Dependency;
+ break;
+ }
+ case OPT_MD: {
+ Opts.mEmitDependency = true;
+ Opts.mOutputType = Slang::OT_Bitcode;
+ break;
+ }
+ default: { slangAssert(false && "Invalid option in M group!"); }
}
+ }
- if (const llvm::opt::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 (const llvm::opt::Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
+ switch (A->getOption().getID()) {
+ case OPT_emit_asm: {
+ Opts.mOutputType = Slang::OT_Assembly;
+ break;
+ }
+ case OPT_emit_llvm: {
+ Opts.mOutputType = Slang::OT_LLVMAssembly;
+ break;
}
+ case OPT_emit_bc: {
+ Opts.mOutputType = Slang::OT_Bitcode;
+ break;
+ }
+ case OPT_emit_nothing: {
+ Opts.mOutputType = Slang::OT_Nothing;
+ break;
+ }
+ default: { slangAssert(false && "Invalid option in output type group!"); }
+ }
+ }
- if (Opts.mEmitDependency &&
- ((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;
-
- llvm::opt::Arg *lastBitwidthArg = Args->getLastArg(OPT_m32, OPT_m64);
- 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 mBitcodeOutputDir (via -o) by default.
- if (Opts.mJavaReflectionPathBase.empty()) {
- Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir;
- }
+ if (Opts.mEmitDependency && ((Opts.mOutputType != Slang::OT_Bitcode) &&
+ (Opts.mOutputType != 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 = BCST_APK_RESOURCE;
+ else if (BitcodeStorageValue == "jc")
+ Opts.mBitcodeStorage = BCST_JAVA_CODE;
+ else if (!BitcodeStorageValue.empty())
+ DiagEngine.Report(clang::diag::err_drv_invalid_value)
+ << OptParser->getOptionName(OPT_bitcode_storage) << BitcodeStorageValue;
+
+ llvm::opt::Arg *lastBitwidthArg = Args->getLastArg(OPT_m32, OPT_m64);
+ if (Args->hasArg(OPT_reflect_cpp)) {
+ Opts.mBitcodeStorage = BCST_CPP_CODE;
+ // mJavaReflectionPathBase can be set for C++ reflected builds.
+ // Set it to the standard mBitcodeOutputDir (via -o) by default.
+ if (Opts.mJavaReflectionPathBase.empty()) {
+ Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir;
+ }
- // Check for bitwidth arguments.
- if (lastBitwidthArg) {
- if (lastBitwidthArg->getOption().matches(OPT_m32)) {
- Opts.mBitWidth = 32;
- } else {
- Opts.mBitWidth = 64;
- }
+ // Check for bitwidth arguments.
+ if (lastBitwidthArg) {
+ if (lastBitwidthArg->getOption().matches(OPT_m32)) {
+ Opts.mBitWidth = 32;
+ } else {
+ Opts.mBitWidth = 64;
}
- } else if (lastBitwidthArg) {
- // -m32/-m64 are forbidden for non-C++ reflection paths.
- DiagEngine.Report(DiagEngine.getCustomDiagID(
- clang::DiagnosticsEngine::Error,
- "cannot use -m32/-m64 without specifying C++ reflection (-reflect-c++)"));
}
+ } else if (lastBitwidthArg) {
+ // -m32/-m64 are forbidden for non-C++ reflection paths.
+ DiagEngine.Report(
+ DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
+ "cannot use -m32/-m64 without specifying "
+ "C++ reflection (-reflect-c++)"));
+ }
- Opts.mDependencyOutputDir =
- Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir);
- Opts.mAdditionalDepTargets =
- Args->getAllArgValues(OPT_additional_dep_target);
+ Opts.mDependencyOutputDir =
+ Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir);
+ 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);
- Opts.mVerbose = Args->hasArg(OPT_verbose);
+ Opts.mShowHelp = Args->hasArg(OPT_help);
+ Opts.mShowVersion = Args->hasArg(OPT_version);
+ Opts.mDebugEmission = Args->hasArg(OPT_emit_g);
+ Opts.mVerbose = Args->hasArg(OPT_verbose);
- // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
+ // If we are emitting both 32-bit and 64-bit bitcode, we must embed it.
- size_t OptLevel =
- clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine);
+ size_t OptLevel =
+ clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine);
- Opts.mOptimizationLevel =
- OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive;
+ Opts.mOptimizationLevel =
+ OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive;
- Opts.mTargetAPI = clang::getLastArgIntValue(*Args, OPT_target_api,
- RS_VERSION, DiagEngine);
+ Opts.mTargetAPI =
+ clang::getLastArgIntValue(*Args, OPT_target_api, RS_VERSION, DiagEngine);
- if (Opts.mTargetAPI == 0) {
- Opts.mTargetAPI = UINT_MAX;
- }
+ if (Opts.mTargetAPI == 0) {
+ Opts.mTargetAPI = UINT_MAX;
+ }
- Opts.mEmit3264 = (Opts.mTargetAPI >= 21) && (Opts.mBitcodeStorage != slang::BCST_CPP_CODE);
- if (Opts.mEmit3264) {
- Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
- }
+ Opts.mEmit3264 =
+ (Opts.mTargetAPI >= 21) && (Opts.mBitcodeStorage != BCST_CPP_CODE);
+ if (Opts.mEmit3264) {
+ Opts.mBitcodeStorage = BCST_JAVA_CODE;
}
+
+ if (DiagEngine.hasErrorOccurred()) {
+ llvm::errs() << DiagsBuffer.str();
+ return false;
+ }
+
+ return true;
+}
}