[cfe-commits] r63098 - in /cfe/trunk: Driver/AnalysisConsumer.cpp Driver/DependencyFile.cpp Driver/PrintPreprocessedOutput.cpp include/clang/Basic/SourceLocation.h include/clang/Basic/SourceManager.h include/clang/Driver/TextDiagnosticPrinter.h lib/AST/StmtDumper.cpp lib/Analysis/LiveVariables.cpp lib/Basic/SourceLocation.cpp lib/Basic/SourceManager.cpp lib/Driver/TextDiagnosticPrinter.cpp lib/Lex/PPMacroExpansion.cpp lib/Lex/Preprocessor.cpp test/Preprocessor/dumptokens_phyloc.c
Chris Lattner
sabre at nondot.org
Mon Jan 26 23:57:44 PST 2009
Author: lattner
Date: Tue Jan 27 01:57:44 2009
New Revision: 63098
URL: http://llvm.org/viewvc/llvm-project?rev=63098&view=rev
Log:
Introduce a new PresumedLoc class to represent the concept of a location
as reported to the user and as manipulated by #line. This is what __FILE__,
__INCLUDE_LEVEL__, diagnostics and other things should follow (but not
dependency generation!).
This patch also includes several cleanups along the way:
- SourceLocation now has a dump method, and several other places
that did similar things now use it.
- I cleaned up some code in AnalysisConsumer, but it should probably be
simplified further now that NamedDecl is better.
- TextDiagnosticPrinter is now simplified and cleaned up a bit.
This patch is a prerequisite for #line, but does not actually provide
any #line functionality.
Modified:
cfe/trunk/Driver/AnalysisConsumer.cpp
cfe/trunk/Driver/DependencyFile.cpp
cfe/trunk/Driver/PrintPreprocessedOutput.cpp
cfe/trunk/include/clang/Basic/SourceLocation.h
cfe/trunk/include/clang/Basic/SourceManager.h
cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h
cfe/trunk/lib/AST/StmtDumper.cpp
cfe/trunk/lib/Analysis/LiveVariables.cpp
cfe/trunk/lib/Basic/SourceLocation.cpp
cfe/trunk/lib/Basic/SourceManager.cpp
cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
cfe/trunk/test/Preprocessor/dumptokens_phyloc.c
Modified: cfe/trunk/Driver/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.cpp (original)
+++ cfe/trunk/Driver/AnalysisConsumer.cpp Tue Jan 27 01:57:44 2009
@@ -257,18 +257,14 @@
DisplayedFunction = true;
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(getCodeDecl())) {
+ // FIXME: Is getCodeDecl() always a named decl?
+ if (isa<FunctionDecl>(getCodeDecl()) ||
+ isa<ObjCMethodDecl>(getCodeDecl())) {
+ NamedDecl *ND = cast<NamedDecl>(getCodeDecl());
+ SourceManager &SM = getContext().getSourceManager();
llvm::cerr << "ANALYZE: "
- << getContext().getSourceManager().getSourceName(FD->getLocation())
- << ' '
- << FD->getIdentifier()->getName()
- << '\n';
- }
- else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCodeDecl())) {
- llvm::cerr << "ANALYZE (ObjC Method): "
- << getContext().getSourceManager().getSourceName(MD->getLocation())
- << " '"
- << MD->getSelector().getAsString() << "'\n";
+ << SM.getPresumedLoc(ND->getLocation()).getFilename()
+ << ' ' << ND->getNameAsString() << '\n';
}
}
Modified: cfe/trunk/Driver/DependencyFile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/DependencyFile.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/Driver/DependencyFile.cpp (original)
+++ cfe/trunk/Driver/DependencyFile.cpp Tue Jan 27 01:57:44 2009
@@ -13,6 +13,7 @@
#include "clang.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/DirectoryLookup.h"
@@ -167,8 +168,14 @@
SrcMgr::CharacteristicKind FileType) {
if (Reason != PPCallbacks::EnterFile)
return;
-
- const char *Filename = PP->getSourceManager().getSourceName(Loc);
+
+ // Depedency generation really does want to go all the way to the file entry
+ // for a source location to find out what is depended on. We do not want
+ // #line markers to affect dependency generation!
+ SourceManager &SM = PP->getSourceManager();
+
+ FileID FID = SM.getFileID(SM.getInstantiationLoc(Loc));
+ const char *Filename = SM.getFileEntryForID(FID)->getName();
if (!FileMatchesDepCriteria(Filename, FileType))
return;
Modified: cfe/trunk/Driver/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/PrintPreprocessedOutput.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/Driver/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/Driver/PrintPreprocessedOutput.cpp Tue Jan 27 01:57:44 2009
@@ -150,7 +150,7 @@
// #include directive was at.
SourceManager &SourceMgr = PP.getSourceManager();
if (Reason == PPCallbacks::EnterFile) {
- MoveToLine(SourceMgr.getIncludeLoc(Loc));
+ MoveToLine(SourceMgr.getPresumedLoc(Loc).getIncludeLoc());
} else if (Reason == PPCallbacks::SystemHeaderPragma) {
MoveToLine(Loc);
@@ -165,7 +165,7 @@
if (DisableLineMarkers) return;
CurFilename.clear();
- CurFilename += SourceMgr.getSourceName(Loc);
+ CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
Lexer::Stringify(CurFilename);
FileType = NewFileType;
@@ -540,7 +540,8 @@
const SourceManager &SourceMgr = PP.getSourceManager();
do PP.Lex(Tok);
while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
- !strcmp(SourceMgr.getSourceName(Tok.getLocation()), "<predefines>"));
+ !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
+ "<predefines>"));
while (1) {
Modified: cfe/trunk/include/clang/Basic/SourceLocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceLocation.h?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceLocation.h (original)
+++ cfe/trunk/include/clang/Basic/SourceLocation.h Tue Jan 27 01:57:44 2009
@@ -133,6 +133,8 @@
/// ReadVal - Read a SourceLocation object from Bitcode.
static SourceLocation ReadVal(llvm::Deserializer& D);
+
+ void dump(const SourceManager &SM) const;
};
inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
@@ -182,13 +184,13 @@
explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
- SourceManager& getManager() {
- assert (SrcMgr && "SourceManager is NULL.");
+ SourceManager &getManager() {
+ assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
}
- const SourceManager& getManager() const {
- assert (SrcMgr && "SourceManager is NULL.");
+ const SourceManager &getManager() const {
+ assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
}
@@ -196,7 +198,6 @@
FullSourceLoc getInstantiationLoc() const;
FullSourceLoc getSpellingLoc() const;
- FullSourceLoc getIncludeLoc() const;
unsigned getLineNumber() const;
unsigned getColumnNumber() const;
@@ -211,13 +212,11 @@
const llvm::MemoryBuffer* getBuffer() const;
- const char* getSourceName() const;
-
bool isInSystemHeader() const;
/// Prints information about this FullSourceLoc to stderr. Useful for
/// debugging.
- void dump() const;
+ void dump() const { SourceLocation::dump(*SrcMgr); }
friend inline bool
operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
@@ -231,7 +230,47 @@
}
};
-
+
+/// PresumedLoc - This class represents an unpacked "presumed" location which
+/// can be presented to the user. A 'presumed' location can be modified by
+/// #line and GNU line marker directives and is always the instantiation point
+/// of a normal location.
+///
+/// You can get a PresumedLoc from a SourceLocation with SourceManager.
+class PresumedLoc {
+ const char *Filename;
+ unsigned Line, Col;
+ SourceLocation IncludeLoc;
+public:
+ PresumedLoc() : Filename(0) {}
+ PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
+ : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
+ }
+
+ /// isInvalid - Return true if this object is invalid or uninitialized. This
+ /// occurs when created with invalid source locations or when walking off
+ /// the top of a #include stack.
+ bool isInvalid() const { return Filename == 0; }
+ bool isValid() const { return Filename != 0; }
+
+ /// getFilename - Return the presumed filename of this location. This can be
+ /// affected by #line etc.
+ const char *getFilename() const { return Filename; }
+
+ /// getLine - Return the presumed line number of this location. This can be
+ /// affected by #line etc.
+ unsigned getLine() const { return Line; }
+
+ /// getColumn - Return the presumed column number of this location. This can
+ /// not be affected by #line, but is packaged here for convenience.
+ unsigned getColumn() const { return Col; }
+
+ /// getIncludeLoc - Return the presumed include location of this location.
+ /// This can be affected by GNU linemarker directives.
+ SourceLocation getIncludeLoc() const { return IncludeLoc; }
+};
+
+
} // end namespace clang
namespace llvm {
Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Tue Jan 27 01:57:44 2009
@@ -404,14 +404,6 @@
return SourceLocation::getFileLoc(FileOffset);
}
- /// getIncludeLoc - Return the location of the #include for the specified
- /// 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 getSLocEntry(getFileID(getInstantiationLoc(ID)))
- .getFile().getIncludeLoc();
- }
-
/// Given a SourceLocation object, return the instantiation location
/// referenced by the ID.
SourceLocation getInstantiationLoc(SourceLocation Loc) const {
@@ -518,10 +510,14 @@
return getSLocEntry(FID).getFile().getFileCharacteristic();
}
- /// getSourceName - This method returns the name of the file or buffer that
- /// the SourceLocation specifies. This can be modified with #line directives,
- /// etc.
- const char *getSourceName(SourceLocation Loc) const;
+ /// getPresumedLoc - This method returns the "presumed" location of a
+ /// SourceLocation specifies. A "presumed location" can be modified by #line
+ /// or GNU line marker directives. This provides a view on the data that a
+ /// user should see in diagnostics, for example.
+ ///
+ /// Note that a presumed location is always given as the instantiation point
+ /// of an instantiation location, not at the spelling location.
+ PresumedLoc getPresumedLoc(SourceLocation Loc) const;
Modified: cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Driver/TextDiagnosticPrinter.h Tue Jan 27 01:57:44 2009
@@ -26,7 +26,7 @@
class SourceManager;
class TextDiagnosticPrinter : public DiagnosticClient {
- FullSourceLoc LastWarningLoc;
+ SourceLocation LastWarningLoc;
FullSourceLoc LastLoc;
llvm::raw_ostream &OS;
bool ShowColumn;
@@ -36,7 +36,7 @@
bool caretDiagnistics = true)
: OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics) {}
- void PrintIncludeStack(FullSourceLoc Pos);
+ void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
void HighlightRange(const SourceRange &R,
const SourceManager& SrcMgr,
Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Jan 27 01:57:44 2009
@@ -153,21 +153,26 @@
void StmtDumper::DumpLocation(SourceLocation Loc) {
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
+
+ if (SpellingLoc.isInvalid()) {
+ fprintf(stderr, "<invalid sloc>");
+ return;
+ }
// The general format we print out is filename:line:col, but we drop pieces
// that haven't changed since the last loc printed.
- const char *Filename = SM->getSourceName(SpellingLoc);
- unsigned LineNo = SM->getLineNumber(SpellingLoc);
- unsigned ColNo = SM->getColumnNumber(SpellingLoc);
- if (strcmp(Filename, LastLocFilename) != 0) {
- fprintf(stderr, "%s:%u:%u", Filename, LineNo, ColNo);
- LastLocFilename = Filename;
- LastLocLine = LineNo;
- } else if (LineNo != LastLocLine) {
- fprintf(stderr, "line:%u:%u", LineNo, ColNo);
- LastLocLine = LineNo;
+ PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
+
+ if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
+ fprintf(stderr, "%s:%u:%u", PLoc.getFilename(), PLoc.getLine(),
+ PLoc.getColumn());
+ LastLocFilename = PLoc.getFilename();
+ LastLocLine = PLoc.getLine();
+ } else if (PLoc.getLine() != LastLocLine) {
+ fprintf(stderr, "line:%u:%u", PLoc.getLine(), PLoc.getColumn());
+ LastLocLine = PLoc.getLine();
} else {
- fprintf(stderr, "col:%u", ColNo);
+ fprintf(stderr, "col:%u", PLoc.getColumn());
}
}
Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/lib/Analysis/LiveVariables.cpp Tue Jan 27 01:57:44 2009
@@ -358,13 +358,9 @@
for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
E = AD.end_decl(); I!=E; ++I)
if (V.getDeclBit(I->second)) {
- SourceLocation SpellingLoc = SM.getSpellingLoc(I->first->getLocation());
-
- fprintf(stderr, " %s <%s:%u:%u>\n",
- I->first->getIdentifier()->getName(),
- SM.getSourceName(SpellingLoc),
- SM.getLineNumber(SpellingLoc),
- SM.getColumnNumber(SpellingLoc));
+ fprintf(stderr, " %s <", I->first->getIdentifier()->getName());
+ I->first->getLocation().dump(SM);
+ fprintf(stderr, ">\n");
}
}
Modified: cfe/trunk/lib/Basic/SourceLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceLocation.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceLocation.cpp (original)
+++ cfe/trunk/lib/Basic/SourceLocation.cpp Tue Jan 27 01:57:44 2009
@@ -26,6 +26,29 @@
return SourceLocation::getFromRawEncoding(D.ReadInt());
}
+void SourceLocation::dump(const SourceManager &SM) const {
+ if (!isValid()) {
+ fprintf(stderr, "<invalid loc>");
+ return;
+ }
+
+ if (isFileID()) {
+ PresumedLoc PLoc = SM.getPresumedLoc(*this);
+
+ // The instantiation and spelling pos is identical for file locs.
+ fprintf(stderr, "%s:%d:%d",
+ PLoc.getFilename(), PLoc.getLine(), PLoc.getColumn());
+ return;
+ }
+
+ SM.getInstantiationLoc(*this).dump(SM);
+
+ fprintf(stderr, " <Spelling=");
+ SM.getSpellingLoc(*this).dump(SM);
+ fprintf(stderr, ">");
+}
+
+
void SourceRange::Emit(llvm::Serializer& S) const {
B.Emit(S);
E.Emit(S);
@@ -53,11 +76,6 @@
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
}
-FullSourceLoc FullSourceLoc::getIncludeLoc() const {
- assert(isValid());
- return FullSourceLoc(SrcMgr->getIncludeLoc(*this), *SrcMgr);
-}
-
unsigned FullSourceLoc::getLineNumber() const {
assert(isValid());
return SrcMgr->getLineNumber(*this);
@@ -89,11 +107,6 @@
return SrcMgr->getSpellingColumnNumber(*this);
}
-const char* FullSourceLoc::getSourceName() const {
- assert(isValid());
- return SrcMgr->getSourceName(*this);
-}
-
bool FullSourceLoc::isInSystemHeader() const {
assert(isValid());
return SrcMgr->isInSystemHeader(*this);
@@ -109,22 +122,3 @@
return SrcMgr->getBuffer(SrcMgr->getFileID(*this));
}
-void FullSourceLoc::dump() const {
- if (!isValid()) {
- fprintf(stderr, "Invalid Loc\n");
- return;
- }
-
- if (isFileID()) {
- // The instantiation and spelling pos is identical for file locs.
- fprintf(stderr, "File Loc from '%s': %d: %d\n",
- getSourceName(), getInstantiationLineNumber(),
- getInstantiationColumnNumber());
- } else {
- fprintf(stderr, "Macro Loc (\n Spelling: ");
- getSpellingLoc().dump();
- fprintf(stderr, " Instantiation: ");
- getInstantiationLoc().dump();
- fprintf(stderr, ")\n");
- }
-}
Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Tue Jan 27 01:57:44 2009
@@ -552,18 +552,31 @@
return LineNo;
}
-/// getSourceName - This method returns the name of the file or buffer that
-/// the SourceLocation specifies. This can be modified with #line directives,
-/// etc.
-const char *SourceManager::getSourceName(SourceLocation Loc) const {
- if (Loc.isInvalid()) return "";
+/// getPresumedLoc - This method returns the "presumed" location of a
+/// SourceLocation specifies. A "presumed location" can be modified by #line
+/// or GNU line marker directives. This provides a view on the data that a
+/// user should see in diagnostics, for example.
+///
+/// Note that a presumed location is always given as the instantiation point
+/// of an instantiation location, not at the spelling location.
+PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
+ if (Loc.isInvalid()) return PresumedLoc();
+
+ // Presumed locations are always for instantiation points.
+ Loc = getInstantiationLoc(Loc);
- const SrcMgr::ContentCache *C =
- getSLocEntry(getFileID(getSpellingLoc(Loc))).getFile().getContentCache();
+ // FIXME: Could just decompose Loc once!
+ const SrcMgr::FileInfo &FI = getSLocEntry(getFileID(Loc)).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.
- return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
+ const char *Filename =
+ C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
+
+ return PresumedLoc(Filename, getLineNumber(Loc), getColumnNumber(Loc),
+ FI.getIncludeLoc());
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Driver/TextDiagnosticPrinter.cpp Tue Jan 27 01:57:44 2009
@@ -15,28 +15,26 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;
void TextDiagnosticPrinter::
-PrintIncludeStack(FullSourceLoc Pos) {
- if (Pos.isInvalid()) return;
+PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) {
+ if (Loc.isInvalid()) return;
- Pos = Pos.getInstantiationLoc();
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
// Print out the other include frames first.
- PrintIncludeStack(Pos.getIncludeLoc());
- unsigned LineNo = Pos.getLineNumber();
+ PrintIncludeStack(PLoc.getIncludeLoc(), SM);
- OS << "In file included from " << Pos.getSourceName()
- << ':' << LineNo << ":\n";
+ OS << "In file included from " << PLoc.getFilename()
+ << ':' << PLoc.getLine() << ":\n";
}
/// 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,
+ const SourceManager &SM,
unsigned LineNo, FileID FID,
std::string &CaretLine,
const std::string &SourceLine) {
@@ -44,23 +42,21 @@
"Expect a correspondence between source and caret line!");
if (!R.isValid()) return;
- SourceLocation InstantiationStart =
- SourceMgr.getInstantiationLoc(R.getBegin());
- unsigned StartLineNo = SourceMgr.getLineNumber(InstantiationStart);
- if (StartLineNo > LineNo ||
- SourceMgr.getFileID(InstantiationStart) != FID)
+ SourceLocation Begin = SM.getInstantiationLoc(R.getBegin());
+ SourceLocation End = SM.getInstantiationLoc(R.getEnd());
+
+ unsigned StartLineNo = SM.getLineNumber(Begin);
+ if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
return; // No intersection.
- SourceLocation InstantiationEnd = SourceMgr.getInstantiationLoc(R.getEnd());
- unsigned EndLineNo = SourceMgr.getLineNumber(InstantiationEnd);
- if (EndLineNo < LineNo ||
- SourceMgr.getFileID(InstantiationEnd) != FID)
+ unsigned EndLineNo = SM.getLineNumber(End);
+ if (EndLineNo < LineNo || SM.getFileID(End) != FID)
return; // No intersection.
// Compute the column number of the start.
unsigned StartColNo = 0;
if (StartLineNo == LineNo) {
- StartColNo = SourceMgr.getInstantiationColumnNumber(R.getBegin());
+ StartColNo = SM.getColumnNumber(Begin);
if (StartColNo) --StartColNo; // Zero base the col #.
}
@@ -72,12 +68,12 @@
// Compute the column number of the end.
unsigned EndColNo = CaretLine.size();
if (EndLineNo == LineNo) {
- EndColNo = SourceMgr.getInstantiationColumnNumber(R.getEnd());
+ EndColNo = SM.getColumnNumber(End);
if (EndColNo) {
--EndColNo; // Zero base the col #.
// Add in the length of the token, so that we cover multi-char tokens.
- EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
+ EndColNo += Lexer::MeasureTokenLength(End, SM);
} else {
EndColNo = CaretLine.size();
}
@@ -99,39 +95,25 @@
void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
const DiagnosticInfo &Info) {
- unsigned LineNo = 0, ColNo = 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();
+ const SourceManager &SM = Info.getLocation().getManager();
+ unsigned ColNo = 0;
+
+ // If the location is specified, print out a file/line/col and include trace
+ // if enabled.
+ if (Info.getLocation().isValid()) {
+ PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
+ unsigned LineNo = PLoc.getLine();
// First, if this diagnostic is not in the main file, print out the
// "included from" lines.
- if (LastWarningLoc != LPos.getIncludeLoc()) {
- LastWarningLoc = LPos.getIncludeLoc();
- PrintIncludeStack(LastWarningLoc);
+ if (LastWarningLoc != PLoc.getIncludeLoc()) {
+ LastWarningLoc = PLoc.getIncludeLoc();
+ PrintIncludeStack(LastWarningLoc, SM);
}
- // Compute the column number. Rewind from the current position to the start
- // of the line.
- ColNo = LPos.getColumnNumber();
- const char *TokInstantiationPtr = LPos.getCharacterData();
- LineStart = TokInstantiationPtr-ColNo+1; // Column # is 1-based
-
- // Compute the line end. Scan forward from the error position to the end of
- // the line.
- const llvm::MemoryBuffer *Buffer = LPos.getBuffer();
- const char *BufEnd = Buffer->getBufferEnd();
- LineEnd = TokInstantiationPtr;
- while (LineEnd != BufEnd &&
- *LineEnd != '\n' && *LineEnd != '\r')
- ++LineEnd;
-
- OS << Buffer->getBufferIdentifier() << ':' << LineNo << ':';
+ // Compute the column number.
+ ColNo = PLoc.getColumn();
+ OS << PLoc.getFilename() << ':' << LineNo << ':';
if (ColNo && ShowColumn)
OS << ColNo << ':';
OS << ' ';
@@ -149,21 +131,49 @@
OS.write(OutStr.begin(), OutStr.size());
OS << '\n';
- if (CaretDiagnostics && Pos.isValid() &&
- ((LastLoc != Pos) || Info.getNumRanges())) {
+ // If caret diagnostics are enabled and we have location, we want to emit the
+ // caret. However, we only do this if the location moved from the last
+ // diagnostic, or if the diagnostic has ranges. We don't want to emit the
+ // same caret multiple times if one loc has multiple diagnostics.
+ if (CaretDiagnostics && Info.getLocation().isValid() &&
+ ((LastLoc != Info.getLocation()) || Info.getNumRanges())) {
// Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
- LastLoc = Pos;
+ LastLoc = Info.getLocation();
+
+ // Inspect the actual instantiation point of the diagnostic, we don't care
+ // about presumed locations anymore.
+ SourceLocation ILoc = SM.getInstantiationLoc(Info.getLocation());
+
+ // Get the file and line that we want to highlight. We only draw ranges
+ // that intersect this.
+ FileID ILocFID = SM.getFileID(ILoc);
+ unsigned LineNo = SM.getLineNumber(ILoc);
+
+ // Get the line of the source file. Scan from the location backward and
+ // forward to find the start/end of the line.
+
+ // Rewind from the current position to the start of the line.
+ const char *TokInstantiationPtr = SM.getCharacterData(ILoc);
+ const char *LineStart = TokInstantiationPtr-ColNo+1; // Column # is 1-based.
- // Get the line of the source file.
+ // Compute the line end. Scan forward from the error position to the end of
+ // the line.
+ const char *BufEnd = SM.getBufferData(ILocFID).second;
+ const char *LineEnd = TokInstantiationPtr;
+ while (LineEnd != BufEnd &&
+ *LineEnd != '\n' && *LineEnd != '\r')
+ ++LineEnd;
+
+ // Copy the line of code into an std::string for ease of manipulation.
std::string SourceLine(LineStart, LineEnd);
// Create a line for the caret that is filled with spaces that is the same
// length as the line of source code.
std::string CaretLine(LineEnd-LineStart, ' ');
-
+
// 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, FID,
+ HighlightRange(Info.getRange(i), SM, LineNo, ILocFID,
CaretLine, SourceLine);
// Next, insert the caret itself.
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Jan 27 01:57:44 2009
@@ -454,28 +454,37 @@
Tok.clearFlag(Token::NeedsCleaning);
if (II == Ident__LINE__) {
+ // C99 6.10.8: "__LINE__: The presumed line number (within the current
+ // source file) of the current source line (an integer constant)". This can
+ // be affected by #line.
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
// __LINE__ expands to a simple numeric value. Add a space after it so that
// it will tokenize as a number (and not run into stuff after it in the temp
// buffer).
- sprintf(TmpBuffer, "%u ",
- SourceMgr.getInstantiationLineNumber(Tok.getLocation()));
+ sprintf(TmpBuffer, "%u ", PLoc.getLine());
unsigned Length = strlen(TmpBuffer)-1;
Tok.setKind(tok::numeric_constant);
CreateString(TmpBuffer, Length+1, Tok, Tok.getLocation());
Tok.setLength(Length); // Trim off space.
} else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
- SourceLocation Loc = Tok.getLocation();
+ // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
+ // character string literal)". This can be affected by #line.
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
+ // __BASE_FILE__ is a GNU extension that returns the top of the presumed
+ // #include stack instead of the current file.
if (II == Ident__BASE_FILE__) {
Diag(Tok, diag::ext_pp_base_file);
- SourceLocation NextLoc = SourceMgr.getIncludeLoc(Loc);
+ SourceLocation NextLoc = PLoc.getIncludeLoc();
while (NextLoc.isValid()) {
- Loc = NextLoc;
- NextLoc = SourceMgr.getIncludeLoc(Loc);
+ PLoc = SourceMgr.getPresumedLoc(NextLoc);
+ NextLoc = PLoc.getIncludeLoc();
}
}
// Escape this filename. Turn '\' -> '\\' '"' -> '\"'
- std::string FN =SourceMgr.getSourceName(SourceMgr.getInstantiationLoc(Loc));
+ std::string FN = PLoc.getFilename();
FN = '"' + Lexer::Stringify(FN) + '"';
Tok.setKind(tok::string_literal);
CreateString(&FN[0], FN.size(), Tok, Tok.getLocation());
@@ -496,11 +505,14 @@
} else if (II == Ident__INCLUDE_LEVEL__) {
Diag(Tok, diag::ext_pp_include_level);
- // Compute the include depth of this token.
+ // Compute the presumed include depth of this token. This can be affected
+ // by GNU line markers.
unsigned Depth = 0;
- SourceLocation Loc = SourceMgr.getIncludeLoc(Tok.getLocation());
- for (; Loc.isValid(); ++Depth)
- Loc = SourceMgr.getIncludeLoc(Loc);
+
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+ PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+ for (; PLoc.isValid(); ++Depth)
+ PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
// __INCLUDE_LEVEL__ expands to a simple numeric value. Add a space after
// it so that it will tokenize as a number (and not run into stuff after it
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Jan 27 01:57:44 2009
@@ -142,17 +142,7 @@
}
void Preprocessor::DumpLocation(SourceLocation Loc) const {
- SourceLocation LogLoc = SourceMgr.getInstantiationLoc(Loc);
- llvm::cerr << SourceMgr.getSourceName(LogLoc) << ':'
- << SourceMgr.getLineNumber(LogLoc) << ':'
- << SourceMgr.getColumnNumber(LogLoc);
-
- SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(Loc);
- if (SpellingLoc != LogLoc) {
- llvm::cerr << " <SpellingLoc=";
- DumpLocation(SpellingLoc);
- llvm::cerr << ">";
- }
+ Loc.dump(SourceMgr);
}
void Preprocessor::DumpMacro(const MacroInfo &MI) const {
Modified: cfe/trunk/test/Preprocessor/dumptokens_phyloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/dumptokens_phyloc.c?rev=63098&r1=63097&r2=63098&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/dumptokens_phyloc.c (original)
+++ cfe/trunk/test/Preprocessor/dumptokens_phyloc.c Tue Jan 27 01:57:44 2009
@@ -1,4 +1,4 @@
-// RUN: clang -dump-tokens %s 2>&1 | grep "SpellingLoc=.*dumptokens_phyloc.c:3:20"
+// RUN: clang -dump-tokens %s 2>&1 | grep "Spelling=.*dumptokens_phyloc.c:3:20"
#define TESTPHYLOC 10
More information about the cfe-commits
mailing list