diff options
author | Chris Lattner <sabre@nondot.org> | 2009-02-04 01:55:42 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-02-04 01:55:42 +0000 |
commit | 3cd949c27c63f544a081b9a750740064ddef181b (patch) | |
tree | 4e5f393cf014c8e2e3a6e1b33a571f9972c6b106 /lib/Basic/SourceManager.cpp | |
parent | a3824c6348794788094f8afa44dc1d2cf67ba440 (diff) |
add really really trivial #line support, where #line now makes every
location below it report as coming from the #line location. For example,
with:
#line 92 "foo.h"
#warning blarg!
#warning blarg!
we now emit:
foo.h:92:2: warning: #warning blarg!
#warning blarg!
^
foo.h:92:2: warning: #warning blarg!
#warning blarg!
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63709 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Basic/SourceManager.cpp')
-rw-r--r-- | lib/Basic/SourceManager.cpp | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 0e18416314..34e7049894 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -107,8 +107,17 @@ public: ~LineTableInfo() {} unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); + const char *getFilename(unsigned ID) const { + assert(ID < FilenamesByID.size() && "Invalid FilenameID"); + return FilenamesByID[ID]->getKeyData(); + } + void AddLineNote(unsigned FID, unsigned Offset, unsigned LineNo, int FilenameID); + + /// FindNearestLineEntry - Find the line entry nearest to FID that is before + /// it. If there is no line entry before Offset in FID, return null. + const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset); }; } // namespace clang @@ -135,9 +144,31 @@ void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset, assert((Entries.empty() || Entries.back().FileOffset < Offset) && "Adding line entries out of order!"); + + // If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember that + // we are still in "foo.h". + if (FilenameID == -1 && !Entries.empty()) + FilenameID = Entries.back().FilenameID; + Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID)); } +/// FindNearestLineEntry - Find the line entry nearest to FID that is before +/// it. If there is no line entry before Offset in FID, return null. +const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID, + unsigned Offset) { + const std::vector<LineEntry> &Entries = LineEntries[FID]; + assert(!Entries.empty() && "No #line entries for this FID after all!"); + + if (Entries[0].FileOffset > Offset) return 0; + + // FIXME: Dumb linear search. + // Find the maximal element that is still before Offset. + for (unsigned i = 1, e = Entries.size(); i != e; ++i) + if (Entries[i].FileOffset > Offset) return &Entries[i-1]; + // Otherwise, all entries are before Offset. + return &Entries.back(); +} /// getLineTableFilenameID - Return the uniqued ID for the specified filename. @@ -649,16 +680,31 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile(); const SrcMgr::ContentCache *C = FI.getContentCache(); - - // To get the source name, first consult the FileEntry (if one exists) before - // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. + + // To get the source name, first consult the FileEntry (if one exists) + // before the MemBuffer as this will avoid unnecessarily paging in the + // MemBuffer. const char *Filename = C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); - - return PresumedLoc(Filename, - getLineNumber(LocInfo.first, LocInfo.second), - getColumnNumber(LocInfo.first, LocInfo.second), - FI.getIncludeLoc()); + unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second); + unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second); + SourceLocation IncludeLoc = FI.getIncludeLoc(); + + // If we have #line directives in this file, update and overwrite the physical + // location info if appropriate. + if (FI.hasLineDirectives()) { + assert(LineTable && "Can't have linetable entries without a LineTable!"); + // See if there is a #line directive before this. If so, get it. + if (const LineEntry *Entry = + LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second)) { + LineNo = Entry->LineNo; + + if (Entry->FilenameID != -1) + Filename = LineTable->getFilename(Entry->FilenameID); + } + } + + return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); } //===----------------------------------------------------------------------===// |