mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add CharSourceRange -- a half-open character range, which will be used in IDE
integration Motivation: libIDE clients should be simple, and they should not have to translate token-based SourceRanges to character locations. This also allows us to remove the dependency of DiagnosticConsumer on the Lexer. Now the DiagnosticEngine translates the diagnostics to CharSourceRanges and passes character-based ranges to the DiagnosticConsumer. Swift SVN r7173
This commit is contained in:
@@ -180,13 +180,12 @@ namespace swift {
|
||||
/// the DiagnosticArguments that it requires.
|
||||
class Diagnostic {
|
||||
public:
|
||||
typedef DiagnosticInfo::Range Range;
|
||||
typedef DiagnosticInfo::FixIt FixIt;
|
||||
|
||||
private:
|
||||
DiagID ID;
|
||||
SmallVector<DiagnosticArgument, 3> Args;
|
||||
SmallVector<Range, 2> Ranges;
|
||||
SmallVector<CharSourceRange, 2> Ranges;
|
||||
SmallVector<FixIt, 2> FixIts;
|
||||
|
||||
public:
|
||||
@@ -207,10 +206,10 @@ namespace swift {
|
||||
// Accessors.
|
||||
DiagID getID() const { return ID; }
|
||||
ArrayRef<DiagnosticArgument> getArgs() const { return Args; }
|
||||
ArrayRef<Range> getRanges() const { return Ranges; }
|
||||
ArrayRef<CharSourceRange> getRanges() const { return Ranges; }
|
||||
ArrayRef<FixIt> getFixIts() const { return FixIts; }
|
||||
|
||||
void addRange(Range R) {
|
||||
void addRange(CharSourceRange R) {
|
||||
Ranges.push_back(R);
|
||||
}
|
||||
|
||||
@@ -266,30 +265,37 @@ namespace swift {
|
||||
/// \brief Flush the active diagnostic to the diagnostic output engine.
|
||||
void flush();
|
||||
|
||||
/// \brief Add a range to the currently-active diagnostic.
|
||||
///
|
||||
/// Use a SourceRange for a token-based range; explicitly construct a
|
||||
/// Diagnostic::Range from two SourceLocs for a character-based range.
|
||||
InFlightDiagnostic &highlight(Diagnostic::Range R);
|
||||
/// \brief Add a token-based range to the currently-active diagnostic.
|
||||
InFlightDiagnostic &highlight(SourceRange R);
|
||||
|
||||
/// \brief Add a replacement fix-it to the currently-active diagnostic.
|
||||
///
|
||||
/// Use a SourceRange for a token-based range; explicitly construct a
|
||||
/// Diagnostic::Range from two SourceLocs for a character-based range.
|
||||
InFlightDiagnostic &fixItReplace(Diagnostic::Range R, StringRef Str);
|
||||
/// \brief Add a character-based range to the currently-active diagnostic.
|
||||
InFlightDiagnostic &highlightChars(SourceLoc Start, SourceLoc End);
|
||||
|
||||
/// \brief Add a token-based replacement fix-it to the currently-active
|
||||
/// diagnostic.
|
||||
InFlightDiagnostic &fixItReplace(SourceRange R, StringRef Str);
|
||||
|
||||
/// \brief Add a character-based replacement fix-it to the currently-active
|
||||
/// diagnostic.
|
||||
InFlightDiagnostic &fixItReplaceChars(SourceLoc Start, SourceLoc End,
|
||||
StringRef Str);
|
||||
|
||||
/// \brief Add an insertion fix-it to the currently-active diagnostic.
|
||||
InFlightDiagnostic &fixItInsert(SourceLoc L, StringRef Str) {
|
||||
return fixItReplace(Diagnostic::Range(L, L), Str);
|
||||
return fixItReplaceChars(L, L, Str);
|
||||
}
|
||||
|
||||
/// \brief Add a removal fix-it to the currently-active diagnostic.
|
||||
///
|
||||
/// Use a SourceRange for a token-based range; explicitly construct a
|
||||
/// Diagnostic::Range from two SourceLocs for a character-based range.
|
||||
InFlightDiagnostic &fixItRemove(Diagnostic::Range R) {
|
||||
/// \brief Add a token-based removal fix-it to the currently-active
|
||||
/// diagnostic.
|
||||
InFlightDiagnostic &fixItRemove(SourceRange R) {
|
||||
return fixItReplace(R, {});
|
||||
}
|
||||
|
||||
/// \brief Add a token-based removal fix-it to the currently-active
|
||||
/// diagnostic.
|
||||
InFlightDiagnostic &fixItRemoveChars(SourceLoc Start, SourceLoc End) {
|
||||
return fixItReplaceChars(Start, End, {});
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Class responsible for formatting diagnostics and presenting them
|
||||
@@ -475,22 +481,6 @@ namespace swift {
|
||||
/// \brief Retrieve the active diagnostic.
|
||||
Diagnostic &getActiveDiagnostic() { return *ActiveDiagnostic; }
|
||||
};
|
||||
|
||||
inline InFlightDiagnostic &
|
||||
InFlightDiagnostic::highlight(Diagnostic::Range R) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic().addRange(R);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline InFlightDiagnostic &
|
||||
InFlightDiagnostic::fixItReplace(Diagnostic::Range R, StringRef Str) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic().addFixIt(Diagnostic::FixIt(R, Str));
|
||||
return *this;
|
||||
}
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,42 +40,21 @@ enum class DiagnosticKind {
|
||||
/// \brief Extra information carried along with a diagnostic, which may or
|
||||
/// may not be of interest to a given diagnostic consumer.
|
||||
struct DiagnosticInfo {
|
||||
/// Represents a source range that can either be a half-open character range
|
||||
/// (like llvm::SMRange) or a closed token range (like SourceRange).
|
||||
///
|
||||
/// Diagnostics need to be able to handle both kinds of ranges.
|
||||
class Range {
|
||||
public:
|
||||
SourceLoc Start, End;
|
||||
bool IsTokenRange;
|
||||
|
||||
Range(SourceLoc S, SourceLoc E, bool TokenRange = false)
|
||||
: Start(S), End(E), IsTokenRange(TokenRange) {}
|
||||
|
||||
/// Force callers to choose whether they want a zero-length range at \p S,
|
||||
/// a one-character range at \p S, or a range consisting of the token at
|
||||
/// \p S.
|
||||
/*implicit*/ Range(SourceLoc S) = delete;
|
||||
|
||||
/*implicit*/ Range(SourceRange SR)
|
||||
: Start(SR.Start), End(SR.End), IsTokenRange(true) {}
|
||||
};
|
||||
|
||||
/// Represents a fix-it, a replacement of one range of text with another.
|
||||
class FixIt {
|
||||
DiagnosticInfo::Range Range;
|
||||
CharSourceRange Range;
|
||||
std::string Text;
|
||||
|
||||
public:
|
||||
FixIt(DiagnosticInfo::Range R, StringRef Str)
|
||||
: Range(R), Text(Str) {}
|
||||
FixIt(CharSourceRange R, StringRef Str)
|
||||
: Range(R), Text(Str) {}
|
||||
|
||||
DiagnosticInfo::Range getRange() const { return Range; }
|
||||
CharSourceRange getRange() const { return Range; }
|
||||
StringRef getText() const { return Text; }
|
||||
};
|
||||
|
||||
/// \brief Extra source ranges that are attached to the diagnostic.
|
||||
ArrayRef<Range> Ranges;
|
||||
ArrayRef<CharSourceRange> Ranges;
|
||||
|
||||
/// \brief Extra source ranges that are attached to the diagnostic.
|
||||
ArrayRef<FixIt> FixIts;
|
||||
@@ -88,7 +67,9 @@ protected:
|
||||
// we need to translate swift::SourceLoc to llvm::SMLoc.
|
||||
static llvm::SMLoc getRawLoc(SourceLoc Loc) { return Loc.Value; }
|
||||
|
||||
static llvm::SMRange getRawRange(SourceManager &SM, DiagnosticInfo::Range R);
|
||||
static llvm::SMRange getRawRange(SourceManager &SM, CharSourceRange R) {
|
||||
return llvm::SMRange(getRawLoc(R.getStart()), getRawLoc(R.getEnd()));
|
||||
}
|
||||
|
||||
static llvm::SMFixIt getRawFixIt(SourceManager &SM, DiagnosticInfo::FixIt F) {
|
||||
// FIXME: It's unfortunate that we have to copy the replacement text.
|
||||
|
||||
@@ -101,6 +101,37 @@ public:
|
||||
void dump(const SourceManager &SM) const;
|
||||
};
|
||||
|
||||
/// A half-open character-based source range.
|
||||
class CharSourceRange {
|
||||
SourceLoc Start;
|
||||
unsigned ByteLength;
|
||||
|
||||
public:
|
||||
/// \brief Constructs an invalid range.
|
||||
CharSourceRange() {}
|
||||
|
||||
/// \brief Constructs a character range which starts and ends at the
|
||||
/// specified character locations.
|
||||
CharSourceRange(SourceManager &SM, SourceLoc Start, SourceLoc End);
|
||||
|
||||
bool isValid() const { return Start.isValid(); }
|
||||
bool isInvalid() const { return Start.isInvalid(); }
|
||||
|
||||
SourceLoc getStart() const { return Start; }
|
||||
SourceLoc getEnd() const {
|
||||
if (Start.isValid())
|
||||
return Start.getAdvancedLoc(ByteLength);
|
||||
else
|
||||
return SourceLoc();
|
||||
}
|
||||
|
||||
/// \brief Return the length of this valid range in bytes. Can be zero.
|
||||
unsigned getByteLength() const {
|
||||
assert(isValid() && "length does not make sense for an invalid range");
|
||||
return ByteLength;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
@@ -107,6 +107,9 @@ public:
|
||||
/// \brief Returns the offset in bytes for the given source location.
|
||||
unsigned getLocOffsetInBuffer(SourceLoc Loc, unsigned BufferID) const;
|
||||
|
||||
/// \brief Returns the distance in bytes between the given source locations.
|
||||
unsigned getByteDistance(SourceLoc Start, SourceLoc End) const;
|
||||
|
||||
std::pair<unsigned, unsigned> getLineAndColumn(SourceLoc Loc,
|
||||
int BufferID = -1) const {
|
||||
assert(Loc.isValid());
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "swift/AST/PrintOptions.h"
|
||||
#include "swift/AST/TypeRepr.h"
|
||||
#include "swift/Basic/SourceManager.h"
|
||||
#include "swift/Parse/Lexer.h" // bad dependency
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
@@ -49,6 +50,51 @@ static StoredDiagnosticInfo StoredDiagnosticInfos[] = {
|
||||
{ DiagnosticKind::Error, "<not a diagnostic>" }
|
||||
};
|
||||
|
||||
static CharSourceRange toCharSourceRange(SourceManager &SM, SourceRange SR) {
|
||||
return CharSourceRange(SM, SR.Start, Lexer::getLocForEndOfToken(SM, SR.End));
|
||||
}
|
||||
|
||||
static CharSourceRange toCharSourceRange(SourceManager &SM, SourceLoc Start,
|
||||
SourceLoc End) {
|
||||
return CharSourceRange(SM, Start, End);
|
||||
}
|
||||
|
||||
InFlightDiagnostic &InFlightDiagnostic::highlight(SourceRange R) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic()
|
||||
.addRange(toCharSourceRange(Engine->SourceMgr, R));
|
||||
return *this;
|
||||
}
|
||||
|
||||
InFlightDiagnostic &InFlightDiagnostic::highlightChars(SourceLoc Start,
|
||||
SourceLoc End) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic()
|
||||
.addRange(toCharSourceRange(Engine->SourceMgr, Start, End));
|
||||
return *this;
|
||||
}
|
||||
|
||||
InFlightDiagnostic &InFlightDiagnostic::fixItReplace(SourceRange R,
|
||||
StringRef Str) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic().addFixIt(
|
||||
Diagnostic::FixIt(toCharSourceRange(Engine->SourceMgr, R), Str));
|
||||
return *this;
|
||||
}
|
||||
|
||||
InFlightDiagnostic &InFlightDiagnostic::fixItReplaceChars(SourceLoc Start,
|
||||
SourceLoc End,
|
||||
StringRef Str) {
|
||||
assert(IsActive && "Cannot modify an inactive diagnostic");
|
||||
if (Engine)
|
||||
Engine->getActiveDiagnostic().addFixIt(Diagnostic::FixIt(
|
||||
toCharSourceRange(Engine->SourceMgr, Start, End), Str));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void InFlightDiagnostic::flush() {
|
||||
if (!IsActive)
|
||||
return;
|
||||
@@ -373,3 +419,4 @@ void DiagnosticEngine::flushActiveDiagnostic() {
|
||||
// Reset the active diagnostic.
|
||||
ActiveDiagnostic.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/Basic/DiagnosticConsumer.h"
|
||||
#include "swift/Parse/Lexer.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@@ -24,18 +23,6 @@ using namespace swift;
|
||||
|
||||
DiagnosticConsumer::~DiagnosticConsumer() { }
|
||||
|
||||
llvm::SMRange DiagnosticConsumer::getRawRange(SourceManager &SM,
|
||||
DiagnosticInfo::Range R) {
|
||||
SourceLoc End;
|
||||
if (R.IsTokenRange)
|
||||
End = Lexer::getLocForEndOfToken(SM, R.End);
|
||||
else
|
||||
End = R.End;
|
||||
|
||||
return llvm::SMRange(getRawLoc(R.Start), getRawLoc(End));
|
||||
}
|
||||
|
||||
|
||||
void NullDiagnosticConsumer::handleDiagnostic(SourceManager &SM,
|
||||
SourceLoc Loc,
|
||||
DiagnosticKind Kind,
|
||||
|
||||
@@ -36,6 +36,19 @@ unsigned SourceManager::getLocOffsetInBuffer(SourceLoc Loc,
|
||||
return Loc.Value.getPointer() - Buffer->getBuffer().begin();
|
||||
}
|
||||
|
||||
unsigned SourceManager::getByteDistance(SourceLoc Start, SourceLoc End) const {
|
||||
#ifndef NDEBUG
|
||||
unsigned BufferID = findBufferContainingLoc(Start);
|
||||
auto *Buffer = LLVMSourceMgr.getMemoryBuffer(BufferID);
|
||||
assert(End.Value.getPointer() >= Buffer->getBuffer().begin() &&
|
||||
End.Value.getPointer() <= Buffer->getBuffer().end() &&
|
||||
"End location is not from the same buffer");
|
||||
#endif
|
||||
// When we have a rope buffer, could be implemented in terms of
|
||||
// getLocOffsetInBuffer().
|
||||
return End.Value.getPointer() - Start.Value.getPointer();
|
||||
}
|
||||
|
||||
void SourceLoc::printLineAndColumn(raw_ostream &OS,
|
||||
const SourceManager &SM) const {
|
||||
if (isInvalid()) {
|
||||
@@ -93,3 +106,12 @@ void SourceRange::dump(const SourceManager &SM) const {
|
||||
print(llvm::errs(), SM);
|
||||
}
|
||||
|
||||
CharSourceRange::CharSourceRange(SourceManager &SM, SourceLoc Start,
|
||||
SourceLoc End)
|
||||
: Start(Start) {
|
||||
assert(Start.isValid() == End.isValid() &&
|
||||
"Start and end should either both be valid or both be invalid!");
|
||||
if (Start.isValid())
|
||||
ByteLength = SM.getByteDistance(Start, End);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,14 +129,14 @@ static bool checkForFixIt(const ExpectedFixIt &Expected,
|
||||
}
|
||||
|
||||
|
||||
/// VerifyDiagnostics - After the file has been processed, check to see if we
|
||||
/// got all of the expected diagnostics and check to see if there were any
|
||||
/// unexpected ones.
|
||||
/// \brief After the file has been processed, check to see if we got all of
|
||||
/// the expected diagnostics and check to see if there were any unexpected
|
||||
/// ones.
|
||||
bool DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
||||
const SourceLoc BufferStartLoc = SM.getLocForBufferStart(BufferID);
|
||||
const llvm::MemoryBuffer &MemBuffer = *SM->getMemoryBuffer(BufferID);
|
||||
StringRef InputFile = MemBuffer.getBuffer();
|
||||
|
||||
|
||||
// Queue up all of the diagnostics, allowing us to sort them and emit them in
|
||||
// file order.
|
||||
std::vector<std::pair<const char *, std::string> > Errors;
|
||||
@@ -210,9 +210,10 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
||||
if (PrevExpectedContinuationLine)
|
||||
Expected.LineNo = PrevExpectedContinuationLine;
|
||||
else
|
||||
Expected.LineNo =
|
||||
SM->FindLineNumber(llvm::SMLoc::getFromPointer(MatchStart.data()),
|
||||
BufferID);
|
||||
Expected.LineNo = SM.getLineAndColumn(
|
||||
BufferStartLoc
|
||||
.getAdvancedLoc(MatchStart.data() - MemBuffer.getBufferStart()),
|
||||
BufferID).first;
|
||||
|
||||
// Check if the next expected diagnostic should be in the same line.
|
||||
StringRef AfterEnd = MatchStart.substr(End + strlen("}}"));
|
||||
|
||||
@@ -43,7 +43,7 @@ PrintingDiagnosticConsumer::handleDiagnostic(SourceManager &SM, SourceLoc Loc,
|
||||
|
||||
// Translate ranges.
|
||||
SmallVector<llvm::SMRange, 2> Ranges;
|
||||
for (DiagnosticInfo::Range R : Info.Ranges)
|
||||
for (auto R : Info.Ranges)
|
||||
Ranges.push_back(getRawRange(SM, R));
|
||||
|
||||
// Translate fix-its.
|
||||
|
||||
@@ -267,7 +267,7 @@ static void diagnoseEmbeddedNul(DiagnosticEngine *Diags, const char *Ptr) {
|
||||
SourceLoc NulLoc = Lexer::getSourceLoc(Ptr);
|
||||
SourceLoc NulEndLoc = Lexer::getSourceLoc(Ptr+1);
|
||||
Diags->diagnose(NulLoc, diag::lex_nul_character)
|
||||
.fixItRemove(DiagnosticInfo::Range(NulLoc, NulEndLoc));
|
||||
.fixItRemoveChars(NulLoc, NulEndLoc);
|
||||
}
|
||||
|
||||
void Lexer::skipToEndOfLine() {
|
||||
@@ -1036,8 +1036,7 @@ static const char *skipToEndOfInterpolatedExpression(const char *CurPtr,
|
||||
if (Diags)
|
||||
Diags->diagnose(Lexer::getSourceLoc(CurPtr - 1),
|
||||
diag::lex_unexpected_quote_string_interpolation)
|
||||
.highlight(Diagnostic::Range(InterpStart,
|
||||
Lexer::getSourceLoc(CurPtr-1)));
|
||||
.highlightChars(InterpStart, Lexer::getSourceLoc(CurPtr-1));
|
||||
return CurPtr-1;
|
||||
case 0:
|
||||
// If we hit EOF, we fail.
|
||||
|
||||
@@ -1309,7 +1309,7 @@ FuncDecl *Parser::parseDeclFunc(SourceLoc StaticLoc, unsigned Flags) {
|
||||
// Reject 'static' functions at global scope.
|
||||
if (StaticLoc.isValid() && !HasContainerType) {
|
||||
diagnose(Tok, diag::static_func_decl_global_scope)
|
||||
.fixItRemove(Diagnostic::Range(StaticLoc, Tok.getLoc()));
|
||||
.fixItRemoveChars(StaticLoc, Tok.getLoc());
|
||||
StaticLoc = SourceLoc();
|
||||
}
|
||||
|
||||
|
||||
@@ -467,7 +467,7 @@ NullablePtr<Expr> Parser::parseExprUnary(Diag<> Message) {
|
||||
|
||||
assert(OperEndLoc != Tok.getLoc() && "binary operator with no spaces?");
|
||||
diagnose(PreviousLoc, diag::expected_prefix_operator)
|
||||
.fixItRemove(Diagnostic::Range(OperEndLoc, Tok.getLoc()));
|
||||
.fixItRemoveChars(OperEndLoc, Tok.getLoc());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ static void checkInheritanceClause(TypeChecker &tc, Decl *decl) {
|
||||
|
||||
tc.diagnose(inherited.getSourceRange().Start,
|
||||
diag::duplicate_inheritance, inheritedTy)
|
||||
.fixItRemove(Diagnostic::Range(afterPriorLoc, afterMyEndLoc))
|
||||
.fixItRemoveChars(afterPriorLoc, afterMyEndLoc)
|
||||
.highlight(knownType->second);
|
||||
continue;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ static void checkInheritanceClause(TypeChecker &tc, Decl *decl) {
|
||||
|
||||
tc.diagnose(inherited.getSourceRange().Start,
|
||||
diag::superclass_not_first, inheritedTy)
|
||||
.fixItRemove(Diagnostic::Range(afterPriorLoc, afterMyEndLoc))
|
||||
.fixItRemoveChars(afterPriorLoc, afterMyEndLoc)
|
||||
.fixItInsert(inheritedClause[0].getSourceRange().Start,
|
||||
inheritedTy.getString() + ", ");
|
||||
|
||||
|
||||
@@ -176,12 +176,12 @@ private:
|
||||
unsigned getEmitFile(StringRef Filename);
|
||||
|
||||
/// \brief Add a source location to a record.
|
||||
void addLocToRecord(llvm::SMLoc Loc,
|
||||
void addLocToRecord(SourceLoc Loc,
|
||||
SourceManager &SM,
|
||||
StringRef Filename,
|
||||
RecordDataImpl &Record);
|
||||
|
||||
void addRangeToRecord(llvm::SMRange Range, SourceManager &SM,
|
||||
void addRangeToRecord(CharSourceRange Range, SourceManager &SM,
|
||||
StringRef Filename, RecordDataImpl &Record);
|
||||
|
||||
/// \brief Emit the message payload of a diagnostic to bitcode.
|
||||
@@ -221,11 +221,10 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(StringRef Filename) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
void SerializedDiagnosticConsumer::addLocToRecord(llvm::SMLoc Loc,
|
||||
void SerializedDiagnosticConsumer::addLocToRecord(SourceLoc Loc,
|
||||
SourceManager &SM,
|
||||
StringRef Filename,
|
||||
RecordDataImpl &Record)
|
||||
{
|
||||
RecordDataImpl &Record) {
|
||||
if (!Loc.isValid()) {
|
||||
// Emit a "sentinel" location.
|
||||
Record.push_back((unsigned)0); // File.
|
||||
@@ -236,7 +235,7 @@ void SerializedDiagnosticConsumer::addLocToRecord(llvm::SMLoc Loc,
|
||||
}
|
||||
|
||||
unsigned line, col;
|
||||
std::tie(line, col) = SM->getLineAndColumn(Loc);
|
||||
std::tie(line, col) = SM.getLineAndColumn(Loc);
|
||||
|
||||
Record.push_back(getEmitFile(Filename));
|
||||
Record.push_back(line);
|
||||
@@ -244,12 +243,12 @@ void SerializedDiagnosticConsumer::addLocToRecord(llvm::SMLoc Loc,
|
||||
Record.push_back(0);
|
||||
}
|
||||
|
||||
void SerializedDiagnosticConsumer::addRangeToRecord(llvm::SMRange Range,
|
||||
void SerializedDiagnosticConsumer::addRangeToRecord(CharSourceRange Range,
|
||||
SourceManager &SM,
|
||||
StringRef Filename,
|
||||
RecordDataImpl &Record) {
|
||||
addLocToRecord(Range.Start, SM, Filename, Record);
|
||||
addLocToRecord(Range.End, SM, Filename, Record);
|
||||
addLocToRecord(Range.getStart(), SM, Filename, Record);
|
||||
addLocToRecord(Range.getEnd(), SM, Filename, Record);
|
||||
}
|
||||
|
||||
/// \brief Map a Swift DiagosticKind to the diagnostic level expected
|
||||
@@ -461,7 +460,7 @@ emitDiagnosticMessage(SourceManager &SM,
|
||||
Record.clear();
|
||||
Record.push_back(RECORD_DIAG);
|
||||
Record.push_back(getDiagnosticLevel(Kind));
|
||||
addLocToRecord(getRawLoc(Loc), SM, D.getFilename(), Record);
|
||||
addLocToRecord(Loc, SM, D.getFilename(), Record);
|
||||
|
||||
// FIXME: Swift diagnostics currently have no category.
|
||||
Record.push_back(0);
|
||||
@@ -485,21 +484,19 @@ emitDiagnosticMessage(SourceManager &SM,
|
||||
for (const auto &R : Info.Ranges) {
|
||||
State->Record.clear();
|
||||
State->Record.push_back(RECORD_SOURCE_RANGE);
|
||||
auto RawRange = getRawRange(SM, R);
|
||||
addRangeToRecord(RawRange, SM, D.getFilename(), State->Record);
|
||||
addRangeToRecord(R, SM, D.getFilename(), State->Record);
|
||||
State->Stream.EmitRecordWithAbbrev(RangeAbbrev, State->Record);
|
||||
}
|
||||
|
||||
// Emit FixIts.
|
||||
auto FixItAbbrev = State->Abbrevs.get(RECORD_FIXIT);
|
||||
for (const auto &F : Info.FixIts) {
|
||||
auto RawFixIt = getRawFixIt(SM, F);
|
||||
if (RawFixIt.getRange().isValid()) {
|
||||
if (F.getRange().isValid()) {
|
||||
State->Record.clear();
|
||||
State->Record.push_back(RECORD_FIXIT);
|
||||
addRangeToRecord(RawFixIt.getRange(), SM, D.getFilename(), State->Record);
|
||||
State->Record.push_back(RawFixIt.getText().size());
|
||||
Stream.EmitRecordWithBlob(FixItAbbrev, Record, RawFixIt.getText());
|
||||
addRangeToRecord(F.getRange(), SM, D.getFilename(), State->Record);
|
||||
State->Record.push_back(F.getText().size());
|
||||
Stream.EmitRecordWithBlob(FixItAbbrev, Record, F.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user