rs_cc_options.cpp revision fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0
1/* 2 * Copyright 2014, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "clang/Basic/DiagnosticOptions.h" 18#include "clang/Driver/DriverDiagnostic.h" 19#include "clang/Driver/Options.h" 20#include "clang/Frontend/Utils.h" 21 22#include "llvm/ADT/OwningPtr.h" 23#include "llvm/Option/Arg.h" 24#include "llvm/Option/ArgList.h" 25#include "llvm/Option/Option.h" 26#include "llvm/Option/OptTable.h" 27 28#include "rs_cc_options.h" 29#include "slang.h" 30#include "slang_assert.h" 31 32#include <cstdlib> 33#include <string> 34#include <utility> 35#include <vector> 36 37enum { 38 OPT_INVALID = 0, // This is not an option ID. 39#define PREFIX(NAME, VALUE) 40#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 41 HELPTEXT, METAVAR) \ 42 OPT_##ID, 43#include "RSCCOptions.inc" 44 LastOption 45#undef OPTION 46#undef PREFIX 47}; 48 49#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 50#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 51 HELPTEXT, METAVAR) 52#include "RSCCOptions.inc" 53#undef OPTION 54#undef PREFIX 55 56static const llvm::opt::OptTable::Info RSCCInfoTable[] = { 57#define PREFIX(NAME, VALUE) 58#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 59 HELPTEXT, METAVAR) \ 60 { \ 61 PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ 62 PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS \ 63 } \ 64 , 65#include "RSCCOptions.inc" 66#undef OPTION 67#undef PREFIX 68}; 69 70namespace { 71 72class RSCCOptTable : public llvm::opt::OptTable { 73 public: 74 RSCCOptTable() 75 : OptTable(RSCCInfoTable, 76 sizeof(RSCCInfoTable) / sizeof(RSCCInfoTable[0])) {} 77}; 78} 79 80llvm::opt::OptTable *slang::createRSCCOptTable() { return new RSCCOptTable(); } 81 82void slang::ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector, 83 llvm::SmallVectorImpl<const char *> &Inputs, 84 slang::RSCCOptions &Opts, 85 clang::DiagnosticsEngine &DiagEngine) { 86 if (ArgVector.size() > 1) { 87 const char **ArgBegin = ArgVector.data() + 1; 88 const char **ArgEnd = ArgVector.data() + ArgVector.size(); 89 unsigned MissingArgIndex, MissingArgCount; 90 llvm::OwningPtr<llvm::opt::OptTable> OptParser(slang::createRSCCOptTable()); 91 llvm::OwningPtr<llvm::opt::InputArgList> Args(OptParser->ParseArgs( 92 ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount)); 93 94 // Check for missing argument error. 95 if (MissingArgCount) 96 DiagEngine.Report(clang::diag::err_drv_missing_argument) 97 << Args->getArgString(MissingArgIndex) << MissingArgCount; 98 99 clang::DiagnosticOptions DiagOpts; 100 DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w); 101 DiagOpts.Warnings = Args->getAllArgValues(OPT_W); 102 clang::ProcessWarningOptions(DiagEngine, DiagOpts); 103 104 // Issue errors on unknown arguments. 105 for (llvm::opt::arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), 106 ie = Args->filtered_end(); 107 it != ie; ++it) 108 DiagEngine.Report(clang::diag::err_drv_unknown_argument) 109 << (*it)->getAsString(*Args); 110 111 for (llvm::opt::ArgList::const_iterator it = Args->begin(), 112 ie = Args->end(); 113 it != ie; ++it) { 114 const llvm::opt::Arg *A = *it; 115 if (A->getOption().getKind() == llvm::opt::Option::InputClass) 116 Inputs.push_back(A->getValue()); 117 } 118 119 Opts.mIncludePaths = Args->getAllArgValues(OPT_I); 120 121 Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o); 122 123 if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) { 124 switch (A->getOption().getID()) { 125 case OPT_M: { 126 Opts.mEmitDependency = true; 127 Opts.mOutputType = slang::Slang::OT_Dependency; 128 break; 129 } 130 case OPT_MD: { 131 Opts.mEmitDependency = true; 132 Opts.mOutputType = slang::Slang::OT_Bitcode; 133 break; 134 } 135 default: { slangAssert(false && "Invalid option in M group!"); } 136 } 137 } 138 139 if (const llvm::opt::Arg *A = Args->getLastArg(OPT_Output_Type_Group)) { 140 switch (A->getOption().getID()) { 141 case OPT_emit_asm: { 142 Opts.mOutputType = slang::Slang::OT_Assembly; 143 break; 144 } 145 case OPT_emit_llvm: { 146 Opts.mOutputType = slang::Slang::OT_LLVMAssembly; 147 break; 148 } 149 case OPT_emit_bc: { 150 Opts.mOutputType = slang::Slang::OT_Bitcode; 151 break; 152 } 153 case OPT_emit_nothing: { 154 Opts.mOutputType = slang::Slang::OT_Nothing; 155 break; 156 } 157 default: { 158 slangAssert(false && "Invalid option in output type group!"); 159 } 160 } 161 } 162 163 if (Opts.mEmitDependency && 164 ((Opts.mOutputType != slang::Slang::OT_Bitcode) && 165 (Opts.mOutputType != slang::Slang::OT_Dependency))) 166 DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with) 167 << Args->getLastArg(OPT_M_Group)->getAsString(*Args) 168 << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args); 169 170 Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix); 171 172 Opts.mJavaReflectionPathBase = 173 Args->getLastArgValue(OPT_java_reflection_path_base); 174 Opts.mJavaReflectionPackageName = 175 Args->getLastArgValue(OPT_java_reflection_package_name); 176 177 Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name); 178 179 llvm::StringRef BitcodeStorageValue = 180 Args->getLastArgValue(OPT_bitcode_storage); 181 if (BitcodeStorageValue == "ar") 182 Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE; 183 else if (BitcodeStorageValue == "jc") 184 Opts.mBitcodeStorage = slang::BCST_JAVA_CODE; 185 else if (!BitcodeStorageValue.empty()) 186 DiagEngine.Report(clang::diag::err_drv_invalid_value) 187 << OptParser->getOptionName(OPT_bitcode_storage) 188 << BitcodeStorageValue; 189 190 if (Args->hasArg(OPT_reflect_cpp)) { 191 Opts.mBitcodeStorage = slang::BCST_CPP_CODE; 192 // mJavaReflectionPathBase can be set for C++ reflected builds. 193 // Set it to the standard mBitcodeOutputDir (via -o) by default. 194 if (Opts.mJavaReflectionPathBase.empty()) { 195 Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir; 196 } 197 } 198 199 Opts.mDependencyOutputDir = 200 Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir); 201 Opts.mAdditionalDepTargets = 202 Args->getAllArgValues(OPT_additional_dep_target); 203 204 Opts.mShowHelp = Args->hasArg(OPT_help); 205 Opts.mShowVersion = Args->hasArg(OPT_version); 206 Opts.mDebugEmission = Args->hasArg(OPT_emit_g); 207 Opts.mVerbose = Args->hasArg(OPT_verbose); 208 209 size_t OptLevel = 210 clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine); 211 212 Opts.mOptimizationLevel = 213 OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive; 214 215 Opts.mTargetAPI = clang::getLastArgIntValue(*Args, OPT_target_api, 216 RS_VERSION, DiagEngine); 217 } 218} 219