serialized diagnostics: implement full deserialization of clang diagnostics via the libclang API.
I've tested it on simple cases and it works. Test cases to follow as well as a few tweaks.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144269 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 5984567..974ec53 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/Version.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Frontend/SerializedDiagnosticPrinter.h"
using namespace clang;
@@ -47,7 +48,8 @@
class SDiagsWriter : public DiagnosticConsumer {
public:
SDiagsWriter(DiagnosticsEngine &diags, llvm::raw_ostream *os)
- : Stream(Buffer), OS(os), Diags(diags), inNonNoteDiagnostic(false)
+ : LangOpts(0), Stream(Buffer), OS(os), Diags(diags),
+ inNonNoteDiagnostic(false)
{
EmitPreamble();
};
@@ -59,6 +61,11 @@
void EndSourceFile();
+ void BeginSourceFile(const LangOptions &LO,
+ const Preprocessor *PP) {
+ LangOpts = &LO;
+ }
+
DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
// It makes no sense to clone this.
return 0;
@@ -88,7 +95,8 @@
unsigned getEmitFile(SourceLocation Loc);
/// \brief Add SourceLocation information the specified record.
- void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record);
+ void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
+ unsigned TokSize = 0);
/// \brief Add CharSourceRange information the specified record.
void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record);
@@ -96,6 +104,8 @@
/// \brief The version of the diagnostics file.
enum { Version = 1 };
+ const LangOptions *LangOpts;
+
/// \brief The byte buffer for the serialized content.
std::vector<unsigned char> Buffer;
@@ -181,13 +191,14 @@
}
void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
- RecordDataImpl &Record) {
+ RecordDataImpl &Record,
+ unsigned TokSize) {
if (Loc.isInvalid()) {
// Emit a "sentinel" location.
- Record.push_back((unsigned) 0); // File.
- Record.push_back(~(unsigned)0); // Line.
- Record.push_back(~(unsigned)0); // Column.
- Record.push_back(~(unsigned)0); // Offset.
+ Record.push_back((unsigned)0); // File.
+ Record.push_back((unsigned)0); // Line.
+ Record.push_back((unsigned)0); // Column.
+ Record.push_back((unsigned)0); // Offset.
return;
}
@@ -195,7 +206,7 @@
Loc = SM.getSpellingLoc(Loc);
Record.push_back(getEmitFile(Loc));
Record.push_back(SM.getSpellingLineNumber(Loc));
- Record.push_back(SM.getSpellingColumnNumber(Loc));
+ Record.push_back(SM.getSpellingColumnNumber(Loc)+TokSize);
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
FileID FID = LocInfo.first;
@@ -206,7 +217,13 @@
void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
RecordDataImpl &Record) {
AddLocToRecord(Range.getBegin(), Record);
- AddLocToRecord(Range.getEnd(), Record);
+ unsigned TokSize = 0;
+ if (Range.isTokenRange())
+ TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
+ Diags.getSourceManager(),
+ *LangOpts);
+
+ AddLocToRecord(Range.getEnd(), Record, TokSize);
}
unsigned SDiagsWriter::getEmitFile(SourceLocation Loc) {