本文整理汇总了C++中SourceColumnMap::byteToContainingColumn方法的典型用法代码示例。如果您正苦于以下问题:C++ SourceColumnMap::byteToContainingColumn方法的具体用法?C++ SourceColumnMap::byteToContainingColumn怎么用?C++ SourceColumnMap::byteToContainingColumn使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SourceColumnMap
的用法示例。
在下文中一共展示了SourceColumnMap::byteToContainingColumn方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: buildFixItInsertionLine
static std::string buildFixItInsertionLine(unsigned LineNo,
const SourceColumnMap &map,
ArrayRef<FixItHint> Hints,
const SourceManager &SM,
const DiagnosticOptions *DiagOpts) {
std::string FixItInsertionLine;
if (Hints.empty() || !DiagOpts->ShowFixits)
return FixItInsertionLine;
unsigned PrevHintEndCol = 0;
for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
I != E; ++I) {
if (!I->CodeToInsert.empty()) {
// We have an insertion hint. Determine whether the inserted
// code contains no newlines and is on the same line as the caret.
std::pair<FileID, unsigned> HintLocInfo
= SM.getDecomposedExpansionLoc(I->RemoveRange.getBegin());
if (LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) &&
StringRef(I->CodeToInsert).find_first_of("\n\r") == StringRef::npos) {
// Insert the new code into the line just below the code
// that the user wrote.
// Note: When modifying this function, be very careful about what is a
// "column" (printed width, platform-dependent) and what is a
// "byte offset" (SourceManager "column").
unsigned HintByteOffset
= SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1;
// The hint must start inside the source or right at the end
assert(HintByteOffset < static_cast<unsigned>(map.bytes())+1);
unsigned HintCol = map.byteToContainingColumn(HintByteOffset);
// If we inserted a long previous hint, push this one forwards, and add
// an extra space to show that this is not part of the previous
// completion. This is sort of the best we can do when two hints appear
// to overlap.
//
// Note that if this hint is located immediately after the previous
// hint, no space will be added, since the location is more important.
if (HintCol < PrevHintEndCol)
HintCol = PrevHintEndCol + 1;
// FIXME: This function handles multibyte characters in the source, but
// not in the fixits. This assertion is intended to catch unintended
// use of multibyte characters in fixits. If we decide to do this, we'll
// have to track separate byte widths for the source and fixit lines.
assert((size_t)llvm::sys::locale::columnWidth(I->CodeToInsert) ==
I->CodeToInsert.size());
// This relies on one byte per column in our fixit hints.
// This should NOT use HintByteOffset, because the source might have
// Unicode characters in earlier columns.
unsigned LastColumnModified = HintCol + I->CodeToInsert.size();
if (LastColumnModified > FixItInsertionLine.size())
FixItInsertionLine.resize(LastColumnModified, ' ');
std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(),
FixItInsertionLine.begin() + HintCol);
PrevHintEndCol = LastColumnModified;
} else {
FixItInsertionLine.clear();
break;
}
}
}
expandTabs(FixItInsertionLine, DiagOpts->TabStop);
return FixItInsertionLine;
}
示例2: emitSnippetAndCaret
/// \brief Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
///
/// \param Loc The location for the caret.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void TextDiagnostic::emitSnippetAndCaret(
SourceLocation Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
assert(!Loc.isInvalid() && "must have a valid source location here");
assert(Loc.isFileID() && "must have a file location here");
// If caret diagnostics are enabled and we have location, we want to
// emit the caret. However, we only do this if the location moved
// from the last diagnostic, if the last diagnostic was a note that
// was part of a different warning or error diagnostic, or if the
// diagnostic has ranges. We don't want to emit the same caret
// multiple times if one loc has multiple diagnostics.
if (!DiagOpts->ShowCarets)
return;
if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
(LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
return;
// Decompose the location into a FID/Offset pair.
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
FileID FID = LocInfo.first;
unsigned FileOffset = LocInfo.second;
// Get information about the buffer it points into.
bool Invalid = false;
const char *BufStart = SM.getBufferData(FID, &Invalid).data();
if (Invalid)
return;
unsigned LineNo = SM.getLineNumber(FID, FileOffset);
unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
// Rewind from the current position to the start of the line.
const char *TokPtr = BufStart+FileOffset;
const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.
// Compute the line end. Scan forward from the error position to the end of
// the line.
const char *LineEnd = TokPtr;
while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
++LineEnd;
// Copy the line of code into an std::string for ease of manipulation.
std::string SourceLine(LineStart, LineEnd);
// Create a line for the caret that is filled with spaces that is the same
// length as the line of source code.
std::string CaretLine(LineEnd-LineStart, ' ');
const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);
// Highlight all of the characters covered by Ranges with ~ characters.
for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
E = Ranges.end();
I != E; ++I)
highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts);
// Next, insert the caret itself.
ColNo = sourceColMap.byteToContainingColumn(ColNo-1);
if (CaretLine.size()<ColNo+1)
CaretLine.resize(ColNo+1, ' ');
CaretLine[ColNo] = '^';
std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
sourceColMap,
Hints, SM,
DiagOpts.getPtr());
// If the source line is too long for our terminal, select only the
// "interesting" source region within that line.
unsigned Columns = DiagOpts->MessageLength;
if (Columns)
selectInterestingSourceRegion(SourceLine, CaretLine, FixItInsertionLine,
Columns, sourceColMap);
// If we are in -fdiagnostics-print-source-range-info mode, we are trying
// to produce easily machine parsable output. Add a space before the
// source line and the caret to make it trivial to tell the main diagnostic
// line from what the user is intended to see.
if (DiagOpts->ShowSourceRanges) {
SourceLine = ' ' + SourceLine;
CaretLine = ' ' + CaretLine;
}
// Finally, remove any blank spaces from the end of CaretLine.
while (CaretLine[CaretLine.size()-1] == ' ')
CaretLine.erase(CaretLine.end()-1);
// Emit what we have computed.
emitSnippet(SourceLine);
//.........这里部分代码省略.........
示例3: highlightRange
/// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo.
static void highlightRange(const CharSourceRange &R,
unsigned LineNo, FileID FID,
const SourceColumnMap &map,
std::string &CaretLine,
const SourceManager &SM,
const LangOptions &LangOpts) {
if (!R.isValid()) return;
SourceLocation Begin = R.getBegin();
SourceLocation End = R.getEnd();
unsigned StartLineNo = SM.getExpansionLineNumber(Begin);
if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
return; // No intersection.
unsigned EndLineNo = SM.getExpansionLineNumber(End);
if (EndLineNo < LineNo || SM.getFileID(End) != FID)
return; // No intersection.
// Compute the column number of the start.
unsigned StartColNo = 0;
if (StartLineNo == LineNo) {
StartColNo = SM.getExpansionColumnNumber(Begin);
if (StartColNo) --StartColNo; // Zero base the col #.
}
// Compute the column number of the end.
unsigned EndColNo = map.getSourceLine().size();
if (EndLineNo == LineNo) {
EndColNo = SM.getExpansionColumnNumber(End);
if (EndColNo) {
--EndColNo; // Zero base the col #.
// Add in the length of the token, so that we cover multi-char tokens if
// this is a token range.
if (R.isTokenRange())
EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts);
} else {
EndColNo = CaretLine.size();
}
}
assert(StartColNo <= EndColNo && "Invalid range!");
// Check that a token range does not highlight only whitespace.
if (R.isTokenRange()) {
// Pick the first non-whitespace column.
while (StartColNo < map.getSourceLine().size() &&
(map.getSourceLine()[StartColNo] == ' ' ||
map.getSourceLine()[StartColNo] == '\t'))
StartColNo = map.startOfNextColumn(StartColNo);
// Pick the last non-whitespace column.
if (EndColNo > map.getSourceLine().size())
EndColNo = map.getSourceLine().size();
while (EndColNo-1 &&
(map.getSourceLine()[EndColNo-1] == ' ' ||
map.getSourceLine()[EndColNo-1] == '\t'))
EndColNo = map.startOfPreviousColumn(EndColNo);
// If the start/end passed each other, then we are trying to highlight a
// range that just exists in whitespace, which must be some sort of other
// bug.
assert(StartColNo <= EndColNo && "Trying to highlight whitespace??");
}
assert(StartColNo <= map.getSourceLine().size() && "Invalid range!");
assert(EndColNo <= map.getSourceLine().size() && "Invalid range!");
// Fill the range with ~'s.
StartColNo = map.byteToContainingColumn(StartColNo);
EndColNo = map.byteToContainingColumn(EndColNo);
assert(StartColNo <= EndColNo && "Invalid range!");
if (CaretLine.size() < EndColNo)
CaretLine.resize(EndColNo,' ');
std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~');
}
示例4: emitSnippetAndCaret
/// Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
///
/// \param Loc The location for the caret.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
void TextDiagnostic::emitSnippetAndCaret(
FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges, ArrayRef<FixItHint> Hints) {
assert(Loc.isValid() && "must have a valid source location here");
assert(Loc.isFileID() && "must have a file location here");
// If caret diagnostics are enabled and we have location, we want to
// emit the caret. However, we only do this if the location moved
// from the last diagnostic, if the last diagnostic was a note that
// was part of a different warning or error diagnostic, or if the
// diagnostic has ranges. We don't want to emit the same caret
// multiple times if one loc has multiple diagnostics.
if (!DiagOpts->ShowCarets)
return;
if (Loc == LastLoc && Ranges.empty() && Hints.empty() &&
(LastLevel != DiagnosticsEngine::Note || Level == LastLevel))
return;
// Decompose the location into a FID/Offset pair.
std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedLoc();
FileID FID = LocInfo.first;
const SourceManager &SM = Loc.getManager();
// Get information about the buffer it points into.
bool Invalid = false;
StringRef BufData = Loc.getBufferData(&Invalid);
if (Invalid)
return;
unsigned CaretLineNo = Loc.getLineNumber();
unsigned CaretColNo = Loc.getColumnNumber();
// Arbitrarily stop showing snippets when the line is too long.
static const size_t MaxLineLengthToPrint = 4096;
if (CaretColNo > MaxLineLengthToPrint)
return;
// Find the set of lines to include.
const unsigned MaxLines = DiagOpts->SnippetLineLimit;
std::pair<unsigned, unsigned> Lines = {CaretLineNo, CaretLineNo};
for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
E = Ranges.end();
I != E; ++I)
if (auto OptionalRange = findLinesForRange(*I, FID, SM))
Lines = maybeAddRange(Lines, *OptionalRange, MaxLines);
for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; ++LineNo) {
const char *BufStart = BufData.data();
const char *BufEnd = BufStart + BufData.size();
// Rewind from the current position to the start of the line.
const char *LineStart =
BufStart +
SM.getDecomposedLoc(SM.translateLineCol(FID, LineNo, 1)).second;
if (LineStart == BufEnd)
break;
// Compute the line end.
const char *LineEnd = LineStart;
while (*LineEnd != '\n' && *LineEnd != '\r' && LineEnd != BufEnd)
++LineEnd;
// Arbitrarily stop showing snippets when the line is too long.
// FIXME: Don't print any lines in this case.
if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
return;
// Trim trailing null-bytes.
StringRef Line(LineStart, LineEnd - LineStart);
while (!Line.empty() && Line.back() == '\0' &&
(LineNo != CaretLineNo || Line.size() > CaretColNo))
Line = Line.drop_back();
// Copy the line of code into an std::string for ease of manipulation.
std::string SourceLine(Line.begin(), Line.end());
// Build the byte to column map.
const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop);
// Create a line for the caret that is filled with spaces that is the same
// number of columns as the line of source code.
std::string CaretLine(sourceColMap.columns(), ' ');
// Highlight all of the characters covered by Ranges with ~ characters.
for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
E = Ranges.end();
I != E; ++I)
highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts);
// Next, insert the caret itself.
if (CaretLineNo == LineNo) {
CaretColNo = sourceColMap.byteToContainingColumn(CaretColNo - 1);
if (CaretLine.size() < CaretColNo + 1)
//.........这里部分代码省略.........