diff options
Diffstat (limited to 'lib/Basic')
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 55 | ||||
-rw-r--r-- | lib/Basic/SourceLocation.cpp | 6 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 8 |
3 files changed, 49 insertions, 20 deletions
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 16bdd4a6c2..f9e1d2bda3 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -203,11 +203,10 @@ Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const { } } -/// 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 @@ void Diagnostic::Report(DiagnosticClient* C, // 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 83c264ad0b..12a49623c6 100644 --- a/lib/Basic/SourceLocation.cpp +++ b/lib/Basic/SourceLocation.cpp @@ -79,6 +79,12 @@ const FileEntry* FullSourceLoc::getFileEntryForLoc() const { 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 d7d2c84a4c..7534ac4f26 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -75,14 +75,15 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { /// 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 SourceManager::createFileID(const ContentCache *File, 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); |