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.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63098 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 8eada60..a517b1d 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -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
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index e6bf177..48fdd68 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -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 {