aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorDaniel Grumberg <dany.grumberg@gmail.com>2020-05-11 11:42:38 +0100
committerDaniel Grumberg <dany.grumberg@gmail.com>2020-06-24 18:05:05 +0100
commit29125ddf1323951901184d2859274afdecac0327 (patch)
tree53830c3d01333b73fc96679e5c8680ef5b62500a /clang/lib/Frontend/CompilerInvocation.cpp
parentceb298be40211a7235f73c7ff9f46603ca84fd6b (diff)
downloadllvm-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.cpp137
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>