From: Chris Lattner Date: Wed, 4 Feb 2009 05:21:58 +0000 (+0000) Subject: propagate linemarker flags down into the the line table, currently X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9d79ebac47ffde6a1cb312f4c09b66b1b9a397fb;p=clang propagate linemarker flags down into the the line table, currently ignoring include stack push/pop info though. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63719 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index e0ed77f2dd..e24e623899 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -541,6 +541,9 @@ public: /// specified by Loc. If FilenameID is -1, it is considered to be /// unspecified. void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID); + void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, + bool IsFileEntry, bool IsFileExit, + bool IsSystemHeader, bool IsExternCHeader); //===--------------------------------------------------------------------===// // Other miscellaneous methods. diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 6381687d6e..275d520e04 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -65,13 +65,19 @@ namespace clang { struct LineEntry { /// FileOffset - The offset in this file that the line entry occurs at. unsigned FileOffset; + /// LineNo - The presumed line number of this line entry: #line 4. unsigned LineNo; + /// FilenameID - The ID of the filename identified by this line entry: /// #line 4 "foo.c". This is -1 if not specified. int FilenameID; - static LineEntry get(unsigned Offs, unsigned Line, int Filename) { + /// Flags - Set the 0 if no flags, 1 if a system header, + SrcMgr::CharacteristicKind FileKind; + + static LineEntry get(unsigned Offs, unsigned Line, int Filename, + SrcMgr::CharacteristicKind FileKind) { LineEntry E; E.FileOffset = Offs; E.LineNo = Line; @@ -121,6 +127,10 @@ public: void AddLineNote(unsigned FID, unsigned Offset, unsigned LineNo, int FilenameID); + void AddLineNote(unsigned FID, unsigned Offset, + unsigned LineNo, int FilenameID, + unsigned EntryExit, SrcMgr::CharacteristicKind FileKind); + /// FindNearestLineEntry - Find the line entry nearest to FID that is before /// it. If there is no line entry before Offset in FID, return null. @@ -152,14 +162,45 @@ 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; + SrcMgr::CharacteristicKind Kind = SrcMgr::C_User; + + if (!Entries.empty()) { + // 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) + FilenameID = Entries.back().FilenameID; + + // If we are after a line marker that switched us to system header mode, + // preserve it. + Kind = Entries.back().FileKind; + } + + Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind)); +} + +/// AddLineNote This is the same as the previous version of AddLineNote, but is +/// used for GNU line markers. If EntryExit is 0, then this doesn't change the +/// presumed #include stack. If it is 1, this is a file entry, if it is 2 then +/// this is a file exit. FileKind specifies whether this is a system header or +/// extern C system header. +void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset, + unsigned LineNo, int FilenameID, + unsigned EntryExit, + SrcMgr::CharacteristicKind FileKind) { + assert(FilenameID != -1 && "Unspecified filename should use other accessor"); + + std::vector &Entries = LineEntries[FID]; + + assert((Entries.empty() || Entries.back().FileOffset < Offset) && + "Adding line entries out of order!"); + + + // TODO: Handle EntryExit. - Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID)); + Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind)); } + /// 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, @@ -206,6 +247,46 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID); } +/// AddLineNote - Add a GNU line marker to the line table. +void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo, + int FilenameID, bool IsFileEntry, + bool IsFileExit, bool IsSystemHeader, + bool IsExternCHeader) { + // If there is no filename and no flags, this is treated just like a #line, + // which does not change the flags of the previous line marker. + if (FilenameID == -1) { + assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader && + "Can't set flags without setting the filename!"); + return AddLineNote(Loc, LineNo, FilenameID); + } + + std::pair LocInfo = getDecomposedInstantiationLoc(Loc); + const SrcMgr::FileInfo &FileInfo = getSLocEntry(LocInfo.first).getFile(); + + // Remember that this file has #line directives now if it doesn't already. + const_cast(FileInfo).setHasLineDirectives(); + + if (LineTable == 0) + LineTable = new LineTableInfo(); + + SrcMgr::CharacteristicKind FileKind; + if (IsExternCHeader) + FileKind = SrcMgr::C_ExternCSystem; + else if (IsSystemHeader) + FileKind = SrcMgr::C_System; + else + FileKind = SrcMgr::C_User; + + unsigned EntryExit = 0; + if (IsFileEntry) + EntryExit = 1; + else if (IsFileExit) + EntryExit = 2; + + LineTable->AddLineNote(LocInfo.first.ID, LocInfo.second, LineNo, FilenameID, + EntryExit, FileKind); +} + //===----------------------------------------------------------------------===// // Private 'Create' methods. diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index fa57ab3c81..15487925f5 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -693,7 +693,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, PP.Lex(FlagTok); if (FlagTok.is(tok::eom)) return false; - if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP)) + if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP)) return true; // We must have 4 if there is yet another flag. @@ -761,9 +761,11 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { IsSystemHeader, IsExternCHeader, *this)) return; } - - // FIXME: do something with the #line flag info. - SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID); + + // Create a line note with this information. + SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, + IsFileEntry, IsFileExit, + IsSystemHeader, IsExternCHeader); }