aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorJan Svoboda <jan_svoboda@apple.com>2025-07-15 12:45:09 -0700
committerGitHub <noreply@github.com>2025-07-15 12:45:09 -0700
commitc592b61fc82c79366216ae12b25b0130359b0a26 (patch)
tree66b671ae5fdaaf321a94a9378b1af3b957586060 /clang/lib
parentfccae859bc949ba390184614e07234267a734b86 (diff)
downloadllvm-c592b61fc82c79366216ae12b25b0130359b0a26.zip
llvm-c592b61fc82c79366216ae12b25b0130359b0a26.tar.gz
llvm-c592b61fc82c79366216ae12b25b0130359b0a26.tar.bz2
[clang][modules] Serialize `CodeGenOptions` (#146422)
Some `LangOptions` duplicate their `CodeGenOptions` counterparts. My understanding is that this was done solely because some infrastructure (like preprocessor initialization, serialization, module compatibility checks, etc.) were only possible/convenient for `LangOptions`. This PR implements the missing support for `CodeGenOptions`, which makes it possible to remove some duplicate `LangOptions` fields and simplify the logic. Motivated by https://github.com/llvm/llvm-project/pull/146342.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/CodeGenOptions.cpp6
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp39
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp2
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp36
-rw-r--r--clang/lib/Frontend/ChainedIncludesSource.cpp5
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp8
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp37
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp5
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp17
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp12
-rw-r--r--clang/lib/Frontend/PrecompiledPreamble.cpp8
-rw-r--r--clang/lib/Serialization/ASTReader.cpp130
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp21
-rw-r--r--clang/lib/Serialization/GeneratePCH.cpp6
15 files changed, 252 insertions, 84 deletions
diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp
index 9a2aa9b..db8a77c 100644
--- a/clang/lib/Basic/CodeGenOptions.cpp
+++ b/clang/lib/Basic/CodeGenOptions.cpp
@@ -36,13 +36,13 @@ void CodeGenOptions::resetNonModularOptions(StringRef ModuleFormat) {
// emitted into the PCM (-gmodules).
if (ModuleFormat == "raw" && !DebugTypeExtRefs) {
#define DEBUGOPT(Name, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
Name = Default;
#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
Name = Default;
#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
set##Name(Default);
#include "clang/Basic/DebugOptions.def"
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index f97c7b6..b985db7 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -799,7 +799,8 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",
- LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
+ CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
+ CGOpts.PrepareForThinLTO,
CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
NameTableKind, CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK);
@@ -2284,7 +2285,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
Flags |= llvm::DINode::FlagRValueReference;
if (!Method->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
// In this debug mode, emit type info for a class when its constructor type
@@ -4355,7 +4356,7 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
if (!FD->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
if (Stub) {
@@ -4685,7 +4686,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (Fn->hasLocalLinkage())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
@@ -4768,7 +4769,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
unsigned LineNo = getLineNumber(Loc);
unsigned ScopeLine = 0;
llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
@@ -5100,7 +5101,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
// Use VarDecl's Tag, Scope and Line number.
auto FieldAlign = getDeclAlignIfRequired(Field, CGM.getContext());
auto *D = DBuilder.createAutoVariable(
- Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
+ Scope, FieldName, Unit, Line, FieldTy,
+ CGM.getCodeGenOpts().OptimizationLevel != 0,
Flags | llvm::DINode::FlagArtificial, FieldAlign);
// Insert an llvm.dbg.declare into the current block.
@@ -5126,9 +5128,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
llvm::DILocalVariable *D = nullptr;
if (ArgNo) {
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
- D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags,
- Annotations);
+ D = DBuilder.createParameterVariable(
+ Scope, Name, *ArgNo, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
} else {
// For normal local variable, we will try to find out whether 'VD' is the
// copy parameter of coroutine.
@@ -5169,8 +5171,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
D = RemapCoroArgToLocalVar();
// Or we will create a new DIVariable for this Decl if D dose not exists.
if (!D)
- D = DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags, Align);
+ D = DBuilder.createAutoVariable(
+ Scope, Name, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
}
// Insert an llvm.dbg.declare into the current block.
DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
@@ -5224,7 +5227,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
// Create the descriptor for the variable.
llvm::DILocalVariable *D = DBuilder.createAutoVariable(
- Scope, Name, Unit, Line, Ty, CGM.getLangOpts().Optimize,
+ Scope, Name, Unit, Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
llvm::DINode::FlagZero, Align);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
@@ -5322,9 +5325,10 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
StringRef Name = D->getName();
// Create the descriptor for the label.
- auto *L = DBuilder.createLabel(
- Scope, Name, Unit, Line, Column, /*IsArtificial=*/false,
- /*CoroSuspendIdx=*/std::nullopt, CGM.getLangOpts().Optimize);
+ auto *L = DBuilder.createLabel(Scope, Name, Unit, Line, Column,
+ /*IsArtificial=*/false,
+ /*CoroSuspendIdx=*/std::nullopt,
+ CGM.getCodeGenOpts().OptimizationLevel != 0);
// Insert an llvm.dbg.label into the current block.
DBuilder.insertLabel(L,
@@ -5587,7 +5591,8 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
// Create the descriptor for the parameter.
auto *debugVar = DBuilder.createParameterVariable(
- scope, Name, ArgNo, tunit, line, type, CGM.getLangOpts().Optimize, flags);
+ scope, Name, ArgNo, tunit, line, type,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, flags);
// Insert an llvm.dbg.declare into the current block.
DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
@@ -6362,7 +6367,7 @@ llvm::DebugLoc CGDebugInfo::SourceLocToDebugLoc(SourceLocation Loc) {
llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const {
// Call site-related attributes are only useful in optimized programs, and
// when there's a possibility of debugging backtraces.
- if (!CGM.getLangOpts().Optimize ||
+ if (CGM.getCodeGenOpts().OptimizationLevel == 0 ||
DebugKind == llvm::codegenoptions::NoDebugInfo ||
DebugKind == llvm::codegenoptions::LocTrackingOnly)
return llvm::DINode::FlagZero;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index a5f2f0e..ce2dd4d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1092,7 +1092,7 @@ emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Name, &CGM.getModule());
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
- if (CGM.getLangOpts().Optimize) {
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0) {
Fn->removeFnAttr(llvm::Attribute::NoInline);
Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
Fn->addFnAttr(llvm::Attribute::AlwaysInline);
@@ -3199,7 +3199,7 @@ emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
&CGM.getModule());
CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap,
TaskPrivatesMapFnInfo);
- if (CGM.getLangOpts().Optimize) {
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0) {
TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 5493cc9..eb5b604 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -995,7 +995,7 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
std::vector<std::unique_ptr<ASTConsumer>> Consumers(2);
Consumers[0] = std::make_unique<ReducedBMIGenerator>(
CI.getPreprocessor(), CI.getModuleCache(),
- CI.getFrontendOpts().ModuleOutputPath);
+ CI.getFrontendOpts().ModuleOutputPath, CI.getCodeGenOpts());
Consumers[1] = std::move(Result);
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
}
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index b7f52fd..67ed17b 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -215,8 +215,8 @@ struct ASTUnit::ASTWriterData {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
- ASTWriterData(ModuleCache &ModCache)
- : Stream(Buffer), Writer(Stream, Buffer, ModCache, {}) {}
+ ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
+ : Stream(Buffer), Writer(Stream, Buffer, ModCache, CGOpts, {}) {}
};
void ASTUnit::clearFileLevelDecls() {
@@ -235,7 +235,8 @@ const unsigned DefaultPreambleRebuildInterval = 5;
static std::atomic<unsigned> ActiveASTUnitObjects;
ASTUnit::ASTUnit(bool _MainFileIsAST)
- : MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
+ : CodeGenOpts(std::make_unique<CodeGenOptions>()),
+ MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
ShouldCacheCodeCompletionResults(false),
IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
UnsafeToFree(false) {
@@ -516,6 +517,7 @@ class ASTInfoCollector : public ASTReaderListener {
HeaderSearchOptions &HSOpts;
PreprocessorOptions &PPOpts;
LangOptions &LangOpt;
+ CodeGenOptions &CodeGenOpts;
std::shared_ptr<TargetOptions> &TargetOpts;
IntrusiveRefCntPtr<TargetInfo> &Target;
unsigned &Counter;
@@ -525,12 +527,12 @@ class ASTInfoCollector : public ASTReaderListener {
public:
ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
- LangOptions &LangOpt,
+ LangOptions &LangOpt, CodeGenOptions &CodeGenOpts,
std::shared_ptr<TargetOptions> &TargetOpts,
IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
: PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
- LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target),
- Counter(Counter) {}
+ LangOpt(LangOpt), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts),
+ Target(Target), Counter(Counter) {}
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
@@ -555,6 +557,13 @@ public:
return false;
}
+ bool ReadCodeGenOptions(const CodeGenOptions &CGOpts,
+ StringRef ModuleFilename, bool Complain,
+ bool AllowCompatibleDifferences) override {
+ this->CodeGenOpts = CGOpts;
+ return false;
+ }
+
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef ModuleFilename,
StringRef SpecificModuleCachePath,
@@ -858,14 +867,16 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
DisableValidationForModuleKind::None;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = DisableValidationForModuleKind::All;
- AST->Reader = new ASTReader(
- PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"",
- /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors);
+ AST->Reader = new ASTReader(PP, *AST->ModCache, AST->Ctx.get(),
+ PCHContainerRdr, *AST->CodeGenOpts, {},
+ /*isysroot=*/"",
+ /*DisableValidationKind=*/disableValid,
+ AllowASTWithCompilerErrors);
unsigned Counter = 0;
AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
*AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
- AST->TargetOpts, AST->Target, Counter));
+ *AST->CodeGenOpts, AST->TargetOpts, AST->Target, Counter));
// Attach the AST reader to the AST context as an external AST
// source, so that declarations will be deserialized from the
@@ -1836,6 +1847,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
AST->DiagOpts = DiagOpts;
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
+ AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
AST->StorePreamblesInMemory = StorePreamblesInMemory;
@@ -1851,7 +1863,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
AST->Invocation = CI;
AST->SkipFunctionBodies = SkipFunctionBodies;
if (ForSerialization)
- AST->WriterData.reset(new ASTWriterData(*AST->ModCache));
+ AST->WriterData.reset(new ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
// Zero out now to ease cleanup during crash recovery.
CI = nullptr;
Diags = nullptr;
@@ -2385,7 +2397,7 @@ bool ASTUnit::serialize(raw_ostream &OS) {
SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
- ASTWriter Writer(Stream, Buffer, *ModCache, {});
+ ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
return serializeUnit(Writer, Buffer, getSema(), OS);
}
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index f9a398d..ba7c767 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -62,7 +62,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
std::unique_ptr<ASTReader> Reader;
Reader.reset(new ASTReader(
PP, CI.getModuleCache(), &CI.getASTContext(), CI.getPCHContainerReader(),
- /*Extensions=*/{},
+ CI.getCodeGenOpts(), /*Extensions=*/{},
/*isysroot=*/"", DisableValidationForModuleKind::PCH));
for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
StringRef sr(bufNames[ti]);
@@ -138,7 +138,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
auto consumer = std::make_unique<PCHGenerator>(
Clang->getPreprocessor(), Clang->getModuleCache(), "-", /*isysroot=*/"",
- Buffer, Extensions, /*AllowASTWithErrors=*/true);
+ Buffer, Clang->getCodeGenOpts(), Extensions,
+ /*AllowASTWithErrors=*/true);
Clang->getASTContext().setASTMutationListener(
consumer->GetASTMutationListener());
Clang->setASTConsumer(std::move(consumer));
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 6f8cc01..c7b82db 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -614,7 +614,7 @@ void CompilerInstance::createPCHExternalASTSource(
TheASTReader = createPCHExternalASTSource(
Path, getHeaderSearchOpts().Sysroot, DisableValidation,
AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),
- getASTContext(), getPCHContainerReader(),
+ getASTContext(), getPCHContainerReader(), getCodeGenOpts(),
getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
DeserializationListener, OwnDeserializationListener, Preamble,
getFrontendOpts().UseGlobalModuleIndex);
@@ -625,6 +625,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
DisableValidationForModuleKind DisableValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
+ const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
void *DeserializationListener, bool OwnDeserializationListener,
@@ -633,7 +634,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
PP.getHeaderSearchInfo().getHeaderSearchOpts();
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
- PP, ModCache, &Context, PCHContainerRdr, Extensions,
+ PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
HSOpts.ModulesValidateSystemHeaders,
@@ -1746,7 +1747,8 @@ void CompilerInstance::createASTReader() {
"Reading modules", *timerGroup);
TheASTReader = new ASTReader(
getPreprocessor(), getModuleCache(), &getASTContext(),
- getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
+ getPCHContainerReader(), getCodeGenOpts(),
+ getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
PPOpts.DisablePCHOrModuleValidation,
/*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 08cf0ae..56d10ce 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4470,22 +4470,6 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.OpenACCMacroOverride = A->getValue();
}
- // FIXME: Eliminate this dependency.
- unsigned Opt = getOptimizationLevel(Args, IK, Diags),
- OptSize = getOptimizationLevelSize(Args);
- Opts.Optimize = Opt != 0;
- Opts.OptimizeSize = OptSize != 0;
-
- // This is the __NO_INLINE__ define, which just depends on things like the
- // optimization level and -fno-inline, not actually whether the backend has
- // inlining enabled.
- Opts.NoInlineDefine = !Opts.Optimize;
- if (Arg *InlineArg = Args.getLastArg(
- options::OPT_finline_functions, options::OPT_finline_hint_functions,
- options::OPT_fno_inline_functions, options::OPT_fno_inline))
- if (InlineArg->getOption().matches(options::OPT_fno_inline))
- Opts.NoInlineDefine = true;
-
if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
StringRef Val = A->getValue();
if (Val == "fast")
@@ -5335,6 +5319,21 @@ std::string CompilerInvocation::getModuleHash() const {
HBuilder.add(*Build);
}
+ // Extend the signature with affecting codegen options.
+ {
+ using CK = CodeGenOptions::CompatibilityKind;
+#define CODEGENOPT(Name, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ HBuilder.add(CodeGenOpts->Name);
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
+#define DEBUGOPT(Name, Bits, Default, Compatibility)
+#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
+#include "clang/Basic/CodeGenOptions.def"
+ }
+
// When compiling with -gmodules, also hash -fdebug-prefix-map as it
// affects the debug info in the PCM.
if (getCodeGenOpts().DebugTypeExtRefs)
@@ -5345,13 +5344,13 @@ std::string CompilerInvocation::getModuleHash() const {
// FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
using CK = CodeGenOptions::CompatibilityKind;
#define DEBUGOPT(Name, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
HBuilder.add(CodeGenOpts->Name);
#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
HBuilder.add(CodeGenOpts->Name);
#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility) \
- if constexpr (CK::Compatibility == CK::Affecting) \
+ if constexpr (CK::Compatibility != CK::Benign) \
HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
#include "clang/Basic/DebugOptions.def"
}
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index f5996a8..1d82fc7 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -947,8 +947,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (ASTReader::isAcceptableASTFile(
Dir->path(), FileMgr, CI.getModuleCache(),
CI.getPCHContainerReader(), CI.getLangOpts(),
- CI.getTargetOpts(), CI.getPreprocessorOpts(),
- SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
+ CI.getCodeGenOpts(), CI.getTargetOpts(),
+ CI.getPreprocessorOpts(), SpecificModuleCachePath,
+ /*RequireStrictOptionMatches=*/true)) {
PPOpts.ImplicitPCHInclude = std::string(Dir->path());
Found = true;
break;
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 89eb0b6..dcfbd53 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -139,7 +139,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(std::make_unique<PCHGenerator>(
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
- FrontendOpts.ModuleFileExtensions,
+ CI.getCodeGenOpts(), FrontendOpts.ModuleFileExtensions,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
FrontendOpts.IncludeTimestamps, FrontendOpts.BuildingImplicitModule,
+CI.getLangOpts().CacheGeneratedPCH));
@@ -199,7 +199,7 @@ GenerateModuleAction::CreateMultiplexConsumer(CompilerInstance &CI,
Consumers.push_back(std::make_unique<PCHGenerator>(
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
- CI.getFrontendOpts().ModuleFileExtensions,
+ CI.getCodeGenOpts(), CI.getFrontendOpts().ModuleFileExtensions,
/*AllowASTWithErrors=*/
+CI.getFrontendOpts().AllowPCMWithCompilerErrors,
/*IncludeTimestamps=*/
@@ -292,13 +292,13 @@ GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
!CI.getFrontendOpts().ModuleOutputPath.empty()) {
Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
CI.getPreprocessor(), CI.getModuleCache(),
- CI.getFrontendOpts().ModuleOutputPath,
+ CI.getFrontendOpts().ModuleOutputPath, CI.getCodeGenOpts(),
+CI.getFrontendOpts().AllowPCMWithCompilerErrors));
}
Consumers.push_back(std::make_unique<CXX20ModulesGenerator>(
CI.getPreprocessor(), CI.getModuleCache(),
- CI.getFrontendOpts().OutputFile,
+ CI.getFrontendOpts().OutputFile, CI.getCodeGenOpts(),
+CI.getFrontendOpts().AllowPCMWithCompilerErrors));
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
@@ -313,9 +313,9 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
std::unique_ptr<ASTConsumer>
GenerateReducedModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
- return std::make_unique<ReducedBMIGenerator>(CI.getPreprocessor(),
- CI.getModuleCache(),
- CI.getFrontendOpts().OutputFile);
+ return std::make_unique<ReducedBMIGenerator>(
+ CI.getPreprocessor(), CI.getModuleCache(),
+ CI.getFrontendOpts().OutputFile, CI.getCodeGenOpts());
}
bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
@@ -358,7 +358,8 @@ void VerifyPCHAction::ExecuteAction() {
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
std::unique_ptr<ASTReader> Reader(new ASTReader(
CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(),
- CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
+ CI.getPCHContainerReader(), CI.getCodeGenOpts(),
+ CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
DisableValidationForModuleKind::None,
/*AllowASTWithCompilerErrors*/ false,
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 34fb825..136bc55 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -862,6 +862,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
const LangOptions &LangOpts,
const FrontendOptions &FEOpts,
const PreprocessorOptions &PPOpts,
+ const CodeGenOptions &CGOpts,
MacroBuilder &Builder) {
// Compiler version introspection macros.
Builder.defineMacro("__llvm__"); // LLVM Backend
@@ -1070,9 +1071,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__clang_wide_literal_encoding__", "\"UTF-16\"");
}
- if (LangOpts.Optimize)
+ if (CGOpts.OptimizationLevel != 0)
Builder.defineMacro("__OPTIMIZE__");
- if (LangOpts.OptimizeSize)
+ if (CGOpts.OptimizeSize != 0)
Builder.defineMacro("__OPTIMIZE_SIZE__");
if (LangOpts.FastMath)
@@ -1393,7 +1394,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.GNUCVersion)
addLockFreeMacros("__GCC_ATOMIC_");
- if (LangOpts.NoInlineDefine)
+ if (CGOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
Builder.defineMacro("__NO_INLINE__");
if (unsigned PICLevel = LangOpts.PICLevel) {
@@ -1572,10 +1573,11 @@ void clang::InitializePreprocessor(Preprocessor &PP,
// macros. This is not the right way to handle this.
if ((LangOpts.CUDA || LangOpts.isTargetDevice()) && PP.getAuxTargetInfo())
InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
- PP.getPreprocessorOpts(), Builder);
+ PP.getPreprocessorOpts(), CodeGenOpts,
+ Builder);
InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts,
- PP.getPreprocessorOpts(), Builder);
+ PP.getPreprocessorOpts(), CodeGenOpts, Builder);
// Install definitions to make Objective-C++ ARC work well with various
// C++ Standard Library implementations.
diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp
index 3f3fe3c..146cf90 100644
--- a/clang/lib/Frontend/PrecompiledPreamble.cpp
+++ b/clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -293,8 +293,9 @@ class PrecompilePreambleConsumer : public PCHGenerator {
public:
PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
ModuleCache &ModCache, StringRef isysroot,
- std::shared_ptr<PCHBuffer> Buffer)
- : PCHGenerator(PP, ModCache, "", isysroot, std::move(Buffer),
+ std::shared_ptr<PCHBuffer> Buffer,
+ const CodeGenOptions &CodeGenOpts)
+ : PCHGenerator(PP, ModCache, "", isysroot, std::move(Buffer), CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
/*AllowASTWithErrors=*/true),
Action(Action) {}
@@ -337,7 +338,8 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
Sysroot.clear();
return std::make_unique<PrecompilePreambleConsumer>(
- *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, Buffer);
+ *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, Buffer,
+ CI.getCodeGenOpts());
}
template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 30e0973..d0bb7fb 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -175,6 +175,15 @@ bool ChainedASTReaderListener::ReadLanguageOptions(
AllowCompatibleDifferences);
}
+bool ChainedASTReaderListener::ReadCodeGenOptions(
+ const CodeGenOptions &CGOpts, StringRef ModuleFilename, bool Complain,
+ bool AllowCompatibleDifferences) {
+ return First->ReadCodeGenOptions(CGOpts, ModuleFilename, Complain,
+ AllowCompatibleDifferences) ||
+ Second->ReadCodeGenOptions(CGOpts, ModuleFilename, Complain,
+ AllowCompatibleDifferences);
+}
+
bool ChainedASTReaderListener::ReadTargetOptions(
const TargetOptions &TargetOpts, StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) {
@@ -383,6 +392,68 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
return false;
}
+static bool checkCodegenOptions(const CodeGenOptions &CGOpts,
+ const CodeGenOptions &ExistingCGOpts,
+ StringRef ModuleFilename,
+ DiagnosticsEngine *Diags,
+ bool AllowCompatibleDifferences = true) {
+ // FIXME: Specify and print a description for each option instead of the name.
+ // FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
+ using CK = CodeGenOptions::CompatibilityKind;
+#define CODEGENOPT(Name, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) { \
+ if ((CK::Compatibility == CK::NotCompatible) || \
+ (CK::Compatibility == CK::Compatible && \
+ !AllowCompatibleDifferences)) { \
+ if (ExistingCGOpts.Name != CGOpts.Name) { \
+ if (Diags) { \
+ if (Bits == 1) \
+ Diags->Report(diag::err_ast_file_codegenopt_mismatch) \
+ << #Name << CGOpts.Name << ExistingCGOpts.Name \
+ << ModuleFilename; \
+ else \
+ Diags->Report(diag::err_ast_file_codegenopt_value_mismatch) \
+ << #Name << ModuleFilename; \
+ } \
+ return true; \
+ } \
+ } \
+ }
+
+#define VALUE_CODEGENOPT(Name, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) { \
+ if ((CK::Compatibility == CK::NotCompatible) || \
+ (CK::Compatibility == CK::Compatible && \
+ !AllowCompatibleDifferences)) { \
+ if (ExistingCGOpts.Name != CGOpts.Name) { \
+ if (Diags) \
+ Diags->Report(diag::err_ast_file_codegenopt_value_mismatch) \
+ << #Name << ModuleFilename; \
+ return true; \
+ } \
+ } \
+ }
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) { \
+ if ((CK::Compatibility == CK::NotCompatible) || \
+ (CK::Compatibility == CK::Compatible && \
+ !AllowCompatibleDifferences)) { \
+ if (ExistingCGOpts.get##Name() != CGOpts.get##Name()) { \
+ if (Diags) \
+ Diags->Report(diag::err_ast_file_codegenopt_value_mismatch) \
+ << #Name << ModuleFilename; \
+ return true; \
+ } \
+ } \
+ }
+#define DEBUGOPT(Name, Bits, Default, Compatibility)
+#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
+#include "clang/Basic/CodeGenOptions.def"
+
+ return false;
+}
+
/// Compare the given set of target options against an existing set of
/// target options.
///
@@ -462,6 +533,15 @@ bool PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts,
AllowCompatibleDifferences);
}
+bool PCHValidator::ReadCodeGenOptions(const CodeGenOptions &CGOpts,
+ StringRef ModuleFilename, bool Complain,
+ bool AllowCompatibleDifferences) {
+ const CodeGenOptions &ExistingCGOpts = Reader.getCodeGenOpts();
+ return checkCodegenOptions(ExistingCGOpts, CGOpts, ModuleFilename,
+ Complain ? &Reader.Diags : nullptr,
+ AllowCompatibleDifferences);
+}
+
bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) {
@@ -2993,6 +3073,14 @@ ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
break;
}
+ case CODEGEN_OPTIONS: {
+ bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
+ if (ParseCodeGenOptions(Record, Filename, Complain, Listener,
+ AllowCompatibleConfigurationMismatch))
+ Result = ConfigurationMismatch;
+ break;
+ }
+
case TARGET_OPTIONS: {
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
if (ParseTargetOptions(Record, Filename, Complain, Listener,
@@ -5639,6 +5727,7 @@ namespace {
class SimplePCHValidator : public ASTReaderListener {
const LangOptions &ExistingLangOpts;
+ const CodeGenOptions &ExistingCGOpts;
const TargetOptions &ExistingTargetOpts;
const PreprocessorOptions &ExistingPPOpts;
std::string ExistingModuleCachePath;
@@ -5647,11 +5736,12 @@ namespace {
public:
SimplePCHValidator(const LangOptions &ExistingLangOpts,
+ const CodeGenOptions &ExistingCGOpts,
const TargetOptions &ExistingTargetOpts,
const PreprocessorOptions &ExistingPPOpts,
StringRef ExistingModuleCachePath, FileManager &FileMgr,
bool StrictOptionMatches)
- : ExistingLangOpts(ExistingLangOpts),
+ : ExistingLangOpts(ExistingLangOpts), ExistingCGOpts(ExistingCGOpts),
ExistingTargetOpts(ExistingTargetOpts),
ExistingPPOpts(ExistingPPOpts),
ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr),
@@ -5664,6 +5754,13 @@ namespace {
nullptr, AllowCompatibleDifferences);
}
+ bool ReadCodeGenOptions(const CodeGenOptions &CGOpts,
+ StringRef ModuleFilename, bool Complain,
+ bool AllowCompatibleDifferences) override {
+ return checkCodegenOptions(ExistingCGOpts, CGOpts, ModuleFilename,
+ nullptr, AllowCompatibleDifferences);
+ }
+
bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override {
@@ -6012,9 +6109,10 @@ bool ASTReader::readASTFileControlBlock(
bool ASTReader::isAcceptableASTFile(
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts,
- const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts,
- StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches) {
- SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
+ const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts,
+ const PreprocessorOptions &PPOpts, StringRef ExistingModuleCachePath,
+ bool RequireStrictOptionMatches) {
+ SimplePCHValidator validator(LangOpts, CGOpts, TargetOpts, PPOpts,
ExistingModuleCachePath, FileMgr,
RequireStrictOptionMatches);
return !readASTFileControlBlock(Filename, FileMgr, ModCache, PCHContainerRdr,
@@ -6395,6 +6493,28 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record,
AllowCompatibleDifferences);
}
+bool ASTReader::ParseCodeGenOptions(const RecordData &Record,
+ StringRef ModuleFilename, bool Complain,
+ ASTReaderListener &Listener,
+ bool AllowCompatibleDifferences) {
+ unsigned Idx = 0;
+ CodeGenOptions CGOpts;
+ using CK = CodeGenOptions::CompatibilityKind;
+#define CODEGENOPT(Name, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ CGOpts.Name = static_cast<unsigned>(Record[Idx++]);
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ CGOpts.set##Name(static_cast<clang::CodeGenOptions::Type>(Record[Idx++]));
+#define DEBUGOPT(Name, Bits, Default, Compatibility)
+#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
+#include "clang/Basic/CodeGenOptions.def"
+
+ return Listener.ReadCodeGenOptions(CGOpts, ModuleFilename, Complain,
+ AllowCompatibleDifferences);
+}
+
bool ASTReader::ParseTargetOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
@@ -10985,6 +11105,7 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache,
ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
+ const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot,
DisableValidationForModuleKind DisableValidationKind,
@@ -10999,6 +11120,7 @@ ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache,
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()),
StackHandler(Diags), PP(PP), ContextObj(Context),
+ CodeGenOpts(CodeGenOpts),
ModuleMgr(PP.getFileManager(), ModCache, PCHContainerRdr,
PP.getHeaderSearchInfo()),
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1a20fc9..847283e 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -898,6 +898,7 @@ void ASTWriter::WriteBlockInfoBlock() {
BLOCK(OPTIONS_BLOCK);
RECORD(LANGUAGE_OPTIONS);
+ RECORD(CODEGEN_OPTIONS);
RECORD(TARGET_OPTIONS);
RECORD(FILE_SYSTEM_OPTIONS);
RECORD(HEADER_SEARCH_OPTIONS);
@@ -1646,6 +1647,23 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
+ // Codegen options.
+ // FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
+ using CK = CodeGenOptions::CompatibilityKind;
+ Record.clear();
+ const CodeGenOptions &CGOpts = getCodeGenOpts();
+#define CODEGENOPT(Name, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ Record.push_back(static_cast<unsigned>(CGOpts.Name));
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
+ if constexpr (CK::Compatibility != CK::Benign) \
+ Record.push_back(static_cast<unsigned>(CGOpts.get##Name()));
+#define DEBUGOPT(Name, Bits, Default, Compatibility)
+#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
+#include "clang/Basic/CodeGenOptions.def"
+ Stream.EmitRecord(CODEGEN_OPTIONS, Record);
+
// Target options.
Record.clear();
const TargetInfo &Target = PP.getTargetInfo();
@@ -5384,11 +5402,12 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
SmallVectorImpl<char> &Buffer, ModuleCache &ModCache,
+ const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool IncludeTimestamps, bool BuildingImplicitModule,
bool GeneratingReducedBMI)
: Stream(Stream), Buffer(Buffer), ModCache(ModCache),
- IncludeTimestamps(IncludeTimestamps),
+ CodeGenOpts(CodeGenOpts), IncludeTimestamps(IncludeTimestamps),
BuildingImplicitModule(BuildingImplicitModule),
GeneratingReducedBMI(GeneratingReducedBMI) {
for (const auto &Ext : Extensions) {
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index 77317f0..f8be0e4 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -25,13 +25,14 @@ using namespace clang;
PCHGenerator::PCHGenerator(
Preprocessor &PP, ModuleCache &ModCache, StringRef OutputFile,
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
+ const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
bool BuildingImplicitModule, bool ShouldCacheASTInMemory,
bool GeneratingReducedBMI)
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
- Writer(Stream, this->Buffer->Data, ModCache, Extensions,
+ Writer(Stream, this->Buffer->Data, ModCache, CodeGenOpts, Extensions,
IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
AllowASTWithErrors(AllowASTWithErrors),
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
@@ -102,11 +103,12 @@ void PCHGenerator::anchor() {}
CXX20ModulesGenerator::CXX20ModulesGenerator(Preprocessor &PP,
ModuleCache &ModCache,
StringRef OutputFile,
+ const CodeGenOptions &CodeGenOpts,
bool GeneratingReducedBMI,
bool AllowASTWithErrors)
: PCHGenerator(
PP, ModCache, OutputFile, llvm::StringRef(),
- std::make_shared<PCHBuffer>(),
+ std::make_shared<PCHBuffer>(), CodeGenOpts,
/*Extensions=*/ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
AllowASTWithErrors, /*IncludeTimestamps=*/false,
/*BuildingImplicitModule=*/false, /*ShouldCacheASTInMemory=*/false,