bool operator==(const SourceLocation &a, const SourceLocation &b) { return a.line() == b.line() && a.column() == b.column() && a.offset() == b.offset() && a.fileName() == b.fileName() ; }
void PrintTo(const SourceLocation &sourceLocation, std::ostream *os) { *os << sourceLocation.filePath().constData() << ", line: " << sourceLocation.line() << ", column: "<< sourceLocation.column() << ", offset: "<< sourceLocation.offset(); }
bool CodeCompleter::hasDotAt(uint line, uint column) const { const UnsavedFile &unsavedFile = translationUnit.unsavedFile(); const SourceLocation location = translationUnit.sourceLocationAtWithoutReparsing(line, column); return unsavedFile.hasCharacterAt(location.offset(), '.'); }
unsigned SourceManager::getCol(const LREntry &range, const SourceLocation &loc, unsigned line) { if (!line) { if ((line = getLine(range, loc)) == 0) return 0; } SourceFile *file = range.getFile(); // Cached and returned lines are + 1, but the line cache starts at 0. line = line - 1; assert(line < file->lineCache()->length()); uint32_t pos = loc.offset() - range.id; uint32_t line_start = file->lineCache()->at(line); #if !defined(NDEBUG) uint32_t line_end = (line < file->lineCache()->length() - 1) ? file->lineCache()->at(line + 1) : file->length() + 1; assert(pos >= line_start && pos < line_end); #endif return pos - line_start + 1; }
void PrintTo(const SourceLocation &sourceLocation, std::ostream *os) { auto filePath = sourceLocation.filePath(); if (filePath.hasContent()) *os << filePath.constData() << ", "; *os << "line: " << sourceLocation.line() << ", column: "<< sourceLocation.column() << ", offset: "<< sourceLocation.offset(); }
FullSourceRef SourceManager::fullSourceRef(const LREntry &range, const SourceLocation &loc) { FullSourceRef ref; ref.file = range.getFile(); ref.line = getLine(range, loc); ref.col = getCol(range, loc, ref.line); ref.offset = loc.offset() - range.id; return ref; }
bool SourceManager::findLocation(const SourceLocation &loc, size_t *aIndex) { if (!loc.isSet()) return false; if (last_lookup_ < locations_.length() && locations_[last_lookup_].owns(loc)) { *aIndex = last_lookup_; return true; } // We should not allocate ids >= the next id. assert(loc.offset() < next_source_id_); // Binary search. size_t lower = 0; size_t upper = locations_.length(); while (lower < upper) { size_t index = (lower + upper) / 2; LREntry &range = locations_[index]; if (loc.offset() < range.id) { upper = index; } else if (loc.offset() > range.id + range.length() + 1) { // Note +1 for the terminal offset. lower = index + 1; } else { assert(range.owns(loc)); // Update cache. last_lookup_ = index; *aIndex = index; return true; } } // What happened? assert(false); return false; }
QDebug operator<<(QDebug dbg, const SourceLocation &location) { dbg.nospace() << location.fileName() << " [" << location.line() << ":" << location.column() << "(" << location.offset() << ")]"; return dbg.space(); }
unsigned SourceManager::getLine(const LREntry &range, const SourceLocation &loc) { SourceFile *file = range.getFile(); // Note: we don't OOM check this, since we don't oom check anything. if (!file->lineCache()) file->computeLineCache(); uint32_t pos = loc.offset() - range.id; assert(pos <= file->length()); // If the position is at end-of-file, return the last line number. LineExtents *lines = file->lineCache(); if (pos == file->length()) return lines->length(); uint32_t lower = 0; uint32_t upper = lines->length(); while (lower < upper) { uint32_t index = (lower + upper) / 2; uint32_t line_start = lines->at(index); if (pos < line_start) { upper = index; continue; } // The range should be (start, end]. uint32_t line_end = (index < lines->length() - 1) ? lines->at(index + 1) : file->length(); if (pos >= line_end) { lower = index + 1; continue; } // Either the id is the first character of a line, or before the first // character of the next line, or it should be the terminal offset. assert(pos >= line_start && pos < line_end); return index + 1; } assert(false); return 0; }
void SourceManager::getTokenHistory(const SourceLocation &aLoc, TokenHistory *history) { SourceLocation loc = aLoc; while (loc.isSet()) { size_t loc_index; if (!findLocation(loc, &loc_index)) return; const LREntry &range = locations_[loc_index]; if (loc.isInMacro()) { history->macros.append(FullMacroRef(range.getMacro(), loc.offset() - range.id)); } else { history->files.append(fullSourceRef(range, loc)); } loc = range.getParent(); } }
ClangCodeCompleteResults CodeCompleter::completeWithArrowInsteadOfDot(uint line, uint column) { ClangCodeCompleteResults results; const SourceLocation location = translationUnit.sourceLocationAtWithoutReparsing(line, column - 1); const bool replaced = translationUnit.unsavedFile().replaceAt(location.offset(), 1, Utf8StringLiteral("->")); if (replaced) { results = complete(line, column + 1, translationUnit.cxUnsavedFiles(), translationUnit.unsavedFilesCount()); if (results.hasResults()) neededCorrection_ = CompletionCorrection::DotToArrowCorrection; } return results; }