aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-18 20:30:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-06 20:11:55 +0000
commit5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch)
tree1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
parent3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff)
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp1089
1 files changed, 648 insertions, 441 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
index 1fba91bed041..11f3f2c2d642 100644
--- a/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
@@ -48,7 +48,6 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/CachedHashString.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
@@ -126,45 +125,147 @@ static Expected<std::optional<uint32_t>> parseToleranceOption(StringRef Arg) {
// Initialization.
//===----------------------------------------------------------------------===//
-CompilerInvocationRefBase::CompilerInvocationRefBase()
- : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()),
- DiagnosticOpts(new DiagnosticOptions()),
- HeaderSearchOpts(new HeaderSearchOptions()),
- PreprocessorOpts(new PreprocessorOptions()),
- AnalyzerOpts(new AnalyzerOptions()) {}
-
-CompilerInvocationRefBase::CompilerInvocationRefBase(
- const CompilerInvocationRefBase &X)
- : LangOpts(new LangOptions(*X.getLangOpts())),
- TargetOpts(new TargetOptions(X.getTargetOpts())),
- DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
- HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
- PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())),
- AnalyzerOpts(new AnalyzerOptions(*X.getAnalyzerOpts())) {}
-
-CompilerInvocationRefBase::CompilerInvocationRefBase(
- CompilerInvocationRefBase &&X) = default;
-
-CompilerInvocationRefBase &
-CompilerInvocationRefBase::operator=(CompilerInvocationRefBase X) {
- LangOpts.swap(X.LangOpts);
- TargetOpts.swap(X.TargetOpts);
- DiagnosticOpts.swap(X.DiagnosticOpts);
- HeaderSearchOpts.swap(X.HeaderSearchOpts);
- PreprocessorOpts.swap(X.PreprocessorOpts);
- AnalyzerOpts.swap(X.AnalyzerOpts);
+namespace {
+template <class T> std::shared_ptr<T> make_shared_copy(const T &X) {
+ return std::make_shared<T>(X);
+}
+
+template <class T>
+llvm::IntrusiveRefCntPtr<T> makeIntrusiveRefCntCopy(const T &X) {
+ return llvm::makeIntrusiveRefCnt<T>(X);
+}
+} // namespace
+
+CompilerInvocationBase::CompilerInvocationBase()
+ : LangOpts(std::make_shared<LangOptions>()),
+ TargetOpts(std::make_shared<TargetOptions>()),
+ DiagnosticOpts(llvm::makeIntrusiveRefCnt<DiagnosticOptions>()),
+ HSOpts(std::make_shared<HeaderSearchOptions>()),
+ PPOpts(std::make_shared<PreprocessorOptions>()),
+ AnalyzerOpts(llvm::makeIntrusiveRefCnt<AnalyzerOptions>()),
+ MigratorOpts(std::make_shared<MigratorOptions>()),
+ APINotesOpts(std::make_shared<APINotesOptions>()),
+ CodeGenOpts(std::make_shared<CodeGenOptions>()),
+ FSOpts(std::make_shared<FileSystemOptions>()),
+ FrontendOpts(std::make_shared<FrontendOptions>()),
+ DependencyOutputOpts(std::make_shared<DependencyOutputOptions>()),
+ PreprocessorOutputOpts(std::make_shared<PreprocessorOutputOptions>()) {}
+
+CompilerInvocationBase &
+CompilerInvocationBase::deep_copy_assign(const CompilerInvocationBase &X) {
+ if (this != &X) {
+ LangOpts = make_shared_copy(X.getLangOpts());
+ TargetOpts = make_shared_copy(X.getTargetOpts());
+ DiagnosticOpts = makeIntrusiveRefCntCopy(X.getDiagnosticOpts());
+ HSOpts = make_shared_copy(X.getHeaderSearchOpts());
+ PPOpts = make_shared_copy(X.getPreprocessorOpts());
+ AnalyzerOpts = makeIntrusiveRefCntCopy(X.getAnalyzerOpts());
+ MigratorOpts = make_shared_copy(X.getMigratorOpts());
+ APINotesOpts = make_shared_copy(X.getAPINotesOpts());
+ CodeGenOpts = make_shared_copy(X.getCodeGenOpts());
+ FSOpts = make_shared_copy(X.getFileSystemOpts());
+ FrontendOpts = make_shared_copy(X.getFrontendOpts());
+ DependencyOutputOpts = make_shared_copy(X.getDependencyOutputOpts());
+ PreprocessorOutputOpts = make_shared_copy(X.getPreprocessorOutputOpts());
+ }
+ return *this;
+}
+
+CompilerInvocationBase &
+CompilerInvocationBase::shallow_copy_assign(const CompilerInvocationBase &X) {
+ if (this != &X) {
+ LangOpts = X.LangOpts;
+ TargetOpts = X.TargetOpts;
+ DiagnosticOpts = X.DiagnosticOpts;
+ HSOpts = X.HSOpts;
+ PPOpts = X.PPOpts;
+ AnalyzerOpts = X.AnalyzerOpts;
+ MigratorOpts = X.MigratorOpts;
+ APINotesOpts = X.APINotesOpts;
+ CodeGenOpts = X.CodeGenOpts;
+ FSOpts = X.FSOpts;
+ FrontendOpts = X.FrontendOpts;
+ DependencyOutputOpts = X.DependencyOutputOpts;
+ PreprocessorOutputOpts = X.PreprocessorOutputOpts;
+ }
return *this;
}
-CompilerInvocationRefBase &
-CompilerInvocationRefBase::operator=(CompilerInvocationRefBase &&X) = default;
+namespace {
+template <typename T>
+T &ensureOwned(std::shared_ptr<T> &Storage) {
+ if (Storage.use_count() > 1)
+ Storage = std::make_shared<T>(*Storage);
+ return *Storage;
+}
+
+template <typename T>
+T &ensureOwned(llvm::IntrusiveRefCntPtr<T> &Storage) {
+ if (Storage.useCount() > 1)
+ Storage = llvm::makeIntrusiveRefCnt<T>(*Storage);
+ return *Storage;
+}
+} // namespace
+
+LangOptions &CowCompilerInvocation::getMutLangOpts() {
+ return ensureOwned(LangOpts);
+}
+
+TargetOptions &CowCompilerInvocation::getMutTargetOpts() {
+ return ensureOwned(TargetOpts);
+}
+
+DiagnosticOptions &CowCompilerInvocation::getMutDiagnosticOpts() {
+ return ensureOwned(DiagnosticOpts);
+}
+
+HeaderSearchOptions &CowCompilerInvocation::getMutHeaderSearchOpts() {
+ return ensureOwned(HSOpts);
+}
+
+PreprocessorOptions &CowCompilerInvocation::getMutPreprocessorOpts() {
+ return ensureOwned(PPOpts);
+}
+
+AnalyzerOptions &CowCompilerInvocation::getMutAnalyzerOpts() {
+ return ensureOwned(AnalyzerOpts);
+}
+
+MigratorOptions &CowCompilerInvocation::getMutMigratorOpts() {
+ return ensureOwned(MigratorOpts);
+}
+
+APINotesOptions &CowCompilerInvocation::getMutAPINotesOpts() {
+ return ensureOwned(APINotesOpts);
+}
+
+CodeGenOptions &CowCompilerInvocation::getMutCodeGenOpts() {
+ return ensureOwned(CodeGenOpts);
+}
+
+FileSystemOptions &CowCompilerInvocation::getMutFileSystemOpts() {
+ return ensureOwned(FSOpts);
+}
+
+FrontendOptions &CowCompilerInvocation::getMutFrontendOpts() {
+ return ensureOwned(FrontendOpts);
+}
+
+DependencyOutputOptions &CowCompilerInvocation::getMutDependencyOutputOpts() {
+ return ensureOwned(DependencyOutputOpts);
+}
-CompilerInvocationRefBase::~CompilerInvocationRefBase() = default;
+PreprocessorOutputOptions &
+CowCompilerInvocation::getMutPreprocessorOutputOpts() {
+ return ensureOwned(PreprocessorOutputOpts);
+}
//===----------------------------------------------------------------------===//
// Normalizers
//===----------------------------------------------------------------------===//
+using ArgumentConsumer = CompilerInvocation::ArgumentConsumer;
+
#define SIMPLE_ENUM_VALUE_TABLE
#include "clang/Driver/Options.inc"
#undef SIMPLE_ENUM_VALUE_TABLE
@@ -191,11 +292,10 @@ static std::optional<bool> normalizeSimpleNegativeFlag(OptSpecifier Opt,
/// denormalizeSimpleFlags never looks at it. Avoid bloating compile-time with
/// unnecessary template instantiations and just ignore it with a variadic
/// argument.
-static void denormalizeSimpleFlag(SmallVectorImpl<const char *> &Args,
- const char *Spelling,
- CompilerInvocation::StringAllocator,
- Option::OptionClass, unsigned, /*T*/...) {
- Args.push_back(Spelling);
+static void denormalizeSimpleFlag(ArgumentConsumer Consumer,
+ const Twine &Spelling, Option::OptionClass,
+ unsigned, /*T*/...) {
+ Consumer(Spelling);
}
template <typename T> static constexpr bool is_uint64_t_convertible() {
@@ -232,29 +332,27 @@ static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue,
}
static auto makeBooleanOptionDenormalizer(bool Value) {
- return [Value](SmallVectorImpl<const char *> &Args, const char *Spelling,
- CompilerInvocation::StringAllocator, Option::OptionClass,
- unsigned, bool KeyPath) {
+ return [Value](ArgumentConsumer Consumer, const Twine &Spelling,
+ Option::OptionClass, unsigned, bool KeyPath) {
if (KeyPath == Value)
- Args.push_back(Spelling);
+ Consumer(Spelling);
};
}
-static void denormalizeStringImpl(SmallVectorImpl<const char *> &Args,
- const char *Spelling,
- CompilerInvocation::StringAllocator SA,
+static void denormalizeStringImpl(ArgumentConsumer Consumer,
+ const Twine &Spelling,
Option::OptionClass OptClass, unsigned,
const Twine &Value) {
switch (OptClass) {
case Option::SeparateClass:
case Option::JoinedOrSeparateClass:
case Option::JoinedAndSeparateClass:
- Args.push_back(Spelling);
- Args.push_back(SA(Value));
+ Consumer(Spelling);
+ Consumer(Value);
break;
case Option::JoinedClass:
case Option::CommaJoinedClass:
- Args.push_back(SA(Twine(Spelling) + Value));
+ Consumer(Spelling + Value);
break;
default:
llvm_unreachable("Cannot denormalize an option with option class "
@@ -263,11 +361,10 @@ static void denormalizeStringImpl(SmallVectorImpl<const char *> &Args,
}
template <typename T>
-static void
-denormalizeString(SmallVectorImpl<const char *> &Args, const char *Spelling,
- CompilerInvocation::StringAllocator SA,
- Option::OptionClass OptClass, unsigned TableIndex, T Value) {
- denormalizeStringImpl(Args, Spelling, SA, OptClass, TableIndex, Twine(Value));
+static void denormalizeString(ArgumentConsumer Consumer, const Twine &Spelling,
+ Option::OptionClass OptClass, unsigned TableIndex,
+ T Value) {
+ denormalizeStringImpl(Consumer, Spelling, OptClass, TableIndex, Twine(Value));
}
static std::optional<SimpleEnumValue>
@@ -308,15 +405,14 @@ static std::optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
return std::nullopt;
}
-static void denormalizeSimpleEnumImpl(SmallVectorImpl<const char *> &Args,
- const char *Spelling,
- CompilerInvocation::StringAllocator SA,
+static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer,
+ const Twine &Spelling,
Option::OptionClass OptClass,
unsigned TableIndex, unsigned Value) {
assert(TableIndex < SimpleEnumValueTablesSize);
const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) {
- denormalizeString(Args, Spelling, SA, OptClass, TableIndex,
+ denormalizeString(Consumer, Spelling, OptClass, TableIndex,
MaybeEnumVal->Name);
} else {
llvm_unreachable("The simple enum value was not correctly defined in "
@@ -325,12 +421,11 @@ static void denormalizeSimpleEnumImpl(SmallVectorImpl<const char *> &Args,
}
template <typename T>
-static void denormalizeSimpleEnum(SmallVectorImpl<const char *> &Args,
- const char *Spelling,
- CompilerInvocation::StringAllocator SA,
+static void denormalizeSimpleEnum(ArgumentConsumer Consumer,
+ const Twine &Spelling,
Option::OptionClass OptClass,
unsigned TableIndex, T Value) {
- return denormalizeSimpleEnumImpl(Args, Spelling, SA, OptClass, TableIndex,
+ return denormalizeSimpleEnumImpl(Consumer, Spelling, OptClass, TableIndex,
static_cast<unsigned>(Value));
}
@@ -366,9 +461,8 @@ normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
return Args.getAllArgValues(Opt);
}
-static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
- const char *Spelling,
- CompilerInvocation::StringAllocator SA,
+static void denormalizeStringVector(ArgumentConsumer Consumer,
+ const Twine &Spelling,
Option::OptionClass OptClass,
unsigned TableIndex,
const std::vector<std::string> &Values) {
@@ -382,7 +476,7 @@ static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
CommaJoinedValue.append(Value);
}
}
- denormalizeString(Args, Spelling, SA, Option::OptionClass::JoinedClass,
+ denormalizeString(Consumer, Spelling, Option::OptionClass::JoinedClass,
TableIndex, CommaJoinedValue);
break;
}
@@ -390,7 +484,7 @@ static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
case Option::SeparateClass:
case Option::JoinedOrSeparateClass:
for (const std::string &Value : Values)
- denormalizeString(Args, Spelling, SA, OptClass, TableIndex, Value);
+ denormalizeString(Consumer, Spelling, OptClass, TableIndex, Value);
break;
default:
llvm_unreachable("Cannot denormalize an option with option class "
@@ -427,11 +521,11 @@ static T extractMaskValue(T KeyPath) {
}
#define PARSE_OPTION_WITH_MARSHALLING( \
- ARGS, DIAGS, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
- PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \
- KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
- DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
- if ((FLAGS)&options::CC1Option) { \
+ ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \
+ FLAGS, VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, \
+ ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, \
+ NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
+ if ((VISIBILITY)&options::CC1Option) { \
KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
if (IMPLIED_CHECK) \
KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
@@ -444,18 +538,18 @@ static T extractMaskValue(T KeyPath) {
// Capture the extracted value as a lambda argument to avoid potential issues
// with lifetime extension of the reference.
#define GENERATE_OPTION_WITH_MARSHALLING( \
- ARGS, STRING_ALLOCATOR, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, \
- ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, \
- SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \
- IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
- if ((FLAGS)&options::CC1Option) { \
+ CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
+ VISIBILITY, PARAM, HELPTEXT, METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, \
+ KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
+ DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
+ if ((VISIBILITY)&options::CC1Option) { \
[&](const auto &Extracted) { \
if (ALWAYS_EMIT || \
(Extracted != \
static_cast<decltype(KEYPATH)>((IMPLIED_CHECK) ? (IMPLIED_VALUE) \
: (DEFAULT_VALUE)))) \
- DENORMALIZER(ARGS, SPELLING, STRING_ALLOCATOR, Option::KIND##Class, \
- TABLE_INDEX, Extracted); \
+ DENORMALIZER(CONSUMER, SPELLING, Option::KIND##Class, TABLE_INDEX, \
+ Extracted); \
}(EXTRACTOR(KEYPATH)); \
}
@@ -466,7 +560,7 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
InputKind IK) {
unsigned NumErrorsBefore = Diags.getNumErrors();
- LangOptions &LangOpts = *Invocation.getLangOpts();
+ LangOptions &LangOpts = Invocation.getLangOpts();
CodeGenOptions &CodeGenOpts = Invocation.getCodeGenOpts();
TargetOptions &TargetOpts = Invocation.getTargetOpts();
FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
@@ -486,6 +580,7 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
llvm::Triple::ArchType Arch = T.getArch();
CodeGenOpts.CodeModel = TargetOpts.CodeModel;
+ CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
if (LangOpts.getExceptionHandling() !=
LangOptions::ExceptionHandlingKind::None &&
@@ -559,6 +654,7 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
DefaultCC == LangOptions::DCC_RegCall) &&
!T.isX86();
+ emitError |= DefaultCC == LangOptions::DCC_RtdCall && Arch != llvm::Triple::m68k;
if (emitError)
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << T.getTriple();
@@ -573,27 +669,27 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
- unsigned DefaultOpt = llvm::CodeGenOpt::None;
+ unsigned DefaultOpt = 0;
if ((IK.getLanguage() == Language::OpenCL ||
IK.getLanguage() == Language::OpenCLCXX) &&
!Args.hasArg(OPT_cl_opt_disable))
- DefaultOpt = llvm::CodeGenOpt::Default;
+ DefaultOpt = 2;
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O0))
- return llvm::CodeGenOpt::None;
+ return 0;
if (A->getOption().matches(options::OPT_Ofast))
- return llvm::CodeGenOpt::Aggressive;
+ return 3;
assert(A->getOption().matches(options::OPT_O));
StringRef S(A->getValue());
if (S == "s" || S == "z")
- return llvm::CodeGenOpt::Default;
+ return 2;
if (S == "g")
- return llvm::CodeGenOpt::Less;
+ return 1;
return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
}
@@ -617,21 +713,18 @@ static unsigned getOptimizationLevelSize(ArgList &Args) {
return 0;
}
-static void GenerateArg(SmallVectorImpl<const char *> &Args,
- llvm::opt::OptSpecifier OptSpecifier,
- CompilerInvocation::StringAllocator SA) {
+static void GenerateArg(ArgumentConsumer Consumer,
+ llvm::opt::OptSpecifier OptSpecifier) {
Option Opt = getDriverOptTable().getOption(OptSpecifier);
- denormalizeSimpleFlag(Args, SA(Opt.getPrefix() + Opt.getName()), SA,
+ denormalizeSimpleFlag(Consumer, Opt.getPrefixedName(),
Option::OptionClass::FlagClass, 0);
}
-static void GenerateArg(SmallVectorImpl<const char *> &Args,
+static void GenerateArg(ArgumentConsumer Consumer,
llvm::opt::OptSpecifier OptSpecifier,
- const Twine &Value,
- CompilerInvocation::StringAllocator SA) {
+ const Twine &Value) {
Option Opt = getDriverOptTable().getOption(OptSpecifier);
- denormalizeString(Args, SA(Opt.getPrefix() + Opt.getName()), SA,
- Opt.getKind(), 0, Value);
+ denormalizeString(Consumer, Opt.getPrefixedName(), Opt.getKind(), 0, Value);
}
// Parse command line arguments into CompilerInvocation.
@@ -846,13 +939,12 @@ static void getAllNoBuiltinFuncValues(ArgList &Args,
Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
}
-static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts,
+ ArgumentConsumer Consumer) {
const AnalyzerOptions *AnalyzerOpts = &Opts;
#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef ANALYZER_OPTION_WITH_MARSHALLING
@@ -860,7 +952,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
switch (Opts.AnalysisConstraintsOpt) {
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
case NAME##Model: \
- GenerateArg(Args, OPT_analyzer_constraints, CMDFLAG, SA); \
+ GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
default:
@@ -872,7 +964,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
switch (Opts.AnalysisDiagOpt) {
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
case PD_##NAME: \
- GenerateArg(Args, OPT_analyzer_output, CMDFLAG, SA); \
+ GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
default:
@@ -884,7 +976,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
switch (Opts.AnalysisPurgeOpt) {
#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
case NAME: \
- GenerateArg(Args, OPT_analyzer_purge, CMDFLAG, SA); \
+ GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
default:
@@ -896,7 +988,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
switch (Opts.InliningMode) {
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
case NAME: \
- GenerateArg(Args, OPT_analyzer_inlining_mode, CMDFLAG, SA); \
+ GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
default:
@@ -907,7 +999,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
for (const auto &CP : Opts.CheckersAndPackages) {
OptSpecifier Opt =
CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
- GenerateArg(Args, Opt, CP.first, SA);
+ GenerateArg(Consumer, Opt, CP.first);
}
AnalyzerOptions ConfigOpts;
@@ -926,7 +1018,7 @@ static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)
continue;
- GenerateArg(Args, OPT_analyzer_config, Key + "=" + Value, SA);
+ GenerateArg(Consumer, OPT_analyzer_config, Key + "=" + Value);
}
// Nothing to generate for FullCompilerInvocation.
@@ -1192,16 +1284,15 @@ static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
/// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`.
static void
-GenerateOptimizationRemark(SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA,
- OptSpecifier OptEQ, StringRef Name,
+GenerateOptimizationRemark(ArgumentConsumer Consumer, OptSpecifier OptEQ,
+ StringRef Name,
const CodeGenOptions::OptRemark &Remark) {
if (Remark.hasValidPattern()) {
- GenerateArg(Args, OptEQ, Remark.Pattern, SA);
+ GenerateArg(Consumer, OptEQ, Remark.Pattern);
} else if (Remark.Kind == CodeGenOptions::RK_Enabled) {
- GenerateArg(Args, OPT_R_Joined, Name, SA);
+ GenerateArg(Consumer, OPT_R_Joined, Name);
} else if (Remark.Kind == CodeGenOptions::RK_Disabled) {
- GenerateArg(Args, OPT_R_Joined, StringRef("no-") + Name, SA);
+ GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);
}
}
@@ -1356,35 +1447,36 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts,
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
}
-void CompilerInvocation::GenerateCodeGenArgs(
- const CodeGenOptions &Opts, SmallVectorImpl<const char *> &Args,
- StringAllocator SA, const llvm::Triple &T, const std::string &OutputFile,
- const LangOptions *LangOpts) {
+void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
+ ArgumentConsumer Consumer,
+ const llvm::Triple &T,
+ const std::string &OutputFile,
+ const LangOptions *LangOpts) {
const CodeGenOptions &CodeGenOpts = Opts;
if (Opts.OptimizationLevel == 0)
- GenerateArg(Args, OPT_O0, SA);
+ GenerateArg(Consumer, OPT_O0);
else
- GenerateArg(Args, OPT_O, Twine(Opts.OptimizationLevel), SA);
+ GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));
#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef CODEGEN_OPTION_WITH_MARSHALLING
if (Opts.OptimizationLevel > 0) {
if (Opts.Inlining == CodeGenOptions::NormalInlining)
- GenerateArg(Args, OPT_finline_functions, SA);
+ GenerateArg(Consumer, OPT_finline_functions);
else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining)
- GenerateArg(Args, OPT_finline_hint_functions, SA);
+ GenerateArg(Consumer, OPT_finline_hint_functions);
else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining)
- GenerateArg(Args, OPT_fno_inline, SA);
+ GenerateArg(Consumer, OPT_fno_inline);
}
if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)
- GenerateArg(Args, OPT_fdirect_access_external_data, SA);
+ GenerateArg(Consumer, OPT_fdirect_access_external_data);
else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
- GenerateArg(Args, OPT_fno_direct_access_external_data, SA);
+ GenerateArg(Consumer, OPT_fno_direct_access_external_data);
std::optional<StringRef> DebugInfoVal;
switch (Opts.DebugInfo) {
@@ -1414,23 +1506,23 @@ void CompilerInvocation::GenerateCodeGenArgs(
break;
}
if (DebugInfoVal)
- GenerateArg(Args, OPT_debug_info_kind_EQ, *DebugInfoVal, SA);
+ GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
for (const auto &Prefix : Opts.DebugPrefixMap)
- GenerateArg(Args, OPT_fdebug_prefix_map_EQ,
- Prefix.first + "=" + Prefix.second, SA);
+ GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,
+ Prefix.first + "=" + Prefix.second);
for (const auto &Prefix : Opts.CoveragePrefixMap)
- GenerateArg(Args, OPT_fcoverage_prefix_map_EQ,
- Prefix.first + "=" + Prefix.second, SA);
+ GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
+ Prefix.first + "=" + Prefix.second);
if (Opts.NewStructPathTBAA)
- GenerateArg(Args, OPT_new_struct_path_tbaa, SA);
+ GenerateArg(Consumer, OPT_new_struct_path_tbaa);
if (Opts.OptimizeSize == 1)
- GenerateArg(Args, OPT_O, "s", SA);
+ GenerateArg(Consumer, OPT_O, "s");
else if (Opts.OptimizeSize == 2)
- GenerateArg(Args, OPT_O, "z", SA);
+ GenerateArg(Consumer, OPT_O, "z");
// SimplifyLibCalls is set only in the absence of -fno-builtin and
// -ffreestanding. We'll consider that when generating them.
@@ -1438,65 +1530,65 @@ void CompilerInvocation::GenerateCodeGenArgs(
// NoBuiltinFuncs are generated by LangOptions.
if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
- GenerateArg(Args, OPT_funroll_loops, SA);
+ GenerateArg(Consumer, OPT_funroll_loops);
else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
- GenerateArg(Args, OPT_fno_unroll_loops, SA);
+ GenerateArg(Consumer, OPT_fno_unroll_loops);
if (!Opts.BinutilsVersion.empty())
- GenerateArg(Args, OPT_fbinutils_version_EQ, Opts.BinutilsVersion, SA);
+ GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion);
if (Opts.DebugNameTable ==
static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
- GenerateArg(Args, OPT_ggnu_pubnames, SA);
+ GenerateArg(Consumer, OPT_ggnu_pubnames);
else if (Opts.DebugNameTable ==
static_cast<unsigned>(
llvm::DICompileUnit::DebugNameTableKind::Default))
- GenerateArg(Args, OPT_gpubnames, SA);
+ GenerateArg(Consumer, OPT_gpubnames);
auto TNK = Opts.getDebugSimpleTemplateNames();
if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {
if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)
- GenerateArg(Args, OPT_gsimple_template_names_EQ, "simple", SA);
+ GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple");
else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)
- GenerateArg(Args, OPT_gsimple_template_names_EQ, "mangled", SA);
+ GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled");
}
// ProfileInstrumentUsePath is marshalled automatically, no need to generate
// it or PGOUseInstrumentor.
if (Opts.TimePasses) {
if (Opts.TimePassesPerRun)
- GenerateArg(Args, OPT_ftime_report_EQ, "per-pass-run", SA);
+ GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");
else
- GenerateArg(Args, OPT_ftime_report, SA);
+ GenerateArg(Consumer, OPT_ftime_report);
}
if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
- GenerateArg(Args, OPT_flto_EQ, "full", SA);
+ GenerateArg(Consumer, OPT_flto_EQ, "full");
if (Opts.PrepareForThinLTO)
- GenerateArg(Args, OPT_flto_EQ, "thin", SA);
+ GenerateArg(Consumer, OPT_flto_EQ, "thin");
if (!Opts.ThinLTOIndexFile.empty())
- GenerateArg(Args, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile, SA);
+ GenerateArg(Consumer, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile);
if (Opts.SaveTempsFilePrefix == OutputFile)
- GenerateArg(Args, OPT_save_temps_EQ, "obj", SA);
+ GenerateArg(Consumer, OPT_save_temps_EQ, "obj");
StringRef MemProfileBasename("memprof.profraw");
if (!Opts.MemoryProfileOutput.empty()) {
if (Opts.MemoryProfileOutput == MemProfileBasename) {
- GenerateArg(Args, OPT_fmemory_profile, SA);
+ GenerateArg(Consumer, OPT_fmemory_profile);
} else {
size_t ArgLength =
Opts.MemoryProfileOutput.size() - MemProfileBasename.size();
- GenerateArg(Args, OPT_fmemory_profile_EQ,
- Opts.MemoryProfileOutput.substr(0, ArgLength), SA);
+ GenerateArg(Consumer, OPT_fmemory_profile_EQ,
+ Opts.MemoryProfileOutput.substr(0, ArgLength));
}
}
if (memcmp(Opts.CoverageVersion, "408*", 4) != 0)
- GenerateArg(Args, OPT_coverage_version_EQ,
- StringRef(Opts.CoverageVersion, 4), SA);
+ GenerateArg(Consumer, OPT_coverage_version_EQ,
+ StringRef(Opts.CoverageVersion, 4));
// TODO: Check if we need to generate arguments stored in CmdArgs. (Namely
// '-fembed_bitcode', which does not map to any CompilerInvocation field and
@@ -1506,95 +1598,94 @@ void CompilerInvocation::GenerateCodeGenArgs(
std::string InstrBundle =
serializeXRayInstrumentationBundle(Opts.XRayInstrumentationBundle);
if (!InstrBundle.empty())
- GenerateArg(Args, OPT_fxray_instrumentation_bundle, InstrBundle, SA);
+ GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);
}
if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
- GenerateArg(Args, OPT_fcf_protection_EQ, "full", SA);
+ GenerateArg(Consumer, OPT_fcf_protection_EQ, "full");
else if (Opts.CFProtectionReturn)
- GenerateArg(Args, OPT_fcf_protection_EQ, "return", SA);
+ GenerateArg(Consumer, OPT_fcf_protection_EQ, "return");
else if (Opts.CFProtectionBranch)
- GenerateArg(Args, OPT_fcf_protection_EQ, "branch", SA);
+ GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
if (Opts.FunctionReturnThunks)
- GenerateArg(Args, OPT_mfunction_return_EQ, "thunk-extern", SA);
+ GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
for (const auto &F : Opts.LinkBitcodeFiles) {
bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
F.PropagateAttrs && F.Internalize;
- GenerateArg(Args,
+ GenerateArg(Consumer,
Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
- F.Filename, SA);
+ F.Filename);
}
if (Opts.EmulatedTLS)
- GenerateArg(Args, OPT_femulated_tls, SA);
+ GenerateArg(Consumer, OPT_femulated_tls);
if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
- GenerateArg(Args, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str(), SA);
+ GenerateArg(Consumer, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str());
if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) ||
(Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()))
- GenerateArg(Args, OPT_fdenormal_fp_math_f32_EQ, Opts.FP32DenormalMode.str(),
- SA);
+ GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
+ Opts.FP32DenormalMode.str());
if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) {
OptSpecifier Opt =
T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
- GenerateArg(Args, Opt, SA);
+ GenerateArg(Consumer, Opt);
} else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) {
OptSpecifier Opt =
T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
- GenerateArg(Args, Opt, SA);
+ GenerateArg(Consumer, Opt);
}
if (Opts.EnableAIXExtendedAltivecABI)
- GenerateArg(Args, OPT_mabi_EQ_vec_extabi, SA);
+ GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi);
if (Opts.XCOFFReadOnlyPointers)
- GenerateArg(Args, OPT_mxcoff_roptr, SA);
+ GenerateArg(Consumer, OPT_mxcoff_roptr);
if (!Opts.OptRecordPasses.empty())
- GenerateArg(Args, OPT_opt_record_passes, Opts.OptRecordPasses, SA);
+ GenerateArg(Consumer, OPT_opt_record_passes, Opts.OptRecordPasses);
if (!Opts.OptRecordFormat.empty())
- GenerateArg(Args, OPT_opt_record_format, Opts.OptRecordFormat, SA);
+ GenerateArg(Consumer, OPT_opt_record_format, Opts.OptRecordFormat);
- GenerateOptimizationRemark(Args, SA, OPT_Rpass_EQ, "pass",
+ GenerateOptimizationRemark(Consumer, OPT_Rpass_EQ, "pass",
Opts.OptimizationRemark);
- GenerateOptimizationRemark(Args, SA, OPT_Rpass_missed_EQ, "pass-missed",
+ GenerateOptimizationRemark(Consumer, OPT_Rpass_missed_EQ, "pass-missed",
Opts.OptimizationRemarkMissed);
- GenerateOptimizationRemark(Args, SA, OPT_Rpass_analysis_EQ, "pass-analysis",
+ GenerateOptimizationRemark(Consumer, OPT_Rpass_analysis_EQ, "pass-analysis",
Opts.OptimizationRemarkAnalysis);
- GenerateArg(Args, OPT_fdiagnostics_hotness_threshold_EQ,
+ GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
Opts.DiagnosticsHotnessThreshold
? Twine(*Opts.DiagnosticsHotnessThreshold)
- : "auto",
- SA);
+ : "auto");
- GenerateArg(Args, OPT_fdiagnostics_misexpect_tolerance_EQ,
- Twine(*Opts.DiagnosticsMisExpectTolerance), SA);
+ GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
+ Twine(*Opts.DiagnosticsMisExpectTolerance));
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover))
- GenerateArg(Args, OPT_fsanitize_recover_EQ, Sanitizer, SA);
+ GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
- GenerateArg(Args, OPT_fsanitize_trap_EQ, Sanitizer, SA);
+ GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
if (!Opts.EmitVersionIdentMetadata)
- GenerateArg(Args, OPT_Qn, SA);
+ GenerateArg(Consumer, OPT_Qn);
switch (Opts.FiniteLoops) {
case CodeGenOptions::FiniteLoopsKind::Language:
break;
case CodeGenOptions::FiniteLoopsKind::Always:
- GenerateArg(Args, OPT_ffinite_loops, SA);
+ GenerateArg(Consumer, OPT_ffinite_loops);
break;
case CodeGenOptions::FiniteLoopsKind::Never:
- GenerateArg(Args, OPT_fno_finite_loops, SA);
+ GenerateArg(Consumer, OPT_fno_finite_loops);
break;
}
}
@@ -1770,6 +1861,20 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_funified_lto))
Opts.PrepareForThinLTO = true;
}
+ if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects,
+ options::OPT_fno_fat_lto_objects)) {
+ if (A->getOption().matches(options::OPT_ffat_lto_objects)) {
+ if (Arg *Uni = Args.getLastArg(options::OPT_funified_lto,
+ options::OPT_fno_unified_lto)) {
+ if (Uni->getOption().matches(options::OPT_fno_unified_lto))
+ Diags.Report(diag::err_drv_incompatible_options)
+ << A->getAsString(Args) << "-fno-unified-lto";
+ } else
+ Diags.Report(diag::err_drv_argument_only_allowed_with)
+ << A->getAsString(Args) << "-funified-lto";
+ }
+ }
+
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
if (IK.getLanguage() != Language::LLVM_IR)
Diags.Report(diag::err_drv_argument_only_allowed_with)
@@ -1887,7 +1992,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
if (T.isOSAIX()) {
StringRef Name = A->getValue();
- if (Name != "global-dynamic" && Name != "local-exec")
+ if (Name == "local-dynamic")
Diags.Report(diag::err_aix_unsupported_tls_model) << Name;
}
}
@@ -2067,18 +2172,16 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}
-static void
-GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts,
+ ArgumentConsumer Consumer) {
const DependencyOutputOptions &DependencyOutputOpts = Opts;
#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
if (Opts.ShowIncludesDest != ShowIncludesDestination::None)
- GenerateArg(Args, OPT_show_includes, SA);
+ GenerateArg(Consumer, OPT_show_includes);
for (const auto &Dep : Opts.ExtraDeps) {
switch (Dep.second) {
@@ -2094,7 +2197,7 @@ GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts,
// marshalling infrastructure.
continue;
case EDK_DepFileEntry:
- GenerateArg(Args, OPT_fdepfile_entry, Dep.first, SA);
+ GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
break;
}
}
@@ -2220,12 +2323,11 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
}
static void GenerateFileSystemArgs(const FileSystemOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+ ArgumentConsumer Consumer) {
const FileSystemOptions &FileSystemOpts = Opts;
#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
}
@@ -2245,11 +2347,10 @@ static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
}
static void GenerateMigratorArgs(const MigratorOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+ ArgumentConsumer Consumer) {
const MigratorOptions &MigratorOpts = Opts;
#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef MIGRATOR_OPTION_WITH_MARSHALLING
}
@@ -2268,51 +2369,51 @@ static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}
-void CompilerInvocation::GenerateDiagnosticArgs(
- const DiagnosticOptions &Opts, SmallVectorImpl<const char *> &Args,
- StringAllocator SA, bool DefaultDiagColor) {
+void CompilerInvocationBase::GenerateDiagnosticArgs(
+ const DiagnosticOptions &Opts, ArgumentConsumer Consumer,
+ bool DefaultDiagColor) {
const DiagnosticOptions *DiagnosticOpts = &Opts;
#define DIAG_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef DIAG_OPTION_WITH_MARSHALLING
if (!Opts.DiagnosticSerializationFile.empty())
- GenerateArg(Args, OPT_diagnostic_serialized_file,
- Opts.DiagnosticSerializationFile, SA);
+ GenerateArg(Consumer, OPT_diagnostic_serialized_file,
+ Opts.DiagnosticSerializationFile);
if (Opts.ShowColors)
- GenerateArg(Args, OPT_fcolor_diagnostics, SA);
+ GenerateArg(Consumer, OPT_fcolor_diagnostics);
if (Opts.VerifyDiagnostics &&
llvm::is_contained(Opts.VerifyPrefixes, "expected"))
- GenerateArg(Args, OPT_verify, SA);
+ GenerateArg(Consumer, OPT_verify);
for (const auto &Prefix : Opts.VerifyPrefixes)
if (Prefix != "expected")
- GenerateArg(Args, OPT_verify_EQ, Prefix, SA);
+ GenerateArg(Consumer, OPT_verify_EQ, Prefix);
DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected();
if (VIU == DiagnosticLevelMask::None) {
// This is the default, don't generate anything.
} else if (VIU == DiagnosticLevelMask::All) {
- GenerateArg(Args, OPT_verify_ignore_unexpected, SA);
+ GenerateArg(Consumer, OPT_verify_ignore_unexpected);
} else {
if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Note) != 0)
- GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "note", SA);
+ GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Remark) != 0)
- GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "remark", SA);
+ GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Warning) != 0)
- GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "warning", SA);
+ GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Error) != 0)
- GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "error", SA);
+ GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
}
for (const auto &Warning : Opts.Warnings) {
// This option is automatically generated from UndefPrefixes.
if (Warning == "undef-prefix")
continue;
- Args.push_back(SA(StringRef("-W") + Warning));
+ Consumer(StringRef("-W") + Warning);
}
for (const auto &Remark : Opts.Remarks) {
@@ -2324,7 +2425,7 @@ void CompilerInvocation::GenerateDiagnosticArgs(
if (llvm::is_contained(IgnoredRemarks, Remark))
continue;
- Args.push_back(SA(StringRef("-R") + Remark));
+ Consumer(StringRef("-R") + Remark);
}
}
@@ -2510,12 +2611,10 @@ getProgramActionOpt(frontend::ActionKind ProgramAction) {
}
static void GenerateFrontendArgs(const FrontendOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA,
- bool IsHeader) {
+ ArgumentConsumer Consumer, bool IsHeader) {
const FrontendOptions &FrontendOpts = Opts;
#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef FRONTEND_OPTION_WITH_MARSHALLING
@@ -2524,7 +2623,7 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
// Generating a simple flag covers most frontend actions.
std::function<void()> GenerateProgramAction = [&]() {
- GenerateArg(Args, *ProgramActionOpt, SA);
+ GenerateArg(Consumer, *ProgramActionOpt);
};
if (!ProgramActionOpt) {
@@ -2532,7 +2631,7 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
assert(Opts.ProgramAction == frontend::PluginAction &&
"Frontend action without option.");
GenerateProgramAction = [&]() {
- GenerateArg(Args, OPT_plugin, Opts.ActionName, SA);
+ GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
};
}
@@ -2553,21 +2652,21 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
}
if (Opts.ASTDumpAll)
- GenerateArg(Args, OPT_ast_dump_all_EQ, Format, SA);
+ GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
if (Opts.ASTDumpDecls)
- GenerateArg(Args, OPT_ast_dump_EQ, Format, SA);
+ GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
} else {
if (Opts.ASTDumpAll)
- GenerateArg(Args, OPT_ast_dump_all, SA);
+ GenerateArg(Consumer, OPT_ast_dump_all);
if (Opts.ASTDumpDecls)
- GenerateArg(Args, OPT_ast_dump, SA);
+ GenerateArg(Consumer, OPT_ast_dump);
}
};
}
if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
GenerateProgramAction = [&]() {
- GenerateArg(Args, OPT_fixit_EQ, Opts.FixItSuffix, SA);
+ GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
};
}
@@ -2575,34 +2674,34 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
for (const auto &PluginArgs : Opts.PluginArgs) {
Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
- const char *Spelling =
- SA(Opt.getPrefix() + Opt.getName() + PluginArgs.first);
for (const auto &PluginArg : PluginArgs.second)
- denormalizeString(Args, Spelling, SA, Opt.getKind(), 0, PluginArg);
+ denormalizeString(Consumer,
+ Opt.getPrefix() + Opt.getName() + PluginArgs.first,
+ Opt.getKind(), 0, PluginArg);
}
for (const auto &Ext : Opts.ModuleFileExtensions)
if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
- GenerateArg(Args, OPT_ftest_module_file_extension_EQ, TestExt->str(), SA);
+ GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
if (!Opts.CodeCompletionAt.FileName.empty())
- GenerateArg(Args, OPT_code_completion_at, Opts.CodeCompletionAt.ToString(),
- SA);
+ GenerateArg(Consumer, OPT_code_completion_at,
+ Opts.CodeCompletionAt.ToString());
for (const auto &Plugin : Opts.Plugins)
- GenerateArg(Args, OPT_load, Plugin, SA);
+ GenerateArg(Consumer, OPT_load, Plugin);
// ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
for (const auto &ModuleFile : Opts.ModuleFiles)
- GenerateArg(Args, OPT_fmodule_file, ModuleFile, SA);
+ GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
if (Opts.AuxTargetCPU)
- GenerateArg(Args, OPT_aux_target_cpu, *Opts.AuxTargetCPU, SA);
+ GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
if (Opts.AuxTargetFeatures)
for (const auto &Feature : *Opts.AuxTargetFeatures)
- GenerateArg(Args, OPT_aux_target_feature, Feature, SA);
+ GenerateArg(Consumer, OPT_aux_target_feature, Feature);
{
StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
@@ -2669,13 +2768,13 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
break;
}
- GenerateArg(Args, OPT_x,
- Lang + HeaderUnit + Header + ModuleMap + Preprocessed, SA);
+ GenerateArg(Consumer, OPT_x,
+ Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
}
// OPT_INPUT has a unique class, generate it directly.
for (const auto &Input : Opts.Inputs)
- Args.push_back(SA(Input.getFile()));
+ Consumer(Input.getFile());
}
static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
@@ -2730,7 +2829,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
"-interface-stub-version=ifs-v1"
<< ErrorMessage;
ProgramAction = frontend::ParseSyntaxOnly;
- } else if (!ArgStr.startswith("ifs-")) {
+ } else if (!ArgStr.starts_with("ifs-")) {
std::string ErrorMessage =
"Invalid interface stub format: " + ArgStr.str() + ".";
Diags.Report(diag::err_drv_invalid_value)
@@ -2933,29 +3032,28 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
}
-static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
+ ArgumentConsumer Consumer) {
const HeaderSearchOptions *HeaderSearchOpts = &Opts;
#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
if (Opts.UseLibcxx)
- GenerateArg(Args, OPT_stdlib_EQ, "libc++", SA);
+ GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
if (!Opts.ModuleCachePath.empty())
- GenerateArg(Args, OPT_fmodules_cache_path, Opts.ModuleCachePath, SA);
+ GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath);
for (const auto &File : Opts.PrebuiltModuleFiles)
- GenerateArg(Args, OPT_fmodule_file, File.first + "=" + File.second, SA);
+ GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
for (const auto &Path : Opts.PrebuiltModulePaths)
- GenerateArg(Args, OPT_fprebuilt_module_path, Path, SA);
+ GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
for (const auto &Macro : Opts.ModulesIgnoreMacros)
- GenerateArg(Args, OPT_fmodules_ignore_macro, Macro.val(), SA);
+ GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
auto Matches = [](const HeaderSearchOptions::Entry &Entry,
llvm::ArrayRef<frontend::IncludeDirGroup> Groups,
@@ -2986,8 +3084,8 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
}();
if (It->Group == frontend::IndexHeaderMap)
- GenerateArg(Args, OPT_index_header_map, SA);
- GenerateArg(Args, Opt, It->Path, SA);
+ GenerateArg(Consumer, OPT_index_header_map);
+ GenerateArg(Consumer, Opt, It->Path);
};
// Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
@@ -2999,34 +3097,34 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
++It) {
OptSpecifier Opt =
It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
- GenerateArg(Args, Opt, It->Path, SA);
+ GenerateArg(Consumer, Opt, It->Path);
}
// Note: Some paths that came from "-idirafter=xxyy" may have already been
// generated as "-iwithprefix=xxyy". If that's the case, their position on
// command line was such that this has no semantic impact on include paths.
for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
- GenerateArg(Args, OPT_idirafter, It->Path, SA);
+ GenerateArg(Consumer, OPT_idirafter, It->Path);
for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
- GenerateArg(Args, OPT_iquote, It->Path, SA);
+ GenerateArg(Consumer, OPT_iquote, It->Path);
for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
++It)
- GenerateArg(Args, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
- It->Path, SA);
+ GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
+ It->Path);
for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
- GenerateArg(Args, OPT_iframework, It->Path, SA);
+ GenerateArg(Consumer, OPT_iframework, It->Path);
for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
- GenerateArg(Args, OPT_iframeworkwithsysroot, It->Path, SA);
+ GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
// Add the paths for the various language specific isystem flags.
for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
- GenerateArg(Args, OPT_c_isystem, It->Path, SA);
+ GenerateArg(Consumer, OPT_c_isystem, It->Path);
for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
- GenerateArg(Args, OPT_cxx_isystem, It->Path, SA);
+ GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
- GenerateArg(Args, OPT_objc_isystem, It->Path, SA);
+ GenerateArg(Consumer, OPT_objc_isystem, It->Path);
for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
- GenerateArg(Args, OPT_objcxx_isystem, It->Path, SA);
+ GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
// Add the internal paths from a driver that detects standard include paths.
// Note: Some paths that came from "-internal-isystem" arguments may have
@@ -3038,7 +3136,7 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
OptSpecifier Opt = It->Group == frontend::System
? OPT_internal_isystem
: OPT_internal_externc_isystem;
- GenerateArg(Args, Opt, It->Path, SA);
+ GenerateArg(Consumer, Opt, It->Path);
}
assert(It == End && "Unhandled HeaderSearchOption::Entry.");
@@ -3047,11 +3145,11 @@ static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts,
for (const auto &P : Opts.SystemHeaderPrefixes) {
OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
: OPT_no_system_header_prefix;
- GenerateArg(Args, Opt, P.Prefix, SA);
+ GenerateArg(Consumer, Opt, P.Prefix);
}
for (const std::string &F : Opts.VFSOverlayFiles)
- GenerateArg(Args, OPT_ivfsoverlay, F, SA);
+ GenerateArg(Consumer, OPT_ivfsoverlay, F);
}
static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
@@ -3085,8 +3183,8 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
StringRef Val = A->getValue();
if (Val.contains('=')) {
auto Split = Val.split('=');
- Opts.PrebuiltModuleFiles.insert(
- {std::string(Split.first), std::string(Split.second)});
+ Opts.PrebuiltModuleFiles.insert_or_assign(
+ std::string(Split.first), std::string(Split.second));
}
}
for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
@@ -3183,6 +3281,27 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}
+static void GenerateAPINotesArgs(const APINotesOptions &Opts,
+ ArgumentConsumer Consumer) {
+ if (!Opts.SwiftVersion.empty())
+ GenerateArg(Consumer, OPT_fapinotes_swift_version,
+ Opts.SwiftVersion.getAsString());
+
+ for (const auto &Path : Opts.ModuleSearchPaths)
+ GenerateArg(Consumer, OPT_iapinotes_modules, Path);
+}
+
+static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
+ DiagnosticsEngine &diags) {
+ if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
+ if (Opts.SwiftVersion.tryParse(A->getValue()))
+ diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
+ Opts.ModuleSearchPaths.push_back(A->getValue());
+}
+
/// Check if input file kind and language standard are compatible.
static bool IsInputCompatibleWithStandard(InputKind IK,
const LangStandard &S) {
@@ -3264,20 +3383,20 @@ static StringRef GetInputKindName(InputKind IK) {
llvm_unreachable("unknown input language");
}
-void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- StringAllocator SA,
- const llvm::Triple &T, InputKind IK) {
+void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
+ ArgumentConsumer Consumer,
+ const llvm::Triple &T,
+ InputKind IK) {
if (IK.getFormat() == InputKind::Precompiled ||
IK.getLanguage() == Language::LLVM_IR) {
if (Opts.ObjCAutoRefCount)
- GenerateArg(Args, OPT_fobjc_arc, SA);
+ GenerateArg(Consumer, OPT_fobjc_arc);
if (Opts.PICLevel != 0)
- GenerateArg(Args, OPT_pic_level, Twine(Opts.PICLevel), SA);
+ GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
if (Opts.PIE)
- GenerateArg(Args, OPT_pic_is_pie, SA);
+ GenerateArg(Consumer, OPT_pic_is_pie);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
- GenerateArg(Args, OPT_fsanitize_EQ, Sanitizer, SA);
+ GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
return;
}
@@ -3299,145 +3418,145 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
}
auto LangStandard = LangStandard::getLangStandardForKind(Opts.LangStd);
- GenerateArg(Args, StdOpt, LangStandard.getName(), SA);
+ GenerateArg(Consumer, StdOpt, LangStandard.getName());
if (Opts.IncludeDefaultHeader)
- GenerateArg(Args, OPT_finclude_default_header, SA);
+ GenerateArg(Consumer, OPT_finclude_default_header);
if (Opts.DeclareOpenCLBuiltins)
- GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA);
+ GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
const LangOptions *LangOpts = &Opts;
#define LANG_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef LANG_OPTION_WITH_MARSHALLING
// The '-fcf-protection=' option is generated by CodeGenOpts generator.
if (Opts.ObjC) {
- GenerateArg(Args, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString(), SA);
+ GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
if (Opts.GC == LangOptions::GCOnly)
- GenerateArg(Args, OPT_fobjc_gc_only, SA);
+ GenerateArg(Consumer, OPT_fobjc_gc_only);
else if (Opts.GC == LangOptions::HybridGC)
- GenerateArg(Args, OPT_fobjc_gc, SA);
+ GenerateArg(Consumer, OPT_fobjc_gc);
else if (Opts.ObjCAutoRefCount == 1)
- GenerateArg(Args, OPT_fobjc_arc, SA);
+ GenerateArg(Consumer, OPT_fobjc_arc);
if (Opts.ObjCWeakRuntime)
- GenerateArg(Args, OPT_fobjc_runtime_has_weak, SA);
+ GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
if (Opts.ObjCWeak)
- GenerateArg(Args, OPT_fobjc_weak, SA);
+ GenerateArg(Consumer, OPT_fobjc_weak);
if (Opts.ObjCSubscriptingLegacyRuntime)
- GenerateArg(Args, OPT_fobjc_subscripting_legacy_runtime, SA);
+ GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
}
if (Opts.GNUCVersion != 0) {
unsigned Major = Opts.GNUCVersion / 100 / 100;
unsigned Minor = (Opts.GNUCVersion / 100) % 100;
unsigned Patch = Opts.GNUCVersion % 100;
- GenerateArg(Args, OPT_fgnuc_version_EQ,
- Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch), SA);
+ GenerateArg(Consumer, OPT_fgnuc_version_EQ,
+ Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
}
if (Opts.IgnoreXCOFFVisibility)
- GenerateArg(Args, OPT_mignore_xcoff_visibility, SA);
+ GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
- GenerateArg(Args, OPT_ftrapv, SA);
- GenerateArg(Args, OPT_ftrapv_handler, Opts.OverflowHandler, SA);
+ GenerateArg(Consumer, OPT_ftrapv);
+ GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
} else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
- GenerateArg(Args, OPT_fwrapv, SA);
+ GenerateArg(Consumer, OPT_fwrapv);
}
if (Opts.MSCompatibilityVersion != 0) {
unsigned Major = Opts.MSCompatibilityVersion / 10000000;
unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
- GenerateArg(Args, OPT_fms_compatibility_version,
- Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor), SA);
+ GenerateArg(Consumer, OPT_fms_compatibility_version,
+ Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
}
if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17) || T.isOSzOS()) {
if (!Opts.Trigraphs)
- GenerateArg(Args, OPT_fno_trigraphs, SA);
+ GenerateArg(Consumer, OPT_fno_trigraphs);
} else {
if (Opts.Trigraphs)
- GenerateArg(Args, OPT_ftrigraphs, SA);
+ GenerateArg(Consumer, OPT_ftrigraphs);
}
if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
- GenerateArg(Args, OPT_fblocks, SA);
+ GenerateArg(Consumer, OPT_fblocks);
if (Opts.ConvergentFunctions &&
!(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice))
- GenerateArg(Args, OPT_fconvergent_functions, SA);
+ GenerateArg(Consumer, OPT_fconvergent_functions);
if (Opts.NoBuiltin && !Opts.Freestanding)
- GenerateArg(Args, OPT_fno_builtin, SA);
+ GenerateArg(Consumer, OPT_fno_builtin);
if (!Opts.NoBuiltin)
for (const auto &Func : Opts.NoBuiltinFuncs)
- GenerateArg(Args, OPT_fno_builtin_, Func, SA);
+ GenerateArg(Consumer, OPT_fno_builtin_, Func);
if (Opts.LongDoubleSize == 128)
- GenerateArg(Args, OPT_mlong_double_128, SA);
+ GenerateArg(Consumer, OPT_mlong_double_128);
else if (Opts.LongDoubleSize == 64)
- GenerateArg(Args, OPT_mlong_double_64, SA);
+ GenerateArg(Consumer, OPT_mlong_double_64);
else if (Opts.LongDoubleSize == 80)
- GenerateArg(Args, OPT_mlong_double_80, SA);
+ GenerateArg(Consumer, OPT_mlong_double_80);
// Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
// OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
// '-fopenmp-targets='.
if (Opts.OpenMP && !Opts.OpenMPSimd) {
- GenerateArg(Args, OPT_fopenmp, SA);
+ GenerateArg(Consumer, OPT_fopenmp);
if (Opts.OpenMP != 51)
- GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA);
+ GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
if (!Opts.OpenMPUseTLS)
- GenerateArg(Args, OPT_fnoopenmp_use_tls, SA);
+ GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
if (Opts.OpenMPIsTargetDevice)
- GenerateArg(Args, OPT_fopenmp_is_target_device, SA);
+ GenerateArg(Consumer, OPT_fopenmp_is_target_device);
if (Opts.OpenMPIRBuilder)
- GenerateArg(Args, OPT_fopenmp_enable_irbuilder, SA);
+ GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
}
if (Opts.OpenMPSimd) {
- GenerateArg(Args, OPT_fopenmp_simd, SA);
+ GenerateArg(Consumer, OPT_fopenmp_simd);
if (Opts.OpenMP != 51)
- GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA);
+ GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
}
if (Opts.OpenMPThreadSubscription)
- GenerateArg(Args, OPT_fopenmp_assume_threads_oversubscription, SA);
+ GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
if (Opts.OpenMPTeamSubscription)
- GenerateArg(Args, OPT_fopenmp_assume_teams_oversubscription, SA);
+ GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
if (Opts.OpenMPTargetDebug != 0)
- GenerateArg(Args, OPT_fopenmp_target_debug_EQ,
- Twine(Opts.OpenMPTargetDebug), SA);
+ GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
+ Twine(Opts.OpenMPTargetDebug));
if (Opts.OpenMPCUDANumSMs != 0)
- GenerateArg(Args, OPT_fopenmp_cuda_number_of_sm_EQ,
- Twine(Opts.OpenMPCUDANumSMs), SA);
+ GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
+ Twine(Opts.OpenMPCUDANumSMs));
if (Opts.OpenMPCUDABlocksPerSM != 0)
- GenerateArg(Args, OPT_fopenmp_cuda_blocks_per_sm_EQ,
- Twine(Opts.OpenMPCUDABlocksPerSM), SA);
+ GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
+ Twine(Opts.OpenMPCUDABlocksPerSM));
if (Opts.OpenMPCUDAReductionBufNum != 1024)
- GenerateArg(Args, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
- Twine(Opts.OpenMPCUDAReductionBufNum), SA);
+ GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
+ Twine(Opts.OpenMPCUDAReductionBufNum));
if (!Opts.OMPTargetTriples.empty()) {
std::string Targets;
@@ -3445,83 +3564,106 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
llvm::interleave(
Opts.OMPTargetTriples, OS,
[&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
- GenerateArg(Args, OPT_fopenmp_targets_EQ, OS.str(), SA);
+ GenerateArg(Consumer, OPT_fopenmp_targets_EQ, OS.str());
}
if (!Opts.OMPHostIRFile.empty())
- GenerateArg(Args, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile, SA);
+ GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile);
if (Opts.OpenMPCUDAMode)
- GenerateArg(Args, OPT_fopenmp_cuda_mode, SA);
+ GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
+
+ if (Opts.OpenACC) {
+ GenerateArg(Consumer, OPT_fopenacc);
+ if (!Opts.OpenACCMacroOverride.empty())
+ GenerateArg(Consumer, OPT_openacc_macro_override,
+ Opts.OpenACCMacroOverride);
+ }
// The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
// generated from CodeGenOptions.
if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
- GenerateArg(Args, OPT_ffp_contract, "fast", SA);
+ GenerateArg(Consumer, OPT_ffp_contract, "fast");
else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
- GenerateArg(Args, OPT_ffp_contract, "on", SA);
+ GenerateArg(Consumer, OPT_ffp_contract, "on");
else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
- GenerateArg(Args, OPT_ffp_contract, "off", SA);
+ GenerateArg(Consumer, OPT_ffp_contract, "off");
else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
- GenerateArg(Args, OPT_ffp_contract, "fast-honor-pragmas", SA);
+ GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
- GenerateArg(Args, OPT_fsanitize_EQ, Sanitizer, SA);
+ GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
// Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
for (const std::string &F : Opts.NoSanitizeFiles)
- GenerateArg(Args, OPT_fsanitize_ignorelist_EQ, F, SA);
-
- if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver3_8)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "3.8", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver4)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "4.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver6)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "6.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver7)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "7.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver9)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "9.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver11)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "11.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver12)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver14)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "14.0", SA);
- else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver15)
- GenerateArg(Args, OPT_fclang_abi_compat_EQ, "15.0", SA);
+ GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
+
+ switch (Opts.getClangABICompat()) {
+ case LangOptions::ClangABI::Ver3_8:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");
+ break;
+ case LangOptions::ClangABI::Ver4:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");
+ break;
+ case LangOptions::ClangABI::Ver6:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");
+ break;
+ case LangOptions::ClangABI::Ver7:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");
+ break;
+ case LangOptions::ClangABI::Ver9:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");
+ break;
+ case LangOptions::ClangABI::Ver11:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");
+ break;
+ case LangOptions::ClangABI::Ver12:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");
+ break;
+ case LangOptions::ClangABI::Ver14:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");
+ break;
+ case LangOptions::ClangABI::Ver15:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");
+ break;
+ case LangOptions::ClangABI::Ver17:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
+ break;
+ case LangOptions::ClangABI::Latest:
+ break;
+ }
if (Opts.getSignReturnAddressScope() ==
LangOptions::SignReturnAddressScopeKind::All)
- GenerateArg(Args, OPT_msign_return_address_EQ, "all", SA);
+ GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
else if (Opts.getSignReturnAddressScope() ==
LangOptions::SignReturnAddressScopeKind::NonLeaf)
- GenerateArg(Args, OPT_msign_return_address_EQ, "non-leaf", SA);
+ GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
if (Opts.getSignReturnAddressKey() ==
LangOptions::SignReturnAddressKeyKind::BKey)
- GenerateArg(Args, OPT_msign_return_address_key_EQ, "b_key", SA);
+ GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
if (Opts.CXXABI)
- GenerateArg(Args, OPT_fcxx_abi_EQ, TargetCXXABI::getSpelling(*Opts.CXXABI),
- SA);
+ GenerateArg(Consumer, OPT_fcxx_abi_EQ,
+ TargetCXXABI::getSpelling(*Opts.CXXABI));
if (Opts.RelativeCXXABIVTables)
- GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA);
+ GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
else
- GenerateArg(Args, OPT_fno_experimental_relative_cxx_abi_vtables, SA);
+ GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
if (Opts.UseTargetPathSeparator)
- GenerateArg(Args, OPT_ffile_reproducible, SA);
+ GenerateArg(Consumer, OPT_ffile_reproducible);
else
- GenerateArg(Args, OPT_fno_file_reproducible, SA);
+ GenerateArg(Consumer, OPT_fno_file_reproducible);
for (const auto &MP : Opts.MacroPrefixMap)
- GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA);
+ GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
if (!Opts.RandstructSeed.empty())
- GenerateArg(Args, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed, SA);
+ GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
}
bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -3772,11 +3914,17 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << "-fdefault-calling-conv";
else {
- if (T.getArch() != llvm::Triple::x86)
+ switch (T.getArch()) {
+ case llvm::Triple::x86:
+ Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
+ break;
+ case llvm::Triple::m68k:
+ Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
+ break;
+ default:
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << T.getTriple();
- else
- Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
+ }
}
}
@@ -3901,6 +4049,14 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
(T.isNVPTX() || T.isAMDGCN()) &&
Args.hasArg(options::OPT_fopenmp_cuda_mode);
+ // OpenACC Configuration.
+ if (Args.hasArg(options::OPT_fopenacc)) {
+ Opts.OpenACC = true;
+
+ if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
+ Opts.OpenACCMacroOverride = A->getValue();
+ }
+
// FIXME: Eliminate this dependency.
unsigned Opt = getOptimizationLevel(Args, IK, Diags),
OptSize = getOptimizationLevelSize(Args);
@@ -3950,13 +4106,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
// Check the version number is valid: either 3.x (0 <= x <= 9) or
// y or y.0 (4 <= y <= current version).
- if (!VerParts.first.startswith("0") &&
- !VerParts.first.getAsInteger(10, Major) &&
- 3 <= Major && Major <= CLANG_VERSION_MAJOR &&
- (Major == 3 ? VerParts.second.size() == 1 &&
- !VerParts.second.getAsInteger(10, Minor)
- : VerParts.first.size() == Ver.size() ||
- VerParts.second == "0")) {
+ if (!VerParts.first.starts_with("0") &&
+ !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
+ Major <= CLANG_VERSION_MAJOR &&
+ (Major == 3
+ ? VerParts.second.size() == 1 &&
+ !VerParts.second.getAsInteger(10, Minor)
+ : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
// Got a valid version number.
if (Major == 3 && Minor <= 8)
Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
@@ -3976,6 +4132,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
else if (Major <= 15)
Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
+ else if (Major <= 17)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
@@ -4001,10 +4159,10 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
StringRef SignKey = A->getValue();
if (!SignScope.empty() && !SignKey.empty()) {
- if (SignKey.equals_insensitive("a_key"))
+ if (SignKey == "a_key")
Opts.setSignReturnAddressKey(
LangOptions::SignReturnAddressKeyKind::AKey);
- else if (SignKey.equals_insensitive("b_key"))
+ else if (SignKey == "b_key")
Opts.setSignReturnAddressKey(
LangOptions::SignReturnAddressKeyKind::BKey);
else
@@ -4033,6 +4191,14 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
options::OPT_fno_experimental_relative_cxx_abi_vtables,
TargetCXXABI::usesRelativeVTables(T));
+ // RTTI is on by default.
+ bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
+ Opts.OmitVTableRTTI =
+ Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
+ options::OPT_fno_experimental_omit_vtable_rtti, false);
+ if (Opts.OmitVTableRTTI && HasRTTI)
+ Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
+
for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
auto Split = StringRef(A).split('=');
Opts.MacroPrefixMap.insert(
@@ -4067,9 +4233,24 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
// Validate options for HLSL
if (Opts.HLSL) {
- bool SupportedTarget = T.getArch() == llvm::Triple::dxil &&
- T.getOS() == llvm::Triple::ShaderModel;
- if (!SupportedTarget)
+ // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
+ // handle PhysicalStorageBuffer64 memory model
+ if (T.isDXIL() || T.isSPIRVLogical()) {
+ enum { ShaderModel, ShaderStage };
+ if (T.getOSName().empty()) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
+ << ShaderModel << T.str();
+ } else if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
+ << ShaderModel << T.getOSName() << T.str();
+ } else if (T.getEnvironmentName().empty()) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
+ << ShaderStage << T.str();
+ } else if (!T.isShaderStageEnvironment()) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
+ << ShaderStage << T.getEnvironmentName() << T.str();
+ }
+ } else
Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
}
@@ -4121,30 +4302,28 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
llvm_unreachable("invalid frontend action");
}
-static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA,
+static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts,
+ ArgumentConsumer Consumer,
const LangOptions &LangOpts,
const FrontendOptions &FrontendOpts,
const CodeGenOptions &CodeGenOpts) {
- PreprocessorOptions *PreprocessorOpts = &Opts;
+ const PreprocessorOptions *PreprocessorOpts = &Opts;
#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
- GenerateArg(Args, OPT_pch_through_hdrstop_use, SA);
+ GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
- GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA);
+ GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
- GenerateArg(Args, OPT_preamble_bytes_EQ,
+ GenerateArg(Consumer, OPT_preamble_bytes_EQ,
Twine(Opts.PrecompiledPreambleBytes.first) + "," +
- (Opts.PrecompiledPreambleBytes.second ? "1" : "0"),
- SA);
+ (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
for (const auto &M : Opts.Macros) {
// Don't generate __CET__ macro definitions. They are implied by the
@@ -4159,7 +4338,7 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
CodeGenOpts.CFProtectionBranch)
continue;
- GenerateArg(Args, M.second ? OPT_U : OPT_D, M.first, SA);
+ GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
}
for (const auto &I : Opts.Includes) {
@@ -4174,17 +4353,20 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
if (LangOpts.HLSL && I == "hlsl.h")
continue;
- GenerateArg(Args, OPT_include, I, SA);
+ GenerateArg(Consumer, OPT_include, I);
}
for (const auto &CI : Opts.ChainedIncludes)
- GenerateArg(Args, OPT_chain_include, CI, SA);
+ GenerateArg(Consumer, OPT_chain_include, CI);
for (const auto &RF : Opts.RemappedFiles)
- GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA);
+ GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
if (Opts.SourceDateEpoch)
- GenerateArg(Args, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch), SA);
+ GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
+
+ if (Opts.DefineTargetOSMacros)
+ GenerateArg(Consumer, OPT_fdefine_target_os_macros);
// Don't handle LexEditorPlaceholders. It is implied by the action that is
// generated elsewhere.
@@ -4284,26 +4466,31 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
if (isStrictlyPreprocessorAction(Action))
Opts.LexEditorPlaceholders = false;
+ Opts.DefineTargetOSMacros =
+ Args.hasFlag(OPT_fdefine_target_os_macros,
+ OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
+
return Diags.getNumErrors() == NumErrorsBefore;
}
-static void GeneratePreprocessorOutputArgs(
- const PreprocessorOutputOptions &Opts, SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA, frontend::ActionKind Action) {
+static void
+GeneratePreprocessorOutputArgs(const PreprocessorOutputOptions &Opts,
+ ArgumentConsumer Consumer,
+ frontend::ActionKind Action) {
const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
if (Generate_dM)
- GenerateArg(Args, OPT_dM, SA);
+ GenerateArg(Consumer, OPT_dM);
if (!Generate_dM && Opts.ShowMacros)
- GenerateArg(Args, OPT_dD, SA);
+ GenerateArg(Consumer, OPT_dD);
if (Opts.DirectivesOnly)
- GenerateArg(Args, OPT_fdirectives_only, SA);
+ GenerateArg(Consumer, OPT_fdirectives_only);
}
static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
@@ -4326,20 +4513,19 @@ static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
}
static void GenerateTargetArgs(const TargetOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- CompilerInvocation::StringAllocator SA) {
+ ArgumentConsumer Consumer) {
const TargetOptions *TargetOpts = &Opts;
#define TARGET_OPTION_WITH_MARSHALLING(...) \
- GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__)
+ GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
#include "clang/Driver/Options.inc"
#undef TARGET_OPTION_WITH_MARSHALLING
if (!Opts.SDKVersion.empty())
- GenerateArg(Args, OPT_target_sdk_version_EQ, Opts.SDKVersion.getAsString(),
- SA);
+ GenerateArg(Consumer, OPT_target_sdk_version_EQ,
+ Opts.SDKVersion.getAsString());
if (!Opts.DarwinTargetVariantSDKVersion.empty())
- GenerateArg(Args, OPT_darwin_target_variant_sdk_version_EQ,
- Opts.DarwinTargetVariantSDKVersion.getAsString(), SA);
+ GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
+ Opts.DarwinTargetVariantSDKVersion.getAsString());
}
static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
@@ -4381,11 +4567,11 @@ bool CompilerInvocation::CreateFromArgsImpl(
// Parse the arguments.
const OptTable &Opts = getDriverOptTable();
- const unsigned IncludedFlagsBitmask = options::CC1Option;
+ llvm::opt::Visibility VisibilityMask(options::CC1Option);
unsigned MissingArgIndex, MissingArgCount;
InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
- MissingArgCount, IncludedFlagsBitmask);
- LangOptions &LangOpts = *Res.getLangOpts();
+ MissingArgCount, VisibilityMask);
+ LangOptions &LangOpts = Res.getLangOpts();
// Check for missing argument error.
if (MissingArgCount)
@@ -4396,7 +4582,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
auto ArgString = A->getAsString(Args);
std::string Nearest;
- if (Opts.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
+ if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
Diags.Report(diag::err_drv_unknown_argument) << ArgString;
else
Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
@@ -4405,7 +4591,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
- ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags);
+ ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
/*DefaultDiagColor=*/false);
ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
@@ -4415,6 +4601,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
llvm::Triple T(Res.getTargetOpts().Triple);
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
Res.getFileSystemOpts().WorkingDir);
+ ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
Diags);
@@ -4466,7 +4653,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
// If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
- !Res.getLangOpts()->Sanitize.empty()) {
+ !Res.getLangOpts().Sanitize.empty()) {
Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
}
@@ -4514,7 +4701,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Invocation,
std::string CompilerInvocation::getModuleHash() const {
// FIXME: Consider using SHA1 instead of MD5.
- llvm::HashBuilder<llvm::MD5, llvm::support::endianness::native> HBuilder;
+ llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
// Note: For QoI reasons, the things we use as a hash here should all be
// dumped via the -module-info flag.
@@ -4534,15 +4721,15 @@ std::string CompilerInvocation::getModuleHash() const {
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
#include "clang/Basic/LangOptions.def"
- HBuilder.addRange(LangOpts->ModuleFeatures);
+ HBuilder.addRange(getLangOpts().ModuleFeatures);
- HBuilder.add(LangOpts->ObjCRuntime);
- HBuilder.addRange(LangOpts->CommentOpts.BlockCommandNames);
+ HBuilder.add(getLangOpts().ObjCRuntime);
+ HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
// Extend the signature with the target options.
- HBuilder.add(TargetOpts->Triple, TargetOpts->CPU, TargetOpts->TuneCPU,
- TargetOpts->ABI);
- HBuilder.addRange(TargetOpts->FeaturesAsWritten);
+ HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
+ getTargetOpts().TuneCPU, getTargetOpts().ABI);
+ HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
// Extend the signature with preprocessor options.
const PreprocessorOptions &ppOpts = getPreprocessorOpts();
@@ -4590,14 +4777,38 @@ std::string CompilerInvocation::getModuleHash() const {
for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
ext->hashExtension(HBuilder);
+ // Extend the signature with the Swift version for API notes.
+ const APINotesOptions &APINotesOpts = getAPINotesOpts();
+ if (!APINotesOpts.SwiftVersion.empty()) {
+ HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
+ if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
+ HBuilder.add(*Minor);
+ if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
+ HBuilder.add(*Subminor);
+ if (auto Build = APINotesOpts.SwiftVersion.getBuild())
+ HBuilder.add(*Build);
+ }
+
// When compiling with -gmodules, also hash -fdebug-prefix-map as it
// affects the debug info in the PCM.
if (getCodeGenOpts().DebugTypeExtRefs)
HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
+ // Extend the signature with the affecting debug options.
+ if (getHeaderSearchOpts().ModuleFormat == "obj") {
+#define DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
+#define VALUE_DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default) \
+ HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
+#define BENIGN_DEBUGOPT(Name, Bits, Default)
+#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)
+#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)
+#include "clang/Basic/DebugOptions.def"
+ }
+
// Extend the signature with the enabled sanitizers, if at least one is
// enabled. Sanitizers which cannot affect AST generation aren't hashed.
- SanitizerSet SanHash = LangOpts->Sanitize;
+ SanitizerSet SanHash = getLangOpts().Sanitize;
SanHash.clear(getPPTransparentSanitizers());
if (!SanHash.empty())
HBuilder.add(SanHash.Mask);
@@ -4608,48 +4819,44 @@ std::string CompilerInvocation::getModuleHash() const {
return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
}
-void CompilerInvocation::generateCC1CommandLine(
- SmallVectorImpl<const char *> &Args, StringAllocator SA) const {
- llvm::Triple T(TargetOpts->Triple);
-
- GenerateFileSystemArgs(FileSystemOpts, Args, SA);
- GenerateMigratorArgs(MigratorOpts, Args, SA);
- GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA);
- GenerateDiagnosticArgs(*DiagnosticOpts, Args, SA, false);
- GenerateFrontendArgs(FrontendOpts, Args, SA, LangOpts->IsHeaderFile);
- GenerateTargetArgs(*TargetOpts, Args, SA);
- GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA);
- GenerateLangArgs(*LangOpts, Args, SA, T, FrontendOpts.DashX);
- GenerateCodeGenArgs(CodeGenOpts, Args, SA, T, FrontendOpts.OutputFile,
- &*LangOpts);
- GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts, FrontendOpts,
- CodeGenOpts);
- GeneratePreprocessorOutputArgs(PreprocessorOutputOpts, Args, SA,
- FrontendOpts.ProgramAction);
- GenerateDependencyOutputArgs(DependencyOutputOpts, Args, SA);
+void CompilerInvocationBase::generateCC1CommandLine(
+ ArgumentConsumer Consumer) const {
+ llvm::Triple T(getTargetOpts().Triple);
+
+ GenerateFileSystemArgs(getFileSystemOpts(), Consumer);
+ GenerateMigratorArgs(getMigratorOpts(), Consumer);
+ GenerateAnalyzerArgs(getAnalyzerOpts(), Consumer);
+ GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
+ /*DefaultDiagColor=*/false);
+ GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
+ GenerateTargetArgs(getTargetOpts(), Consumer);
+ GenerateHeaderSearchArgs(getHeaderSearchOpts(), Consumer);
+ GenerateAPINotesArgs(getAPINotesOpts(), Consumer);
+ GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
+ GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
+ getFrontendOpts().OutputFile, &getLangOpts());
+ GeneratePreprocessorArgs(getPreprocessorOpts(), Consumer, getLangOpts(),
+ getFrontendOpts(), getCodeGenOpts());
+ GeneratePreprocessorOutputArgs(getPreprocessorOutputOpts(), Consumer,
+ getFrontendOpts().ProgramAction);
+ GenerateDependencyOutputArgs(getDependencyOutputOpts(), Consumer);
}
-std::vector<std::string> CompilerInvocation::getCC1CommandLine() const {
- // Set up string allocator.
- llvm::BumpPtrAllocator Alloc;
- llvm::StringSaver Strings(Alloc);
- auto SA = [&Strings](const Twine &Arg) { return Strings.save(Arg).data(); };
-
- // Synthesize full command line from the CompilerInvocation, including "-cc1".
- SmallVector<const char *, 32> Args{"-cc1"};
- generateCC1CommandLine(Args, SA);
-
- // Convert arguments to the return type.
- return std::vector<std::string>{Args.begin(), Args.end()};
+std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
+ std::vector<std::string> Args{"-cc1"};
+ generateCC1CommandLine(
+ [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
+ return Args;
}
void CompilerInvocation::resetNonModularOptions() {
- getLangOpts()->resetNonModularOptions();
+ getLangOpts().resetNonModularOptions();
getPreprocessorOpts().resetNonModularOptions();
+ getCodeGenOpts().resetNonModularOptions(getHeaderSearchOpts().ModuleFormat);
}
void CompilerInvocation::clearImplicitModuleBuildOptions() {
- getLangOpts()->ImplicitModules = false;
+ getLangOpts().ImplicitModules = false;
getHeaderSearchOpts().ImplicitModuleMaps = false;
getHeaderSearchOpts().ModuleCachePath.clear();
getHeaderSearchOpts().ModulesValidateOncePerBuildSession = false;