Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) { if (Loc.isInvalid()) return 0; // Use the expansion location to determine which module we're in. FullSourceLoc ExpansionLoc = Loc.getExpansionLoc(); if (!ExpansionLoc.isFileID()) return 0; const SourceManager &SrcMgr = Loc.getManager(); FileID ExpansionFileID = ExpansionLoc.getFileID(); while (const FileEntry *ExpansionFile = SrcMgr.getFileEntryForID(ExpansionFileID)) { // Find the module that owns this header (if any). if (Module *Mod = findModuleForHeader(ExpansionFile)) return Mod; // No module owns this header, so look up the inclusion chain to see if // any included header has an associated module. SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID); if (IncludeLoc.isInvalid()) return 0; ExpansionFileID = SrcMgr.getFileID(IncludeLoc); } return 0; }
static bool compareCrossTUSourceLocs(FullSourceLoc XL, FullSourceLoc YL) { std::pair<FileID, unsigned> XOffs = XL.getDecomposedLoc(); std::pair<FileID, unsigned> YOffs = YL.getDecomposedLoc(); const SourceManager &SM = XL.getManager(); std::pair<bool, bool> InSameTU = SM.isInTheSameTranslationUnit(XOffs, YOffs); if (InSameTU.first) return XL.isBeforeInTranslationUnitThan(YL); const FileEntry *XFE = SM.getFileEntryForID(XL.getSpellingLoc().getFileID()); const FileEntry *YFE = SM.getFileEntryForID(YL.getSpellingLoc().getFileID()); if (!XFE || !YFE) return XFE && !YFE; int NameCmp = XFE->getName().compare(YFE->getName()); if (NameCmp != 0) return NameCmp == -1; // Last resort: Compare raw file IDs that are possibly expansions. return XL.getFileID() < YL.getFileID(); }
/*--------------------------------------------------------------------------*/ void getAbsoluteLocation(const FullSourceLoc& lb, const FullSourceLoc& le, int64* pBegin, int64* pEnd, const LangOptions& lopt) { const SourceManager& sm = lb.getManager(); // I need to know the starting point of the file FileID f = lb.getFileID(); SourceLocation fl = sm.getLocForStartOfFile(f); FullSourceLoc e(clang::Lexer::getLocForEndOfToken(le, 0, sm, lopt), sm); const char* fstart = sm.getCharacterData(fl); const char* lbegin = sm.getCharacterData(lb); const char* lend = sm.getCharacterData(e); *pBegin = (int64)(lbegin-fstart); *pEnd = (int64)(lend-fstart); }
/// Print out the file/line/column information and include trace. /// /// This method handlen the emission of the diagnostic location information. /// This includes extracting as much location information as is present for /// the diagnostic and printing it, as well as any include stack or source /// ranges necessary. void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef<CharSourceRange> Ranges) { if (PLoc.isInvalid()) { // At least print the file name if available: FileID FID = Loc.getFileID(); if (FID.isValid()) { const FileEntry *FE = Loc.getFileEntry(); if (FE && FE->isValid()) { emitFilename(FE->getName(), Loc.getManager()); if (FE->isInPCH()) OS << " (in PCH)"; OS << ": "; } } return; } unsigned LineNo = PLoc.getLine(); if (!DiagOpts->ShowLocation) return; if (DiagOpts->ShowColors) OS.changeColor(savedColor, true); emitFilename(PLoc.getFilename(), Loc.getManager()); switch (DiagOpts->getFormat()) { case DiagnosticOptions::Clang: OS << ':' << LineNo; break; case DiagnosticOptions::MSVC: OS << '(' << LineNo; break; case DiagnosticOptions::Vi: OS << " +" << LineNo; break; } if (DiagOpts->ShowColumn) // Compute the column number. if (unsigned ColNo = PLoc.getColumn()) { if (DiagOpts->getFormat() == DiagnosticOptions::MSVC) { OS << ','; // Visual Studio 2010 or earlier expects column number to be off by one if (LangOpts.MSCompatibilityVersion && !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2012)) ColNo--; } else OS << ':'; OS << ColNo; } switch (DiagOpts->getFormat()) { case DiagnosticOptions::Clang: case DiagnosticOptions::Vi: OS << ':'; break; case DiagnosticOptions::MSVC: // MSVC2013 and before print 'file(4) : error'. MSVC2015 gets rid of the // space and prints 'file(4): error'. OS << ')'; if (LangOpts.MSCompatibilityVersion && !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) OS << ' '; OS << ": "; break; } if (DiagOpts->ShowSourceRanges && !Ranges.empty()) { FileID CaretFileID = Loc.getExpansionLoc().getFileID(); bool PrintedRange = false; for (ArrayRef<CharSourceRange>::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { // Ignore invalid ranges. if (!RI->isValid()) continue; auto &SM = Loc.getManager(); SourceLocation B = SM.getExpansionLoc(RI->getBegin()); CharSourceRange ERange = SM.getExpansionRange(RI->getEnd()); SourceLocation E = ERange.getEnd(); bool IsTokenRange = ERange.isTokenRange(); std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B); std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E); // If the start or end of the range is in another file, just discard // it. if (BInfo.first != CaretFileID || EInfo.first != CaretFileID) continue; // Add in the length of the token, so that we cover multi-char // tokens. unsigned TokSize = 0; if (IsTokenRange) TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts); FullSourceLoc BF(B, SM), EF(E, SM); OS << '{' << BF.getLineNumber() << ':' << BF.getColumnNumber() << '-' << EF.getLineNumber() << ':' << (EF.getColumnNumber() + TokSize) << '}'; PrintedRange = true; } if (PrintedRange) OS << ':'; } OS << ' '; }