forked from OSchip/llvm-project
When using a precompiled preamble, save the diagnostics produced when
creating the preamble and "replay" them when reusing the preamble. Also, fix a thinko in the copying of the preamble when building the precompiled preamble. llvm-svn: 110061
This commit is contained in:
parent
e53004b188
commit
d9a30af25b
|
@ -398,6 +398,10 @@ public:
|
||||||
unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
|
unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
|
||||||
unsigned getNumWarnings() const { return NumWarnings; }
|
unsigned getNumWarnings() const { return NumWarnings; }
|
||||||
|
|
||||||
|
void setNumWarnings(unsigned NumWarnings) {
|
||||||
|
this->NumWarnings = NumWarnings;
|
||||||
|
}
|
||||||
|
|
||||||
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
|
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
|
||||||
/// and level. If this is the first request for this diagnosic, it is
|
/// and level. If this is the first request for this diagnosic, it is
|
||||||
/// registered and created, otherwise the existing ID is returned.
|
/// registered and created, otherwise the existing ID is returned.
|
||||||
|
@ -943,7 +947,9 @@ public:
|
||||||
Diagnostic::Level getLevel() const { return Level; }
|
Diagnostic::Level getLevel() const { return Level; }
|
||||||
const FullSourceLoc &getLocation() const { return Loc; }
|
const FullSourceLoc &getLocation() const { return Loc; }
|
||||||
llvm::StringRef getMessage() const { return Message; }
|
llvm::StringRef getMessage() const { return Message; }
|
||||||
|
|
||||||
|
void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
|
||||||
|
|
||||||
typedef std::vector<CharSourceRange>::const_iterator range_iterator;
|
typedef std::vector<CharSourceRange>::const_iterator range_iterator;
|
||||||
range_iterator range_begin() const { return Ranges.begin(); }
|
range_iterator range_begin() const { return Ranges.begin(); }
|
||||||
range_iterator range_end() const { return Ranges.end(); }
|
range_iterator range_end() const { return Ranges.end(); }
|
||||||
|
|
|
@ -149,7 +149,23 @@ private:
|
||||||
/// the main file when it has been padded for use with the precompiled
|
/// the main file when it has been padded for use with the precompiled
|
||||||
/// preamble.
|
/// preamble.
|
||||||
llvm::MemoryBuffer *SavedMainFileBuffer;
|
llvm::MemoryBuffer *SavedMainFileBuffer;
|
||||||
|
|
||||||
|
/// \brief The number of warnings that occurred while parsing the preamble.
|
||||||
|
///
|
||||||
|
/// This value will be used to restore the state of the \c Diagnostic object
|
||||||
|
/// when re-using the precompiled preamble. Note that only the
|
||||||
|
/// number of warnings matters, since we will not save the preamble
|
||||||
|
/// when any errors are present.
|
||||||
|
unsigned NumWarningsInPreamble;
|
||||||
|
|
||||||
|
/// \brief The number of diagnostics that were stored when parsing
|
||||||
|
/// the precompiled preamble.
|
||||||
|
///
|
||||||
|
/// This value is used to determine how many of the stored
|
||||||
|
/// diagnostics should be retained when reparsing in the presence of
|
||||||
|
/// a precompiled preamble.
|
||||||
|
unsigned NumStoredDiagnosticsInPreamble;
|
||||||
|
|
||||||
/// \brief The group of timers associated with this translation unit.
|
/// \brief The group of timers associated with this translation unit.
|
||||||
llvm::OwningPtr<llvm::TimerGroup> TimerGroup;
|
llvm::OwningPtr<llvm::TimerGroup> TimerGroup;
|
||||||
|
|
||||||
|
|
|
@ -381,9 +381,11 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
||||||
|
|
||||||
// Clear out old caches and data.
|
// Clear out old caches and data.
|
||||||
TopLevelDecls.clear();
|
TopLevelDecls.clear();
|
||||||
StoredDiagnostics.clear();
|
|
||||||
CleanTemporaryFiles();
|
CleanTemporaryFiles();
|
||||||
PreprocessedEntitiesByFile.clear();
|
PreprocessedEntitiesByFile.clear();
|
||||||
|
|
||||||
|
if (!OverrideMainBuffer)
|
||||||
|
StoredDiagnostics.clear();
|
||||||
|
|
||||||
// Capture any diagnostics that would otherwise be dropped.
|
// Capture any diagnostics that would otherwise be dropped.
|
||||||
CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
|
CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
|
||||||
|
@ -409,6 +411,17 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
||||||
|
|
||||||
// Keep track of the override buffer;
|
// Keep track of the override buffer;
|
||||||
SavedMainFileBuffer = OverrideMainBuffer;
|
SavedMainFileBuffer = OverrideMainBuffer;
|
||||||
|
|
||||||
|
// The stored diagnostic has the old source manager in it; update
|
||||||
|
// the locations to refer into the new source manager. Since we've
|
||||||
|
// been careful to make sure that the source manager's state
|
||||||
|
// before and after are identical, so that we can reuse the source
|
||||||
|
// location itself.
|
||||||
|
for (unsigned I = 0, N = StoredDiagnostics.size(); I != N; ++I) {
|
||||||
|
FullSourceLoc Loc(StoredDiagnostics[I].getLocation(),
|
||||||
|
getSourceManager());
|
||||||
|
StoredDiagnostics[I].setLocation(Loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
|
llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
|
||||||
|
@ -430,11 +443,9 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
||||||
Act->EndSourceFile();
|
Act->EndSourceFile();
|
||||||
|
|
||||||
// Remove the overridden buffer we used for the preamble.
|
// Remove the overridden buffer we used for the preamble.
|
||||||
if (OverrideMainBuffer) {
|
if (OverrideMainBuffer)
|
||||||
PreprocessorOpts.eraseRemappedFile(
|
PreprocessorOpts.eraseRemappedFile(
|
||||||
PreprocessorOpts.remapped_file_buffer_end() - 1);
|
PreprocessorOpts.remapped_file_buffer_end() - 1);
|
||||||
PreprocessorOpts.DisablePCHValidation = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clang.takeDiagnosticClient();
|
Clang.takeDiagnosticClient();
|
||||||
|
|
||||||
|
@ -627,7 +638,7 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
NewPreamble.second.first) == 0) {
|
NewPreamble.second.first) == 0) {
|
||||||
// The preamble has not changed. We may be able to re-use the precompiled
|
// The preamble has not changed. We may be able to re-use the precompiled
|
||||||
// preamble.
|
// preamble.
|
||||||
|
|
||||||
// Check that none of the files used by the preamble have changed.
|
// Check that none of the files used by the preamble have changed.
|
||||||
bool AnyFileChanged = false;
|
bool AnyFileChanged = false;
|
||||||
|
|
||||||
|
@ -687,7 +698,19 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AnyFileChanged) {
|
if (!AnyFileChanged) {
|
||||||
// Okay! Re-use the precompiled preamble.
|
// Okay! We can re-use the precompiled preamble.
|
||||||
|
|
||||||
|
// Set the state of the diagnostic object to mimic its state
|
||||||
|
// after parsing the preamble.
|
||||||
|
getDiagnostics().Reset();
|
||||||
|
getDiagnostics().setNumWarnings(NumWarningsInPreamble);
|
||||||
|
if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble)
|
||||||
|
StoredDiagnostics.erase(
|
||||||
|
StoredDiagnostics.begin() + NumStoredDiagnosticsInPreamble,
|
||||||
|
StoredDiagnostics.end());
|
||||||
|
|
||||||
|
// Create a version of the main file buffer that is padded to
|
||||||
|
// buffer size we reserved when creating the preamble.
|
||||||
return CreatePaddedMainFileBuffer(NewPreamble.first,
|
return CreatePaddedMainFileBuffer(NewPreamble.first,
|
||||||
CreatedPreambleBuffer,
|
CreatedPreambleBuffer,
|
||||||
PreambleReservedSize,
|
PreambleReservedSize,
|
||||||
|
@ -718,6 +741,13 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
else
|
else
|
||||||
PreambleReservedSize *= 2;
|
PreambleReservedSize *= 2;
|
||||||
|
|
||||||
|
// Save the preamble text for later; we'll need to compare against it for
|
||||||
|
// subsequent reparses.
|
||||||
|
Preamble.assign(NewPreamble.first->getBufferStart(),
|
||||||
|
NewPreamble.first->getBufferStart()
|
||||||
|
+ NewPreamble.second.first);
|
||||||
|
PreambleEndsAtStartOfLine = NewPreamble.second.second;
|
||||||
|
|
||||||
llvm::MemoryBuffer *PreambleBuffer
|
llvm::MemoryBuffer *PreambleBuffer
|
||||||
= llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
|
= llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
|
||||||
FrontendOpts.Inputs[0].second);
|
FrontendOpts.Inputs[0].second);
|
||||||
|
@ -726,13 +756,6 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(),
|
memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(),
|
||||||
' ', PreambleReservedSize - Preamble.size() - 1);
|
' ', PreambleReservedSize - Preamble.size() - 1);
|
||||||
const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n';
|
const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n';
|
||||||
|
|
||||||
// Save the preamble text for later; we'll need to compare against it for
|
|
||||||
// subsequent reparses.
|
|
||||||
Preamble.assign(NewPreamble.first->getBufferStart(),
|
|
||||||
NewPreamble.first->getBufferStart()
|
|
||||||
+ NewPreamble.second.first);
|
|
||||||
PreambleEndsAtStartOfLine = NewPreamble.second.second;
|
|
||||||
|
|
||||||
// Remap the main source file to the preamble buffer.
|
// Remap the main source file to the preamble buffer.
|
||||||
llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
|
llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second);
|
||||||
|
@ -786,7 +809,7 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
|
|
||||||
// Capture any diagnostics that would otherwise be dropped.
|
// Capture any diagnostics that would otherwise be dropped.
|
||||||
CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
|
CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
|
||||||
Clang.getDiagnostics(),
|
getDiagnostics(),
|
||||||
StoredDiagnostics);
|
StoredDiagnostics);
|
||||||
|
|
||||||
// Create a file manager object to provide access to and cache the filesystem.
|
// Create a file manager object to provide access to and cache the filesystem.
|
||||||
|
@ -833,6 +856,8 @@ llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() {
|
||||||
|
|
||||||
// Keep track of the preamble we precompiled.
|
// Keep track of the preamble we precompiled.
|
||||||
PreambleFile = FrontendOpts.OutputFile;
|
PreambleFile = FrontendOpts.OutputFile;
|
||||||
|
NumStoredDiagnosticsInPreamble = StoredDiagnostics.size();
|
||||||
|
NumWarningsInPreamble = getDiagnostics().getNumWarnings();
|
||||||
|
|
||||||
// Keep track of all of the files that the source manager knows about,
|
// Keep track of all of the files that the source manager knows about,
|
||||||
// so we can verify whether they have changed or not.
|
// so we can verify whether they have changed or not.
|
||||||
|
@ -1003,7 +1028,8 @@ bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
|
||||||
OverrideMainBuffer = BuildPrecompiledPreamble();
|
OverrideMainBuffer = BuildPrecompiledPreamble();
|
||||||
|
|
||||||
// Clear out the diagnostics state.
|
// Clear out the diagnostics state.
|
||||||
getDiagnostics().Reset();
|
if (!OverrideMainBuffer)
|
||||||
|
getDiagnostics().Reset();
|
||||||
|
|
||||||
// Parse the sources
|
// Parse the sources
|
||||||
bool Result = Parse(OverrideMainBuffer);
|
bool Result = Parse(OverrideMainBuffer);
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
int bar(int);
|
inline int bar(int i) {
|
||||||
|
int *ptr = 0;
|
||||||
|
float *ptr1;
|
||||||
|
ptr = ptr1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
int wibble(int);
|
int wibble(int);
|
||||||
|
|
||||||
// RUN: %clang -x c-header -o %t.pch %S/Inputs/prefix.h
|
// RUN: %clang -x c-header -o %t.pch %S/Inputs/prefix.h
|
||||||
// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s | FileCheck %s
|
// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck %s
|
||||||
|
// RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
|
||||||
// CHECK: preamble.c:3:5: FunctionDecl=wibble:3:5 Extent=[3:5 - 3:16]
|
// CHECK: preamble.c:3:5: FunctionDecl=wibble:3:5 Extent=[3:5 - 3:16]
|
||||||
// CHECK: preamble.c:3:15: ParmDecl=:3:15 (Definition) Extent=[3:12 - 3:16]
|
// CHECK: preamble.c:3:15: ParmDecl=:3:15 (Definition) Extent=[3:12 - 3:16]
|
||||||
|
// CHECK-DIAG: preamble.h:4:7:{4:9-4:13}: warning: incompatible pointer types assigning to 'int *' from 'float *'
|
||||||
|
|
Loading…
Reference in New Issue