зеркало из https://github.com/microsoft/clang-1.git
[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:
Родитель
7db4bb9226
Коммит
8504b7b810
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче