[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