* Remove isInSystemHeader() from DiagClient, move it to SourceManager
* Move FormatError() from TextDiagnostic up to DiagClient, remove now
empty class TextDiagnostic
* Make DiagClient optional for Diagnostic
This fixes the following problems:
* -html-diags (and probably others) does now output the same set of
warnings as console clang does
* nothing crashes if one forgets to call setHeaderSearch() on
TextDiagnostic
* some code duplication is removed
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54620 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 16bdd4a..f9e1d2b 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -203,11 +203,10 @@
}
}
-/// Report - Issue the message to the client. If the client wants us to stop
-/// compilation, return true, otherwise return false. DiagID is a member of
-/// the diag::kind enum.
+/// Report - Issue the message to the client.
+/// DiagID is a member of the diag::kind enum.
void Diagnostic::Report(DiagnosticClient* C,
- FullSourceLoc Pos, unsigned DiagID,
+ FullSourceLoc Loc, unsigned DiagID,
const std::string *Strs, unsigned NumStrs,
const SourceRange *Ranges, unsigned NumRanges) {
@@ -217,33 +216,55 @@
// If the client doesn't care about this message, don't issue it.
if (DiagLevel == Diagnostic::Ignored)
return;
-
+
// Set the diagnostic client if it isn't set already.
if (!C) C = Client;
- // If this is not an error and we are in a system header, ignore it. We have
- // to check on the original class here, because we also want to ignore
- // extensions and warnings in -Werror and -pedantic-errors modes, which *map*
- // warnings/extensions to errors.
+ // If this is not an error and we are in a system header, ignore it. We
+ // have to check on the original DiagID here, because we also want to
+ // ignore extensions and warnings in -Werror and -pedantic-errors modes,
+ // which *map* warnings/extensions to errors.
if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
getBuiltinDiagClass(DiagID) != ERROR &&
- Client->isInSystemHeader(Pos))
+ Loc.isValid() && Loc.isFileID() && Loc.isInSystemHeader())
return;
if (DiagLevel >= Diagnostic::Error) {
ErrorOccurred = true;
-
- if (C == Client)
+
+ if (C != 0 && C == Client)
++NumErrors;
}
// Finally, report it.
-
- C->HandleDiagnostic(*this, DiagLevel, Pos, (diag::kind)DiagID,
- Strs, NumStrs, Ranges, NumRanges);
-
- if (C == Client)
+
+ if (C != 0)
+ C->HandleDiagnostic(*this, DiagLevel, Loc, (diag::kind)DiagID,
+ Strs, NumStrs, Ranges, NumRanges);
+
+ if (C != 0 && C == Client)
++NumDiagnostics;
}
+
DiagnosticClient::~DiagnosticClient() {}
+
+std::string DiagnosticClient::FormatDiagnostic(Diagnostic &Diags,
+ Diagnostic::Level Level,
+ diag::kind ID,
+ const std::string *Strs,
+ unsigned NumStrs) {
+ std::string Msg = Diags.getDescription(ID);
+
+ // Replace all instances of %0 in Msg with 'Extra'.
+ for (unsigned i = 0; i < Msg.size() - 1; ++i) {
+ if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
+ unsigned StrNo = Msg[i + 1] - '0';
+ Msg = std::string(Msg.begin(), Msg.begin() + i) +
+ (StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
+ std::string(Msg.begin() + i + 2, Msg.end());
+ }
+ }
+
+ return Msg;
+}
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 83c264a..12a4962 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -79,6 +79,12 @@
return SrcMgr->getFileEntryForLoc(Loc);
}
+bool FullSourceLoc::isInSystemHeader() const {
+ assert (isValid());
+ return SrcMgr->isInSystemHeader(Loc);
+}
+
+
const char * FullSourceLoc::getCharacterData() const {
assert (isValid());
return SrcMgr->getCharacterData(Loc);
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index d7d2c84..7534ac4 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -75,14 +75,15 @@
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
unsigned SourceManager::createFileID(const ContentCache *File,
- SourceLocation IncludePos) {
+ SourceLocation IncludePos,
+ bool isSysHeader) {
// If FileEnt is really large (e.g. it's a large .i file), we may not be able
// to fit an arbitrary position in the file in the FilePos field. To handle
// this, we create one FileID for each chunk of the file that fits in a
// FilePos field.
unsigned FileSize = File->Buffer->getBufferSize();
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
- FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File));
+ FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, isSysHeader));
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
"Ran out of file ID's!");
return FileIDs.size();
@@ -93,7 +94,8 @@
unsigned ChunkNo = 0;
while (1) {
- FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File));
+ FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
+ isSysHeader));
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
FileSize -= (1 << SourceLocation::FilePosBits);