diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 227313b7bfdf..4c0f0e9d462e 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -68,10 +68,10 @@ public: enum { // FileID Layout: // bit 31: 0 -> FileID, 1 -> MacroID (invalid for FileID) - // 30...17 -> FileID of source location, index into SourceManager table. - FileIDBits = 14, - // 0...16 -> Index into the chunk of the specified FileID. - FilePosBits = 32-1-FileIDBits, + // 30...17 -> ChunkID of location, index into SourceManager table. + ChunkIDBits = 14, + // 0...16 -> Index into the chunk of the specified ChunkID. + FilePosBits = 32-1-ChunkIDBits, // MacroID Layout: // bit 31: 1 -> MacroID, 0 -> FileID (invalid for MacroID) @@ -100,20 +100,20 @@ public: bool isValid() const { return ID != 0; } bool isInvalid() const { return ID == 0; } - static SourceLocation getFileLoc(unsigned FileID, unsigned FilePos) { + static SourceLocation getFileLoc(unsigned ChunkID, unsigned FilePos) { SourceLocation L; // If a FilePos is larger than (1<= ChunkSize) { - FileID += FilePos >> FilePosBits; + ChunkID += FilePos >> FilePosBits; FilePos &= ChunkSize-1; } - // FIXME: Find a way to handle out of FileID bits! Maybe MaxFileID is an + // FIXME: Find a way to handle out of ChunkID bits! Maybe MaxFileID is an // escape of some sort? - assert(FileID < (1 << FileIDBits) && "Out of fileid's"); + assert(ChunkID < (1 << ChunkIDBits) && "Out of ChunkID's"); - L.ID = (FileID << FilePosBits) | FilePos; + L.ID = (ChunkID << FilePosBits) | FilePos; return L; } @@ -138,16 +138,16 @@ public: } - /// getFileID - Return the file identifier for this SourceLocation. This - /// FileID can be used with the SourceManager object to obtain an entire + /// getChunkID - Return the chunk identifier for this SourceLocation. This + /// ChunkID can be used with the SourceManager object to obtain an entire /// include stack for a file position reference. - unsigned getFileID() const { + unsigned getChunkID() const { assert(isFileID() && "can't get the file id of a non-file sloc!"); return ID >> FilePosBits; } /// getRawFilePos - Return the byte offset from the start of the file-chunk - /// referred to by FileID. This method should not be used to get the offset + /// referred to by ChunkID. This method should not be used to get the offset /// from the start of the file, instead you should use /// SourceManager::getDecomposedFileLoc. This method will be // incorrect for large files. @@ -172,14 +172,14 @@ public: /// getFileLocWithOffset - Return a source location with the specified offset /// from this file SourceLocation. SourceLocation getFileLocWithOffset(int Offset) const { - unsigned FileID = getFileID(); + unsigned ChunkID = getChunkID(); Offset += getRawFilePos(); // Handle negative offsets correctly. while (Offset < 0) { - --FileID; + --ChunkID; Offset += ChunkSize; } - return getFileLoc(FileID, Offset); + return getFileLoc(ChunkID, Offset); } /// getRawEncoding - When a SourceLocation itself cannot be used, this returns @@ -261,6 +261,8 @@ public: return *SrcMgr; } + FileID getFileID() const; + FullSourceLoc getInstantiationLoc() const; FullSourceLoc getSpellingLoc() const; FullSourceLoc getIncludeLoc() const; diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index 4f46bad8db15..08929e39c1e5 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -350,7 +350,7 @@ public: /// SourceLocation. If this is a macro expansion, this transparently figures /// out which file includes the file being expanded into. SourceLocation getIncludeLoc(SourceLocation ID) const { - return getFIDInfo(getInstantiationLoc(ID).getFileID())->getIncludeLoc(); + return getFIDInfo(getInstantiationLoc(ID).getChunkID())->getIncludeLoc(); } /// getCharacterData - Return a pointer to the start of the specified location @@ -415,9 +415,9 @@ public: /// the specified SourceLocation, if one exists. const SrcMgr::ContentCache* getContentCacheForLoc(SourceLocation Loc) const { Loc = getSpellingLoc(Loc); - unsigned FileID = Loc.getFileID(); - assert(FileID-1 < FileIDs.size() && "Invalid FileID!"); - return FileIDs[FileID-1].getContentCache(); + unsigned ChunkID = Loc.getChunkID(); + assert(ChunkID-1 < FileIDs.size() && "Invalid FileID!"); + return FileIDs[ChunkID-1].getContentCache(); } /// getFileEntryForLoc - Return the FileEntry record for the spelling loc of @@ -447,7 +447,7 @@ public: assert(Loc.isFileID() && "Isn't a File SourceLocation"); // TODO: Add a flag "is first chunk" to SLOC. - const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID()); + const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getChunkID()); // If this file has been split up into chunks, factor in the chunk number // that the FileID references. @@ -455,9 +455,9 @@ public: unsigned Offset = Loc.getRawFilePos(); Offset += (ChunkNo << SourceLocation::FilePosBits); - assert(Loc.getFileID() >= ChunkNo && "Unexpected offset"); + assert(Loc.getChunkID() >= ChunkNo && "Unexpected offset"); - return std::make_pair(FileID::Create(Loc.getFileID()-ChunkNo), Offset); + return std::make_pair(FileID::Create(Loc.getChunkID()-ChunkNo), Offset); } /// getFullFilePos - This (efficient) method returns the offset from the start @@ -485,7 +485,8 @@ public: return getFileCharacteristic(Loc) != SrcMgr::C_User; } SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const { - return getFIDInfo(getSpellingLoc(Loc).getFileID())->getFileCharacteristic(); + return getFIDInfo(getSpellingLoc(Loc).getChunkID()) + ->getFileCharacteristic(); } SrcMgr::CharacteristicKind getFileCharacteristic(FileID FID) const { return getFIDInfo(FID)->getFileCharacteristic(); diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h index e6d570c5e3b7..550c337b50b1 100644 --- a/clang/include/clang/Driver/TextDiagnosticPrinter.h +++ b/clang/include/clang/Driver/TextDiagnosticPrinter.h @@ -40,7 +40,7 @@ public: void HighlightRange(const SourceRange &R, const SourceManager& SrcMgr, - unsigned LineNo, unsigned FileID, + unsigned LineNo, FileID FID, std::string &CaretLine, const std::string &SourceLine); diff --git a/clang/lib/Basic/SourceLocation.cpp b/clang/lib/Basic/SourceLocation.cpp index 84fac86a6df7..dcfd547eec4b 100644 --- a/clang/lib/Basic/SourceLocation.cpp +++ b/clang/lib/Basic/SourceLocation.cpp @@ -37,6 +37,12 @@ SourceRange SourceRange::ReadVal(llvm::Deserializer& D) { return SourceRange(A,B); } +FileID FullSourceLoc::getFileID() const { + assert(isValid()); + return SrcMgr->getCanonicalFileID(*this); +} + + FullSourceLoc FullSourceLoc::getInstantiationLoc() const { assert(isValid()); return FullSourceLoc(SrcMgr->getInstantiationLoc(*this), *SrcMgr); diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index b6c4ffab4db0..f793c978ccbb 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -121,7 +121,7 @@ FileID SourceManager::createFileID(const ContentCache *File, unsigned FileSize = File->getSize(); if (FileSize+1 < (1 << SourceLocation::FilePosBits)) { FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter)); - assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) && + assert(FileIDs.size() < (1 << SourceLocation::ChunkIDBits) && "Ran out of file ID's!"); return FileID::Create(FileIDs.size()); } @@ -138,7 +138,7 @@ FileID SourceManager::createFileID(const ContentCache *File, FileSize -= (1 << SourceLocation::FilePosBits); } - assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) && + assert(FileIDs.size() < (1 << SourceLocation::ChunkIDBits) && "Ran out of file ID's!"); return FileID::Create(Result); } @@ -165,7 +165,7 @@ SourceLocation SourceManager::getInstantiationLoc(SourceLocation SpellingLoc, // The instanitation point and source SpellingLoc have to exactly match to // reuse (for now). We could allow "nearby" instantiations in the future. if (LastOne.getInstantiationLoc() != InstantLoc || - LastOne.getSpellingLoc().getFileID() != SpellingLoc.getFileID()) + LastOne.getSpellingLoc().getChunkID() != SpellingLoc.getChunkID()) continue; // Check to see if the spellloc of the token came from near enough to reuse. @@ -215,7 +215,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const { /// this is significantly cheaper to compute than the line number. This returns /// zero if the column number isn't known. unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { - if (Loc.getFileID() == 0) return 0; + if (Loc.getChunkID() == 0) return 0; std::pair LocInfo = getDecomposedFileLoc(Loc); unsigned FilePos = LocInfo.second; @@ -232,7 +232,7 @@ unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { /// the SourceLocation specifies. This can be modified with #line directives, /// etc. const char *SourceManager::getSourceName(SourceLocation Loc) const { - if (Loc.getFileID() == 0) return ""; + if (Loc.getChunkID() == 0) return ""; // To get the source name, first consult the FileEntry (if one exists) before // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. @@ -290,7 +290,7 @@ static void ComputeLineNumbers(ContentCache* FI) { /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. unsigned SourceManager::getLineNumber(SourceLocation Loc) const { - if (Loc.getFileID() == 0) return 0; + if (Loc.getChunkID() == 0) return 0; ContentCache *Content; diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp index 8523723278f1..4080b748ad5a 100644 --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp @@ -36,8 +36,8 @@ PrintIncludeStack(FullSourceLoc Pos) { /// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s) /// any characters in LineNo that intersect the SourceRange. void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, - const SourceManager& SourceMgr, - unsigned LineNo, unsigned FileID, + const SourceManager &SourceMgr, + unsigned LineNo, FileID FID, std::string &CaretLine, const std::string &SourceLine) { assert(CaretLine.size() == SourceLine.size() && @@ -47,12 +47,14 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, SourceLocation InstantiationStart = SourceMgr.getInstantiationLoc(R.getBegin()); unsigned StartLineNo = SourceMgr.getLineNumber(InstantiationStart); - if (StartLineNo > LineNo || InstantiationStart.getFileID() != FileID) + if (StartLineNo > LineNo || + SourceMgr.getCanonicalFileID(InstantiationStart) != FID) return; // No intersection. SourceLocation InstantiationEnd = SourceMgr.getInstantiationLoc(R.getEnd()); unsigned EndLineNo = SourceMgr.getLineNumber(InstantiationEnd); - if (EndLineNo < LineNo || InstantiationEnd.getFileID() != FileID) + if (EndLineNo < LineNo || + SourceMgr.getCanonicalFileID(InstantiationEnd) != FID) return; // No intersection. // Compute the column number of the start. @@ -98,14 +100,14 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) { unsigned LineNo = 0, ColNo = 0; - unsigned FileID = 0; + FileID FID; const char *LineStart = 0, *LineEnd = 0; const FullSourceLoc &Pos = Info.getLocation(); if (Pos.isValid()) { FullSourceLoc LPos = Pos.getInstantiationLoc(); + FID = LPos.getFileID(); LineNo = LPos.getLineNumber(); - FileID = LPos.getFileID(); // First, if this diagnostic is not in the main file, print out the // "included from" lines. @@ -161,7 +163,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // Highlight all of the characters covered by Ranges with ~ characters. for (unsigned i = 0; i != Info.getNumRanges(); ++i) - HighlightRange(Info.getRange(i), Pos.getManager(), LineNo, FileID, + HighlightRange(Info.getRange(i), Pos.getManager(), LineNo, FID, CaretLine, SourceLine); // Next, insert the caret itself. diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 90785b5e1930..6e5402e8a375 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -321,7 +321,7 @@ static SourceLocation GetMappedTokenLoc(Preprocessor &PP, // characters come from spelling(FileLoc)+Offset. SourceLocation InstLoc = SourceMgr.getInstantiationLoc(FileLoc); SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(FileLoc); - SpellingLoc = SourceLocation::getFileLoc(SpellingLoc.getFileID(), CharNo); + SpellingLoc = SourceLocation::getFileLoc(SpellingLoc.getChunkID(), CharNo); return SourceMgr.getInstantiationLoc(SpellingLoc, InstLoc); } @@ -335,7 +335,7 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const { // the file id from FileLoc with the offset specified. unsigned CharNo = Loc-BufferStart; if (FileLoc.isFileID()) - return SourceLocation::getFileLoc(FileLoc.getFileID(), CharNo); + return SourceLocation::getFileLoc(FileLoc.getChunkID(), CharNo); // Otherwise, this is the _Pragma lexer case, which pretends that all of the // tokens are lexed from where the _Pragma was defined.