https://github.com/matts1 created https://github.com/llvm/llvm-project/pull/141459
See #141165 for details on why to do this >From d410b2f6e804697b0903936afb0681889bcb95ef Mon Sep 17 00:00:00 2001 From: Matt Stark <m...@google.com> Date: Mon, 26 May 2025 14:06:00 +1000 Subject: [PATCH] Allow a user to decide whether changes in various language options are allowed across modules. --- .../Basic/DiagnosticSerializationKinds.td | 4 +- .../include/clang/Basic/LangOptionsOptions.h | 38 +++++++++++++++++++ clang/include/clang/Driver/Options.td | 4 ++ .../include/clang/Frontend/CompilerInstance.h | 1 + .../include/clang/Frontend/FrontendOptions.h | 7 ++++ clang/include/clang/Serialization/ASTReader.h | 10 ++++- clang/lib/Frontend/ASTUnit.cpp | 5 ++- clang/lib/Frontend/ChainedIncludesSource.cpp | 1 + clang/lib/Frontend/CompilerInstance.cpp | 11 ++++-- clang/lib/Frontend/CompilerInvocation.cpp | 9 +++++ clang/lib/Frontend/FrontendAction.cpp | 1 + clang/lib/Frontend/FrontendActions.cpp | 1 + clang/lib/Serialization/ASTReader.cpp | 32 ++++++++++------ 13 files changed, 107 insertions(+), 17 deletions(-) create mode 100644 clang/include/clang/Basic/LangOptionsOptions.h diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 7965da593f218..b66338955d3e3 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -37,8 +37,10 @@ def err_ast_file_targetopt_feature_mismatch : Error< "feature '%2' but the %select{current translation unit is|AST file '%1' was}0 " "not">; def err_ast_file_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in " - "AST file '%3' but is currently %select{disabled|enabled}2">; + "AST file '%3' but is currently %select{disabled|enabled}2. To ignore this, add -fmodule-config-mismatch-ignore=%4">; def err_ast_file_langopt_value_mismatch : Error< + "%0 differs in AST file '%1' vs. current file. To ignore this, add -fmodule-config-mismatch-ignore=%4">; +def err_ast_file_langopt_value_nameless_mismatch : Error< "%0 differs in AST file '%1' vs. current file">; def err_ast_file_diagopt_mismatch : Error<"%0 is currently enabled, but was not in " "the AST file '%1'">; diff --git a/clang/include/clang/Basic/LangOptionsOptions.h b/clang/include/clang/Basic/LangOptionsOptions.h new file mode 100644 index 0000000000000..861af1df0b04e --- /dev/null +++ b/clang/include/clang/Basic/LangOptionsOptions.h @@ -0,0 +1,38 @@ +#ifndef LLVM_CLANG_INCLUDE_BASIC_LANGOPTIONSOPTIONS_H +#define LLVM_CLANG_INCLUDE_BASIC_LANGOPTIONSOPTIONS_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticDriver.h" +#include <cstddef> +#include <string> +#include <unordered_map> + +using namespace clang; + +struct LangOptionsOption { + // Completely ignores this option when it comes to + bool ignore_mismatch; +}; + +// Options that can be applied arbitrarily to any langopt +struct LangOptionsOptions { + +#define LANGOPT(Name, Bits, Default, Description) LangOptionsOption Name; +#include "clang/Basic/LangOptions.def" + + LangOptionsOption* get(const std::string& OptName) { + #define LANGOPT(Name, Bits, Default, Description) \ + {std::string(#Name), offsetof(LangOptionsOptions, Name)}, + static const std::unordered_map<std::string, size_t> Offsets = { + #include "clang/Basic/LangOptions.def" + }; + if (auto it = Offsets.find(OptName); it != Offsets.end()) { + auto Offset = it->second; + return reinterpret_cast<LangOptionsOption*>(reinterpret_cast<std::byte*>(this) + Offset); + } else { + return nullptr; + } + } +}; + +#endif // LLVM_CLANG_INCLUDE_BASIC_LANGOPTIONSOPTIONS_H \ No newline at end of file diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 22261621df092..fea227360078d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -8026,6 +8026,10 @@ def fmodules_embed_file_EQ : Joined<["-"], "fmodules-embed-file=">, HelpText<"Embed the contents of the specified file into the module file " "being compiled.">, MarshallingInfoStringVector<FrontendOpts<"ModulesEmbedFiles">>; +def fmodule_config_mismatch_ignores: CommaJoined<["-"], "fmodule-config-mismatch-ignores=">, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Comma separated list of options to ignore for the purposes of a config mismatch">, + MarshallingInfoStringVector<FrontendOpts<"ModuleConfigMismatchIgnoresVec">>; defm fimplicit_modules_use_lock : BoolOption<"f", "implicit-modules-use-lock", FrontendOpts<"BuildingImplicitModuleUsesLock">, DefaultTrue, NegFlag<SetFalse>, diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index 5f25a932c5052..c60720a21ad21 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -721,6 +721,7 @@ class CompilerInstance : public ModuleLoader { bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + LangOptionsOptions& LangOptionsOpts, ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex); diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index c919a53ae089e..7411d56bcfb8b 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H #include "clang/AST/ASTDumperUtils.h" +#include "clang/Basic/LangOptionsOptions.h" #include "clang/Basic/LangStandard.h" #include "clang/Frontend/CommandLineSourceLoc.h" #include "clang/Sema/CodeCompleteOptions.h" @@ -489,6 +490,9 @@ class FrontendOptions { /// The list of files to embed into the compiled module file. std::vector<std::string> ModulesEmbedFiles; + // The list of names of options to ignore for the purposes of a module config mismatch. + std::vector<std::string> ModuleConfigMismatchIgnoresVec; + /// The list of AST files to merge. std::vector<std::string> ASTMergeFiles; @@ -534,6 +538,9 @@ class FrontendOptions { /// minimization hints. std::string DumpMinimizationHintsPath; + // A per-opt configuration. + LangOptionsOptions LangOptionsOpts; + public: FrontendOptions() : DisableFree(false), RelocatablePCH(false), ShowHelp(false), diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 57b0266af26bb..3a3dfe807c686 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -17,6 +17,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangOptionsOptions.h" #include "clang/Basic/OpenCLOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/StackExhaustionHandler.h" @@ -1091,6 +1092,9 @@ class ASTReader /// from the current compiler instance. bool AllowConfigurationMismatch; + /// The options controlling how we use language options. + LangOptionsOptions LangOptionsOpts; + /// Whether to validate system input files. bool ValidateSystemInputs; @@ -1733,10 +1737,12 @@ class ASTReader /// /// \param PCHContainerRdr the PCHContainerOperations to use for loading and /// creating modules. - /// + /// /// \param Extensions the list of module file extensions that can be loaded /// from the AST files. /// + /// \param LangOptionsOpts Controls how LangOptions are treated. + /// /// \param isysroot If non-NULL, the system include path specified by the /// user. This is only used with relocatable PCH files. If non-NULL, /// a relocatable PCH file will use the default path "/". @@ -1764,6 +1770,7 @@ class ASTReader ASTReader(Preprocessor &PP, ModuleCache &ModCache, ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + const LangOptionsOptions &LangOptionsOpts, StringRef isysroot = "", DisableValidationForModuleKind DisableValidationKind = DisableValidationForModuleKind::None, @@ -1988,6 +1995,7 @@ class ASTReader const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, + const LangOptionsOptions &LangOptionsOpts, StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches = false); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 5a79fe070c384..eb49a1d42d2d5 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -30,6 +30,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangOptionsOptions.h" #include "clang/Basic/LangStandard.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" @@ -861,7 +862,9 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = DisableValidationForModuleKind::All; AST->Reader = new ASTReader( - PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, {}, /*isysroot=*/"", + PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, {}, + LangOptionsOptions{}, + /*isysroot=*/"", /*DisableValidationKind=*/disableValid, AllowASTWithCompilerErrors); unsigned Counter = 0; diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index 95b0ed248d545..9ebbb1019cbd5 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -63,6 +63,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile, Reader.reset(new ASTReader( PP, CI.getModuleCache(), &CI.getASTContext(), CI.getPCHContainerReader(), /*Extensions=*/{}, + CI.getFrontendOpts().LangOptionsOpts, /*isysroot=*/"", DisableValidationForModuleKind::PCH)); for (unsigned ti = 0; ti < bufNames.size(); ++ti) { StringRef sr(bufNames[ti]); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 503d36467653e..52b297221560a 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -617,7 +617,9 @@ void CompilerInstance::createPCHExternalASTSource( Path, getHeaderSearchOpts().Sysroot, DisableValidation, AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(), getASTContext(), getPCHContainerReader(), - getFrontendOpts().ModuleFileExtensions, DependencyCollectors, + getFrontendOpts().ModuleFileExtensions, + getFrontendOpts().LangOptionsOpts, + DependencyCollectors, DeserializationListener, OwnDeserializationListener, Preamble, getFrontendOpts().UseGlobalModuleIndex); } @@ -628,6 +630,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + LangOptionsOptions& LangOptionsOpts, ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex) { @@ -636,6 +639,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( PP, ModCache, &Context, PCHContainerRdr, Extensions, + LangOptionsOpts, Sysroot.empty() ? "" : Sysroot.data(), DisableValidation, AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders, @@ -1748,14 +1752,15 @@ void CompilerInstance::createASTReader() { "Reading modules", *timerGroup); TheASTReader = new ASTReader( getPreprocessor(), getModuleCache(), &getASTContext(), - getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, + getPCHContainerReader(), FEOpts.ModuleFileExtensions, + FEOpts.LangOptionsOpts, Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHOrModuleValidation, /*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors, /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders, HSOpts.ModulesForceValidateUserHeaders, HSOpts.ValidateASTInputFilesContent, - getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); + FEOpts.UseGlobalModuleIndex, std::move(ReadTimer)); if (hasASTConsumer()) { TheASTReader->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3c23073fc6a8c..2e24a585f1a16 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3265,6 +3265,15 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.DashX = DashX; + for (auto&& OptName : std::move(Opts.ModuleConfigMismatchIgnoresVec)) { + if (LangOptionsOption* OptValue = Opts.LangOptionsOpts.get(OptName); OptValue != nullptr) { + OptValue->ignore_mismatch = true; + } else { + Diags.Report(diag::err_drv_invalid_value) + << "-fmodule-config-mismatch-ignores" << OptName; + } + } + return Diags.getNumErrors() == NumErrorsBefore; } diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 54a2e3eb297f5..2682be3d1a49a 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -948,6 +948,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, Dir->path(), FileMgr, CI.getModuleCache(), CI.getPCHContainerReader(), CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), + CI.getFrontendOpts().LangOptionsOpts, SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) { PPOpts.ImplicitPCHInclude = std::string(Dir->path()); Found = true; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 8c75e1a46da54..261aa899694c4 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -360,6 +360,7 @@ void VerifyPCHAction::ExecuteAction() { std::unique_ptr<ASTReader> Reader(new ASTReader( CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(), CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions, + CI.getFrontendOpts().LangOptionsOpts, Sysroot.empty() ? "" : Sysroot.c_str(), DisableValidationForModuleKind::None, /*AllowASTWithCompilerErrors*/ false, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index d068f5e163176..422aecf32de67 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -53,6 +53,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangOptionsOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/OpenACCKinds.h" @@ -286,34 +287,35 @@ static bool checkLanguageOptions(const LangOptions &LangOpts, const LangOptions &ExistingLangOpts, StringRef ModuleFilename, DiagnosticsEngine *Diags, + const LangOptionsOptions &LangOptionsOpts, bool AllowCompatibleDifferences = true) { #define LANGOPT(Name, Bits, Default, Description) \ - if (ExistingLangOpts.Name != LangOpts.Name) { \ + if (ExistingLangOpts.Name != LangOpts.Name && !LangOptionsOpts.Name.ignore_mismatch) { \ if (Diags) { \ if (Bits == 1) \ Diags->Report(diag::err_ast_file_langopt_mismatch) \ << Description << LangOpts.Name << ExistingLangOpts.Name \ - << ModuleFilename; \ + << ModuleFilename << #Name; \ else \ Diags->Report(diag::err_ast_file_langopt_value_mismatch) \ - << Description << ModuleFilename; \ + << Description << ModuleFilename << #Name; \ } \ return true; \ } #define VALUE_LANGOPT(Name, Bits, Default, Description) \ - if (ExistingLangOpts.Name != LangOpts.Name) { \ + if (ExistingLangOpts.Name != LangOpts.Name && !LangOptionsOpts.Name.ignore_mismatch) { \ if (Diags) \ Diags->Report(diag::err_ast_file_langopt_value_mismatch) \ - << Description << ModuleFilename; \ + << Description << ModuleFilename << #Name; \ return true; \ } #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) { \ + if (ExistingLangOpts.get##Name() != LangOpts.get##Name() && !LangOptionsOpts.Name.ignore_mismatch) { \ if (Diags) \ Diags->Report(diag::err_ast_file_langopt_value_mismatch) \ - << Description << ModuleFilename; \ + << Description << ModuleFilename << #Name; \ return true; \ } @@ -336,14 +338,14 @@ static bool checkLanguageOptions(const LangOptions &LangOpts, if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) { if (Diags) - Diags->Report(diag::err_ast_file_langopt_value_mismatch) + Diags->Report(diag::err_ast_file_langopt_value_nameless_mismatch) << "module features" << ModuleFilename; return true; } if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) { if (Diags) - Diags->Report(diag::err_ast_file_langopt_value_mismatch) + Diags->Report(diag::err_ast_file_langopt_value_nameless_mismatch) << "target Objective-C runtime" << ModuleFilename; return true; } @@ -351,7 +353,7 @@ static bool checkLanguageOptions(const LangOptions &LangOpts, if (ExistingLangOpts.CommentOpts.BlockCommandNames != LangOpts.CommentOpts.BlockCommandNames) { if (Diags) - Diags->Report(diag::err_ast_file_langopt_value_mismatch) + Diags->Report(diag::err_ast_file_langopt_value_nameless_mismatch) << "block command names" << ModuleFilename; return true; } @@ -462,6 +464,7 @@ bool PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts, const LangOptions &ExistingLangOpts = PP.getLangOpts(); return checkLanguageOptions(LangOpts, ExistingLangOpts, ModuleFilename, Complain ? &Reader.Diags : nullptr, + Reader.LangOptionsOpts, AllowCompatibleDifferences); } @@ -5644,6 +5647,7 @@ namespace { const LangOptions &ExistingLangOpts; const TargetOptions &ExistingTargetOpts; const PreprocessorOptions &ExistingPPOpts; + const LangOptionsOptions &LangOptionsOpts; std::string ExistingModuleCachePath; FileManager &FileMgr; bool StrictOptionMatches; @@ -5652,11 +5656,13 @@ namespace { SimplePCHValidator(const LangOptions &ExistingLangOpts, const TargetOptions &ExistingTargetOpts, const PreprocessorOptions &ExistingPPOpts, + const LangOptionsOptions &LangOptionsOpts, StringRef ExistingModuleCachePath, FileManager &FileMgr, bool StrictOptionMatches) : ExistingLangOpts(ExistingLangOpts), ExistingTargetOpts(ExistingTargetOpts), ExistingPPOpts(ExistingPPOpts), + LangOptionsOpts(LangOptionsOpts), ExistingModuleCachePath(ExistingModuleCachePath), FileMgr(FileMgr), StrictOptionMatches(StrictOptionMatches) {} @@ -5664,7 +5670,7 @@ namespace { StringRef ModuleFilename, bool Complain, bool AllowCompatibleDifferences) override { return checkLanguageOptions(ExistingLangOpts, LangOpts, ModuleFilename, - nullptr, AllowCompatibleDifferences); + nullptr, LangOptionsOpts, AllowCompatibleDifferences); } bool ReadTargetOptions(const TargetOptions &TargetOpts, @@ -6016,8 +6022,10 @@ bool ASTReader::isAcceptableASTFile( StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, + const LangOptionsOptions& LangOptionsOpts, StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches) { SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, + LangOptionsOpts, ExistingModuleCachePath, FileMgr, RequireStrictOptionMatches); return !readASTFileControlBlock(Filename, FileMgr, ModCache, PCHContainerRdr, @@ -10970,6 +10978,7 @@ ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache, ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, + const LangOptionsOptions& LangOptionsOpts, StringRef isysroot, DisableValidationForModuleKind DisableValidationKind, bool AllowASTWithCompilerErrors, @@ -10989,6 +10998,7 @@ ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache, DisableValidationKind(DisableValidationKind), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch), + LangOptionsOpts(LangOptionsOpts), ValidateSystemInputs(ValidateSystemInputs), ForceValidateUserInputs(ForceValidateUserInputs), ValidateASTInputFilesContent(ValidateASTInputFilesContent), _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits