diff options
author | Daniel Grumberg <dany.grumberg@gmail.com> | 2020-05-11 11:42:38 +0100 |
---|---|---|
committer | Daniel Grumberg <dany.grumberg@gmail.com> | 2020-06-24 18:05:05 +0100 |
commit | 29125ddf1323951901184d2859274afdecac0327 (patch) | |
tree | 53830c3d01333b73fc96679e5c8680ef5b62500a /clang/lib/Frontend/CompilerInvocation.cpp | |
parent | ceb298be40211a7235f73c7ff9f46603ca84fd6b (diff) | |
download | llvm-29125ddf1323951901184d2859274afdecac0327.zip llvm-29125ddf1323951901184d2859274afdecac0327.tar.gz llvm-29125ddf1323951901184d2859274afdecac0327.tar.bz2 |
Start adding support for generating CC1 command lines from CompilerInvocation
This change includes the following:
- Add additional information in the relevant table-gen files to encode
the necessary information to automatically parse the argument into a
CompilerInvocation instance and to generate the appropriate command
line argument from a CompilerInvocation instance.
- Extend OptParserEmitter to emit the necessary macro tables as well as
constant tables to support parsing and generating command line
arguments for options that provide the necessary information.
- Port some options to use this new system for parsing and generating
command line arguments.
Differential Revision: https://reviews.llvm.org/D79796
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 137 |
1 files changed, 111 insertions, 26 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 28c4fda..debd793 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -118,6 +118,64 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) CompilerInvocationBase::~CompilerInvocationBase() = default; //===----------------------------------------------------------------------===// +// Normalizers +//===----------------------------------------------------------------------===// + +#define SIMPLE_ENUM_VALUE_TABLE +#include "clang/Driver/Options.inc" +#undef SIMPLE_ENUM_VALUE_TABLE + +static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt, + unsigned TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + assert(TableIndex >= 0); + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + + StringRef ArgValue = Arg->getValue(); + for (int I = 0, E = Table.Size; I != E; ++I) + if (ArgValue == Table.Table[I].Name) + return Table.Table[I].Value; + + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << ArgValue; + return None; +} + +static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + assert(TableIndex >= 0); + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + for (int I = 0, E = Table.Size; I != E; ++I) + if (Value == Table.Table[I].Value) + return Table.Table[I].Name; + + llvm_unreachable("The simple enum value was not correctly defined in " + "the tablegen option description"); +} + +static const char *denormalizeString(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, + const std::string &Value) { + return SA(Value); +} + +static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + return llvm::Triple::normalize(Arg->getValue()); +} + +//===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// @@ -528,25 +586,6 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } -static llvm::Reloc::Model getRelocModel(ArgList &Args, - DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) { - StringRef Value = A->getValue(); - auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(Value) - .Case("static", llvm::Reloc::Static) - .Case("pic", llvm::Reloc::PIC_) - .Case("ropi", llvm::Reloc::ROPI) - .Case("rwpi", llvm::Reloc::RWPI) - .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) - .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) - .Default(None); - if (RM.hasValue()) - return *RM; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return llvm::Reloc::PIC_; -} - /// Create a new Regex instance out of the string value in \p RpassArg. /// It returns a pointer to the newly generated Regex instance. static std::shared_ptr<llvm::Regex> @@ -927,7 +966,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers); Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); - Opts.RelocationModel = getRelocModel(Args, Diags); Opts.ThreadModel = std::string(Args.getLastArgValue(OPT_mthread_model, "posix")); if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") @@ -2107,7 +2145,6 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content); - Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); @@ -3609,11 +3646,6 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); Opts.LinkerVersion = std::string(Args.getLastArgValue(OPT_target_linker_version)); - Opts.Triple = std::string(Args.getLastArgValue(OPT_triple)); - // Use the default target triple if unspecified. - if (Opts.Triple.empty()) - Opts.Triple = llvm::sys::getDefaultTargetTriple(); - Opts.Triple = llvm::Triple::normalize(Opts.Triple); Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ); Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( @@ -3628,6 +3660,31 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, } } +bool CompilerInvocation::parseSimpleArgs(const ArgList &Args, + DiagnosticsEngine &Diags) { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + this->KEYPATH = Args.hasArg(OPT_##ID) && IS_POSITIVE; + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + { \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + this->KEYPATH = static_cast<TYPE>(*MaybeValue); \ + else \ + this->KEYPATH = DEFAULT_VALUE; \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG + return true; +} + bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs, DiagnosticsEngine &Diags, @@ -3661,6 +3718,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success = false; } + Success &= Res.parseSimpleArgs(Args, Diags); Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); @@ -3868,6 +3926,33 @@ std::string CompilerInvocation::getModuleHash() const { return llvm::APInt(64, code).toString(36, /*Signed=*/false); } +void CompilerInvocation::generateCC1CommandLine( + SmallVectorImpl<const char *> &Args, StringAllocator SA) const { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + if (FLAGS & options::CC1Option && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) \ + Args.push_back(SPELLING); + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + if ((FLAGS & options::CC1Option) && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \ + if (Option::KIND##Class == Option::SeparateClass) { \ + Args.push_back(SPELLING); \ + Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \ + } \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG +} + namespace clang { IntrusiveRefCntPtr<llvm::vfs::FileSystem> |