[PCH] Enhance InputFile to also include whether the file is out-of-date.

Previously we would return null for an out-of-date file. This inhibited ASTReader::ReadSLocEntry
from creating a FileID to recover gracefully in such a case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176332 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2013-03-01 03:26:04 +00:00
Родитель 7db4bb9226
Коммит 8504b7b810
3 изменённых файлов: 57 добавлений и 27 удалений

Просмотреть файл

@ -924,11 +924,10 @@ private:
/// \brief Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
typedef llvm::PointerIntPair<const FileEntry *, 1, bool> InputFile;
/// \brief Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true);
serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
bool Complain = true);
/// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take
/// into account all the necessary relocations.

Просмотреть файл

@ -55,6 +55,35 @@ struct DeclContextInfo {
unsigned NumLexicalDecls;
};
/// \brief The input file that has been loaded from this AST file, along with
/// bools indicating whether this was an overridden buffer or if it was
/// out-of-date.
class InputFile {
enum {
Overridden = 1,
OutOfDate = 2
};
llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
public:
InputFile() {}
InputFile(const FileEntry *File,
bool isOverridden = false, bool isOutOfDate = false) {
assert(!(isOverridden && isOutOfDate) &&
"an overridden cannot be out-of-date");
unsigned intVal = 0;
if (isOverridden)
intVal = Overridden;
else if (isOutOfDate)
intVal = OutOfDate;
Val.setPointerAndInt(File, intVal);
}
const FileEntry *getFile() const { return Val.getPointer(); }
bool isOverridden() const { return Val.getInt() == Overridden; }
bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
};
/// \brief Information about a module that has been loaded by the ASTReader.
///
/// Each instance of the Module class corresponds to a single AST file, which
@ -145,10 +174,8 @@ public:
/// \brief Offsets for all of the input file entries in the AST file.
const uint32_t *InputFileOffsets;
/// \brief The input files that have been loaded from this AST file, along
/// with a bool indicating whether this was an overridden buffer.
std::vector<llvm::PointerIntPair<const FileEntry *, 1, bool> >
InputFilesLoaded;
/// \brief The input files that have been loaded from this AST file.
std::vector<InputFile> InputFilesLoaded;
// === Source Locations ===

Просмотреть файл

@ -917,10 +917,13 @@ bool ASTReader::ReadSLocEntry(int ID) {
// we will also try to fail gracefully by setting up the SLocEntry.
unsigned InputID = Record[4];
InputFile IF = getInputFile(*F, InputID);
const FileEntry *File = IF.getPointer();
bool OverriddenBuffer = IF.getInt();
const FileEntry *File = IF.getFile();
bool OverriddenBuffer = IF.isOverridden();
if (!IF.getPointer())
// Note that we only check if a File was returned. If it was out-of-date
// we have complained but we will continue creating a FileID to recover
// gracefully.
if (!File)
return true;
SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]);
@ -1495,14 +1498,13 @@ void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) {
IdentifierGeneration[II] = CurrentGeneration;
}
llvm::PointerIntPair<const FileEntry *, 1, bool>
ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
// If this ID is bogus, just return an empty input file.
if (ID == 0 || ID > F.InputFilesLoaded.size())
return InputFile();
// If we've already loaded this input file, return it.
if (F.InputFilesLoaded[ID-1].getPointer())
if (F.InputFilesLoaded[ID-1].getFile())
return F.InputFilesLoaded[ID-1];
// Go find this input file.
@ -1556,17 +1558,15 @@ ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
}
return InputFile();
}
// Note that we've loaded this input file.
F.InputFilesLoaded[ID-1] = InputFile(File, Overridden);
// Check if there was a request to override the contents of the file
// that was part of the precompiled header. Overridding such a file
// can lead to problems when lexing using the source locations from the
// PCH.
SourceManager &SM = getSourceManager();
if (!Overridden && SM.isFileOverridden(File)) {
Error(diag::err_fe_pch_file_overridden, Filename);
if (Complain)
Error(diag::err_fe_pch_file_overridden, Filename);
// After emitting the diagnostic, recover by disabling the override so
// that the original file will be used.
SM.disableFileContentsOverride(File);
@ -1577,11 +1577,10 @@ ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
StoredSize, StoredTime);
}
// For an overridden file, there is nothing to validate.
if (Overridden)
return InputFile(File, Overridden);
bool IsOutOfDate = false;
if ((StoredSize != File->getSize()
// For an overridden file, there is nothing to validate.
if (!Overridden && (StoredSize != File->getSize()
#if !defined(LLVM_ON_WIN32)
// In our regression testing, the Windows file system seems to
// have inconsistent modification times that sometimes
@ -1591,11 +1590,14 @@ ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
)) {
if (Complain)
Error(diag::err_fe_pch_file_modified, Filename);
return InputFile();
IsOutOfDate = true;
}
return InputFile(File, Overridden);
InputFile IF = InputFile(File, Overridden, IsOutOfDate);
// Note that we've loaded this input file.
F.InputFilesLoaded[ID-1] = IF;
return IF;
}
}
@ -1668,9 +1670,11 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// Validate all of the input files.
if (!DisableValidation) {
bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
for (unsigned I = 0, N = Record[0]; I < N; ++I)
if (!getInputFile(F, I+1, Complain).getPointer())
for (unsigned I = 0, N = Record[0]; I < N; ++I) {
InputFile IF = getInputFile(F, I+1, Complain);
if (!IF.getFile() || IF.isOutOfDate())
return OutOfDate;
}
}
return Success;