[llvm-branch-commits] [clang] b0e8990 - [ASTReader] Allow controlling separately whether validation should be disabled for a PCH vs a module file
Argyrios Kyrtzidis via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jan 21 20:50:29 PST 2021
Author: Argyrios Kyrtzidis
Date: 2021-01-21T20:45:54-08:00
New Revision: b0e89906f5b7e505a1ea315ab4ff612b1607fda8
URL: https://github.com/llvm/llvm-project/commit/b0e89906f5b7e505a1ea315ab4ff612b1607fda8
DIFF: https://github.com/llvm/llvm-project/commit/b0e89906f5b7e505a1ea315ab4ff612b1607fda8.diff
LOG: [ASTReader] Allow controlling separately whether validation should be disabled for a PCH vs a module file
This addresses an issue with how the PCH preable works, specifically:
1. When using a PCH/preamble the module hash changes and a different cache directory is used
2. When the preamble is used, PCH & PCM validation is disabled.
Due to combination of #1 and #2, reparsing with preamble enabled can end up loading a stale module file before a header change and using it without updating it because validation is disabled and it doesn’t check that the header has changed and the module file is out-of-date.
rdar://72611253
Differential Revision: https://reviews.llvm.org/D95159
Added:
clang/test/Index/Inputs/preamble-reparse-changed-module/head.h
clang/test/Index/Inputs/preamble-reparse-changed-module/module.modulemap
clang/test/Index/Inputs/preamble-reparse-changed-module/new-head.h
clang/test/Index/preamble-reparse-changed-module.m
Modified:
clang/include/clang/Driver/Options.td
clang/include/clang/Frontend/CompilerInstance.h
clang/include/clang/Lex/PreprocessorOptions.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/ChainedIncludesSource.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Frontend/FrontendAction.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/lib/Frontend/PrecompiledPreamble.cpp
clang/lib/Serialization/ASTReader.cpp
clang/tools/c-index-test/c-index-test.c
clang/tools/c-index-test/core_main.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 500022c2c99b..a2800381be0e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5121,7 +5121,8 @@ def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interpositi
MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>;
def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
HelpText<"Disable validation of precompiled headers">,
- MarshallingInfoFlag<PreprocessorOpts<"DisablePCHValidation">>;
+ MarshallingInfoFlag<PreprocessorOpts<"DisablePCHOrModuleValidation">, "DisableValidationForModuleKind::None">,
+ Normalizer<"makeFlagToValueNormalizer(DisableValidationForModuleKind::All)">;
def fallow_pcm_with_errors : Flag<["-"], "fallow-pcm-with-compiler-errors">,
HelpText<"Accept a PCM file that was created with compiler errors">,
MarshallingInfoFlag<FrontendOpts<"AllowPCMWithCompilerErrors">>;
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 4fc002c6f383..15f6ed2df885 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -50,6 +50,7 @@ class Preprocessor;
class Sema;
class SourceManager;
class TargetInfo;
+enum class DisableValidationForModuleKind;
/// CompilerInstance - Helper class for managing a single instance of the Clang
/// compiler.
@@ -659,16 +660,17 @@ class CompilerInstance : public ModuleLoader {
/// Create an external AST source to read a PCH file and attach it to the AST
/// context.
- void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors,
- void *DeserializationListener,
- bool OwnDeserializationListener);
+ void createPCHExternalASTSource(
+ StringRef Path, DisableValidationForModuleKind DisableValidation,
+ bool AllowPCHWithCompilerErrors, void *DeserializationListener,
+ bool OwnDeserializationListener);
/// Create an external AST source to read a PCH file.
///
/// \return - The new object on success, or null on failure.
static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
- StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
+ StringRef Path, StringRef Sysroot,
+ DisableValidationForModuleKind DisableValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP,
InMemoryModuleCache &ModuleCache, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h
index c551f87e0d7b..7f024989bf9b 100644
--- a/clang/include/clang/Lex/PreprocessorOptions.h
+++ b/clang/include/clang/Lex/PreprocessorOptions.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
+#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/LLVM.h"
#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
#include "llvm/ADT/StringRef.h"
@@ -40,6 +41,24 @@ enum ObjCXXARCStandardLibraryKind {
ARCXX_libstdcxx
};
+/// Whether to disable the normal validation performed on precompiled
+/// headers and module files when they are loaded.
+enum class DisableValidationForModuleKind {
+ /// Perform validation, don't disable it.
+ None = 0,
+
+ /// Disable validation for a precompiled header and the modules it depends on.
+ PCH = 0x1,
+
+ /// Disable validation for module files.
+ Module = 0x2,
+
+ /// Disable validation for all kinds.
+ All = PCH | Module,
+
+ LLVM_MARK_AS_BITMASK_ENUM(Module)
+};
+
/// PreprocessorOptions - This class is used for passing the various options
/// used in preprocessor initialization to InitializePreprocessor().
class PreprocessorOptions {
@@ -79,9 +98,10 @@ class PreprocessorOptions {
/// Headers that will be converted to chained PCHs in memory.
std::vector<std::string> ChainedIncludes;
- /// When true, disables most of the normal validation performed on
- /// precompiled headers.
- bool DisablePCHValidation = false;
+ /// Whether to disable most of the normal validation performed on
+ /// precompiled headers and module files.
+ DisableValidationForModuleKind DisablePCHOrModuleValidation =
+ DisableValidationForModuleKind::None;
/// When true, a PCH with compiler errors will not be rejected.
bool AllowPCHWithCompilerErrors = false;
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index ec332a73de13..d0d2a68114c7 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -23,6 +23,7 @@
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Sema/Sema.h"
@@ -441,6 +442,9 @@ class ASTReader
/// imported from. For non-module AST types it should be invalid.
SourceLocation CurrentImportLoc;
+ /// The module kind that is currently deserializing.
+ Optional<ModuleKind> CurrentDeserializingModuleKind;
+
/// The global module index, if loaded.
std::unique_ptr<GlobalModuleIndex> GlobalIndex;
@@ -931,8 +935,8 @@ class ASTReader
std::string isysroot;
/// Whether to disable the normal validation performed on precompiled
- /// headers when they are loaded.
- bool DisableValidation;
+ /// headers and module files when they are loaded.
+ DisableValidationForModuleKind DisableValidationKind;
/// Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
@@ -1215,6 +1219,8 @@ class ASTReader
llvm::DenseMap<const Decl *, bool> DefinitionSource;
+ bool shouldDisableValidationForFile(const serialization::ModuleFile &M) const;
+
/// Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
@@ -1473,9 +1479,9 @@ class ASTReader
/// user. This is only used with relocatable PCH files. If non-NULL,
/// a relocatable PCH file will use the default path "/".
///
- /// \param DisableValidation If true, the AST reader will suppress most
+ /// \param DisableValidationKind If set, the AST reader will suppress most
/// of its regular consistency checking, allowing the use of precompiled
- /// headers that cannot be determined to be compatible.
+ /// headers and module files that cannot be determined to be compatible.
///
/// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
/// AST file the was created out of an AST with compiler errors,
@@ -1496,7 +1502,9 @@ class ASTReader
ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
ASTContext *Context, const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- StringRef isysroot = "", bool DisableValidation = false,
+ StringRef isysroot = "",
+ DisableValidationForModuleKind DisableValidationKind =
+ DisableValidationForModuleKind::None,
bool AllowASTWithCompilerErrors = false,
bool AllowConfigurationMismatch = false,
bool ValidateSystemInputs = false,
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 51851a5bac83..e79e70be6338 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -809,9 +809,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
PP.getIdentifierTable(), PP.getSelectorTable(),
PP.getBuiltinInfo());
- bool disableValid = false;
+ DisableValidationForModuleKind disableValid =
+ DisableValidationForModuleKind::None;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
- disableValid = true;
+ disableValid = DisableValidationForModuleKind::All;
AST->Reader = new ASTReader(
PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
/*isysroot=*/"",
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index 1486adf70c3f..380eba4562b4 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -83,10 +83,10 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
ASTDeserializationListener *deserialListener = nullptr) {
Preprocessor &PP = CI.getPreprocessor();
std::unique_ptr<ASTReader> Reader;
- Reader.reset(new ASTReader(PP, CI.getModuleCache(), &CI.getASTContext(),
- CI.getPCHContainerReader(),
- /*Extensions=*/{},
- /*isysroot=*/"", /*DisableValidation=*/true));
+ Reader.reset(new ASTReader(
+ PP, CI.getModuleCache(), &CI.getASTContext(), CI.getPCHContainerReader(),
+ /*Extensions=*/{},
+ /*isysroot=*/"", DisableValidationForModuleKind::PCH));
for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
StringRef sr(bufNames[ti]);
Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
@@ -129,7 +129,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
CInvok->getPreprocessorOpts().ChainedIncludes.clear();
CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
- CInvok->getPreprocessorOpts().DisablePCHValidation = true;
+ CInvok->getPreprocessorOpts().DisablePCHOrModuleValidation =
+ DisableValidationForModuleKind::PCH;
CInvok->getPreprocessorOpts().Includes.clear();
CInvok->getPreprocessorOpts().MacroIncludes.clear();
CInvok->getPreprocessorOpts().Macros.clear();
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 5c413ec4dfa9..a85d6f69d9eb 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -503,11 +503,12 @@ void CompilerInstance::createASTContext() {
// ExternalASTSource
void CompilerInstance::createPCHExternalASTSource(
- StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,
- void *DeserializationListener, bool OwnDeserializationListener) {
+ StringRef Path, DisableValidationForModuleKind DisableValidation,
+ bool AllowPCHWithCompilerErrors, void *DeserializationListener,
+ bool OwnDeserializationListener) {
bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
TheASTReader = createPCHExternalASTSource(
- Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
+ Path, getHeaderSearchOpts().Sysroot, DisableValidation,
AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),
getASTContext(), getPCHContainerReader(),
getFrontendOpts().ModuleFileExtensions, DependencyCollectors,
@@ -516,7 +517,8 @@ void CompilerInstance::createPCHExternalASTSource(
}
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
- StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
+ StringRef Path, StringRef Sysroot,
+ DisableValidationForModuleKind DisableValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP,
InMemoryModuleCache &ModuleCache, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
@@ -528,7 +530,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
- Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
+ Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent,
UseGlobalModuleIndex));
@@ -1497,7 +1499,8 @@ void CompilerInstance::createASTReader() {
TheASTReader = new ASTReader(
getPreprocessor(), getModuleCache(), &getASTContext(),
getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
- Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
+ Sysroot.empty() ? "" : Sysroot.c_str(),
+ PPOpts.DisablePCHOrModuleValidation,
/*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors,
/*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders,
HSOpts.ValidateASTInputFilesContent,
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 231787326243..11b25b106627 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -873,9 +873,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
CI.createPCHExternalASTSource(
CI.getPreprocessorOpts().ImplicitPCHInclude,
- CI.getPreprocessorOpts().DisablePCHValidation,
- CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
- DeleteDeserialListener);
+ CI.getPreprocessorOpts().DisablePCHOrModuleValidation,
+ CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
+ DeserialListener, DeleteDeserialListener);
if (!CI.getASTContext().getExternalSource())
goto failure;
}
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 42531fa3481b..d32f27a62dcf 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -344,7 +344,7 @@ void VerifyPCHAction::ExecuteAction() {
CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(),
CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
- /*DisableValidation*/ false,
+ DisableValidationForModuleKind::None,
/*AllowASTWithCompilerErrors*/ false,
/*AllowConfigurationMismatch*/ true,
/*ValidateSystemInputs*/ true));
diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp
index 49aab8132cc3..b253d083c153 100644
--- a/clang/lib/Frontend/PrecompiledPreamble.cpp
+++ b/clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -812,7 +812,8 @@ void PrecompiledPreamble::configurePreamble(
PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.Size;
PreprocessorOpts.PrecompiledPreambleBytes.second =
Bounds.PreambleEndsAtStartOfLine;
- PreprocessorOpts.DisablePCHValidation = true;
+ PreprocessorOpts.DisablePCHOrModuleValidation =
+ DisableValidationForModuleKind::PCH;
setupPreambleStorage(Storage, PreprocessorOpts, VFS);
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index d01e7c69d181..08de162917ea 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2211,6 +2211,29 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
PP.setLoadedMacroDirective(II, Earliest, Latest);
}
+bool ASTReader::shouldDisableValidationForFile(
+ const serialization::ModuleFile &M) const {
+ if (DisableValidationKind == DisableValidationForModuleKind::None)
+ return false;
+
+ // If a PCH is loaded and validation is disabled for PCH then disable
+ // validation for the PCH and the modules it loads.
+ ModuleKind K = CurrentDeserializingModuleKind.getValueOr(M.Kind);
+
+ switch (K) {
+ case MK_MainFile:
+ case MK_Preamble:
+ case MK_PCH:
+ return bool(DisableValidationKind & DisableValidationForModuleKind::PCH);
+ case MK_ImplicitModule:
+ case MK_ExplicitModule:
+ case MK_PrebuiltModule:
+ return bool(DisableValidationKind & DisableValidationForModuleKind::Module);
+ }
+
+ return false;
+}
+
ASTReader::InputFileInfo
ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
// Go find this input file.
@@ -2357,7 +2380,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
auto HasInputFileChanged = [&]() {
if (StoredSize != File->getSize())
return ModificationType::Size;
- if (!DisableValidation && StoredTime &&
+ if (!shouldDisableValidationForFile(F) && StoredTime &&
StoredTime != File->getModificationTime()) {
// In case the modification time changes but not the content,
// accept the cached file as legit.
@@ -2573,6 +2596,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
return Success;
};
+ bool DisableValidation = shouldDisableValidationForFile(F);
+
// Read all of the records and blocks in the control block.
RecordData Record;
unsigned NumInputs = 0;
@@ -2871,7 +2896,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// If we're implicitly loading a module, the base directory can't
// change between the build and use.
// Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation &&
+ if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
+ DisableValidationForModuleKind::Module) &&
F.Kind != MK_ExplicitModule && F.Kind != MK_PrebuiltModule) {
auto BuildDir = PP.getFileManager().getDirectory(Blob);
if (!BuildDir || *BuildDir != M->Directory) {
@@ -3903,7 +3929,9 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
// Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation && !ModMap) {
+ if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
+ DisableValidationForModuleKind::Module) &&
+ !ModMap) {
if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) {
if (auto ASTFE = M ? M->getASTFile() : None) {
// This module was defined by an imported (explicit) module.
@@ -4189,6 +4217,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
SmallVectorImpl<ImportedSubmodule> *Imported) {
llvm::SaveAndRestore<SourceLocation>
SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
+ llvm::SaveAndRestore<Optional<ModuleKind>> SetCurModuleKindRAII(
+ CurrentDeserializingModuleKind, Type);
// Defer any pending actions until we get to the end of reading the AST file.
Deserializing AnASTFile(this);
@@ -4623,6 +4653,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
PP.getHeaderSearchInfo().getHeaderSearchOpts();
bool AllowCompatibleConfigurationMismatch =
F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
+ bool DisableValidation = shouldDisableValidationForFile(F);
ASTReadResult Result = readUnhashedControlBlockImpl(
&F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch,
@@ -5514,7 +5545,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
if (!ParentModule) {
if (const FileEntry *CurFile = CurrentModule->getASTFile()) {
// Don't emit module relocation error if we have -fno-validate-pch
- if (!PP.getPreprocessorOpts().DisablePCHValidation &&
+ if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
+ DisableValidationForModuleKind::Module) &&
CurFile != F.File) {
Error(diag::err_module_file_conflict,
CurrentModule->getTopLevelModuleName(), CurFile->getName(),
@@ -11601,12 +11633,13 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- StringRef isysroot, bool DisableValidation,
+ StringRef isysroot,
+ DisableValidationForModuleKind DisableValidationKind,
bool AllowASTWithCompilerErrors,
bool AllowConfigurationMismatch, bool ValidateSystemInputs,
bool ValidateASTInputFilesContent, bool UseGlobalIndex,
std::unique_ptr<llvm::Timer> ReadTimer)
- : Listener(DisableValidation
+ : Listener(bool(DisableValidationKind &DisableValidationForModuleKind::PCH)
? cast<ASTReaderListener>(new SimpleASTReaderListener(PP))
: cast<ASTReaderListener>(new PCHValidator(PP, *this))),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
@@ -11614,7 +11647,7 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache,
PCHContainerRdr, PP.getHeaderSearchInfo()),
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
- DisableValidation(DisableValidation),
+ DisableValidationKind(DisableValidationKind),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
AllowConfigurationMismatch(AllowConfigurationMismatch),
ValidateSystemInputs(ValidateSystemInputs),
diff --git a/clang/test/Index/Inputs/preamble-reparse-changed-module/head.h b/clang/test/Index/Inputs/preamble-reparse-changed-module/head.h
new file mode 100644
index 000000000000..47151026eab6
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-reparse-changed-module/head.h
@@ -0,0 +1,3 @@
+ at interface I
+- (void)call_me;
+ at end
diff --git a/clang/test/Index/Inputs/preamble-reparse-changed-module/module.modulemap b/clang/test/Index/Inputs/preamble-reparse-changed-module/module.modulemap
new file mode 100644
index 000000000000..800176730235
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-reparse-changed-module/module.modulemap
@@ -0,0 +1,3 @@
+module mod {
+ header "head.h"
+}
diff --git a/clang/test/Index/Inputs/preamble-reparse-changed-module/new-head.h b/clang/test/Index/Inputs/preamble-reparse-changed-module/new-head.h
new file mode 100644
index 000000000000..8fd2f971686f
--- /dev/null
+++ b/clang/test/Index/Inputs/preamble-reparse-changed-module/new-head.h
@@ -0,0 +1,3 @@
+ at interface I
+- (void)call_me_new;
+ at end
diff --git a/clang/test/Index/preamble-reparse-changed-module.m b/clang/test/Index/preamble-reparse-changed-module.m
new file mode 100644
index 000000000000..1c63e802ce0c
--- /dev/null
+++ b/clang/test/Index/preamble-reparse-changed-module.m
@@ -0,0 +1,18 @@
+// REQUIRES: shell
+
+// RUN: mkdir -p %t/mod
+// RUN: touch %t/empty.h
+// RUN: cp %S/Inputs/preamble-reparse-changed-module/module.modulemap %t/mod
+// RUN: cp %S/Inputs/preamble-reparse-changed-module/head.h %t/mod
+
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_EXECUTE_COMMAND="cp %S/Inputs/preamble-reparse-changed-module/new-head.h %t/mod/head.h" CINDEXTEST_EXECUTE_AFTER_TRIAL=1 \
+// RUN: c-index-test -test-load-source-reparse 3 local %s -I %t -I %t/mod -fmodules -fmodules-cache-path=%t/mcp 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning:
+
+#include "empty.h"
+ at import mod;
+
+void test(I *o) {
+ [o call_me_new];
+}
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 3eb63492071f..a32062caf889 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -24,6 +24,7 @@
#endif
extern int indextest_core_main(int argc, const char **argv);
+extern int indextest_perform_shell_execution(const char *command_line);
/******************************************************************************/
/* Utility functions. */
@@ -2095,6 +2096,8 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
enum CXErrorCode Err;
int result, i;
int trial;
+ int execute_after_trial = 0;
+ const char *execute_command = NULL;
int remap_after_trial = 0;
char *endptr = 0;
@@ -2133,12 +2136,26 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
if (checkForErrors(TU) != 0)
return -1;
+ if (getenv("CINDEXTEST_EXECUTE_COMMAND")) {
+ execute_command = getenv("CINDEXTEST_EXECUTE_COMMAND");
+ }
+ if (getenv("CINDEXTEST_EXECUTE_AFTER_TRIAL")) {
+ execute_after_trial =
+ strtol(getenv("CINDEXTEST_EXECUTE_AFTER_TRIAL"), &endptr, 10);
+ }
+
if (getenv("CINDEXTEST_REMAP_AFTER_TRIAL")) {
remap_after_trial =
strtol(getenv("CINDEXTEST_REMAP_AFTER_TRIAL"), &endptr, 10);
}
for (trial = 0; trial < trials; ++trial) {
+ if (execute_command && trial == execute_after_trial) {
+ result = indextest_perform_shell_execution(execute_command);
+ if (result != 0)
+ return result;
+ }
+
free_remapped_files(unsaved_files, num_unsaved_files);
if (parse_remapped_files_with_try(trial, argc, argv, 0,
&unsaved_files, &num_unsaved_files)) {
diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp
index ed0d99b9d199..1a4c566aa17c 100644
--- a/clang/tools/c-index-test/core_main.cpp
+++ b/clang/tools/c-index-test/core_main.cpp
@@ -13,22 +13,25 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendAction.h"
-#include "clang/Index/IndexingAction.h"
#include "clang/Index/IndexDataConsumer.h"
+#include "clang/Index/IndexingAction.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/PrettyStackTrace.h"
using namespace clang;
using namespace clang::index;
using namespace llvm;
extern "C" int indextest_core_main(int argc, const char **argv);
+extern "C" int indextest_perform_shell_execution(const char *command_line);
namespace {
@@ -359,3 +362,21 @@ int indextest_core_main(int argc, const char **argv) {
return 0;
}
+
+//===----------------------------------------------------------------------===//
+// Utility functions
+//===----------------------------------------------------------------------===//
+
+int indextest_perform_shell_execution(const char *command_line) {
+ BumpPtrAllocator Alloc;
+ llvm::StringSaver Saver(Alloc);
+ SmallVector<const char *, 4> Args;
+ llvm::cl::TokenizeGNUCommandLine(command_line, Saver, Args);
+ auto Program = llvm::sys::findProgramByName(Args[0]);
+ if (std::error_code ec = Program.getError()) {
+ llvm::errs() << "command not found: " << Args[0] << "\n";
+ return ec.value();
+ }
+ SmallVector<StringRef, 8> execArgs(Args.begin(), Args.end());
+ return llvm::sys::ExecuteAndWait(*Program, execArgs);
+}
More information about the llvm-branch-commits
mailing list