summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-22 15:10:57 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-22 15:10:57 +0000
commit857953168467d789125a25b3c262d4140f16c01a (patch)
treebafd030e3fbdca86f1c53fb00744cb4c5222e61a /clang/lib
parent4f22b4b1c75f6343d580c1e9a3691dce9dc57577 (diff)
downloadbcm5719-llvm-857953168467d789125a25b3c262d4140f16c01a.tar.gz
bcm5719-llvm-857953168467d789125a25b3c262d4140f16c01a.zip
Introduce the notion of a single "delayed" diagnostic into the
Diagnostic subsystem, which is used in the rare case where we find a serious problem (i.e., an inconsistency in the file system) while we're busy formatting another diagnostic. In this case, the delayed diagnostic will be emitted after we're done with the other diagnostic. This is only to be used for fatal conditions detected at very inconvenient times, where we can neither stop the current diagnostic in flight nor can we suppress the second error. llvm-svn: 99175
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Diagnostic.cpp47
-rw-r--r--clang/lib/Basic/SourceManager.cpp17
2 files changed, 61 insertions, 3 deletions
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index f7ec873e4c1..227c175dc0c 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -222,6 +222,8 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
ArgToStringFn = DummyArgToStringFn;
ArgToStringCookie = 0;
+ DelayedDiagID = 0;
+
// Set all mappings to 'unset'.
DiagMappings BlankDiags(diag::DIAG_UPPER_LIMIT/2, 0);
DiagMappingsStack.push_back(BlankDiags);
@@ -289,6 +291,23 @@ const char *Diagnostic::getDescription(unsigned DiagID) const {
return CustomDiagInfo->getDescription(DiagID);
}
+void Diagnostic::SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1,
+ llvm::StringRef Arg2) {
+ if (DelayedDiagID)
+ return;
+
+ DelayedDiagID = DiagID;
+ DelayedDiagArg1 = Arg1;
+ DelayedDiagArg1 = Arg2;
+}
+
+void Diagnostic::ReportDelayed() {
+ Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2;
+ DelayedDiagID = 0;
+ DelayedDiagArg1.clear();
+ DelayedDiagArg2.clear();
+}
+
/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticClient.
@@ -532,6 +551,34 @@ bool Diagnostic::ProcessDiag() {
return true;
}
+bool DiagnosticBuilder::Emit() {
+ // If DiagObj is null, then its soul was stolen by the copy ctor
+ // or the user called Emit().
+ if (DiagObj == 0) return false;
+
+ // When emitting diagnostics, we set the final argument count into
+ // the Diagnostic object.
+ DiagObj->NumDiagArgs = NumArgs;
+ DiagObj->NumDiagRanges = NumRanges;
+ DiagObj->NumCodeModificationHints = NumCodeModificationHints;
+
+ // Process the diagnostic, sending the accumulated information to the
+ // DiagnosticClient.
+ bool Emitted = DiagObj->ProcessDiag();
+
+ // Clear out the current diagnostic object.
+ DiagObj->Clear();
+
+ // If there was a delayed diagnostic, emit it now.
+ if (DiagObj->DelayedDiagID)
+ DiagObj->ReportDelayed();
+
+ // This diagnostic is dead.
+ DiagObj = 0;
+
+ return Emitted;
+}
+
DiagnosticClient::~DiagnosticClient() {}
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index c34f3e25439..27cb9bebde4 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -89,15 +89,26 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
Ptr[i] = FillStr[i % FillStr.size()];
- Diag.Report(diag::err_cannot_open_file)
- << Entry->getName() << ErrorStr;
+
+ if (Diag.isDiagnosticInFlight())
+ Diag.SetDelayedDiagnostic(diag::err_cannot_open_file,
+ Entry->getName(), ErrorStr);
+ else
+ Diag.Report(diag::err_cannot_open_file)
+ << Entry->getName() << ErrorStr;
+
Buffer.setInt(true);
} else if (FileInfo.st_size != Entry->getSize() ||
FileInfo.st_mtime != Entry->getModificationTime()) {
// Check that the file's size, modification time, and inode are
// the same as in the file entry (which may have come from a
// stat cache).
- Diag.Report(diag::err_file_modified) << Entry->getName();
+ if (Diag.isDiagnosticInFlight())
+ Diag.SetDelayedDiagnostic(diag::err_file_modified,
+ Entry->getName());
+ else
+ Diag.Report(diag::err_file_modified) << Entry->getName();
+
Buffer.setInt(true);
}
}
OpenPOWER on IntegriCloud