track "just a little more" location information for macro instantiations.
Now instead of just tracking the expansion history, also track the full
range of the macro that got replaced.  For object-like macros, this doesn't
change anything.  For _Pragma and function-like macros, this means we track
the locations of the ')'.

This is required for PR3579 because apparently GCC uses the line of the ')'
of a function-like macro as the location to expand __LINE__ to.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64601 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index e023a91..71bda5b 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -352,7 +352,7 @@
   
   // Use up FileID #0 as an invalid instantiation.
   NextOffset = 0;
-  createInstantiationLoc(SourceLocation(), SourceLocation(), 1);
+  createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
 }
 
 /// getOrCreateContentCache - Create or return a cached ContentCache for the
@@ -418,11 +418,11 @@
 /// that a token from SpellingLoc should actually be referenced from
 /// InstantiationLoc.
 SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
-                                                     SourceLocation InstantLoc,
+                                                     SourceLocation ILocStart,
+                                                     SourceLocation ILocEnd,
                                                      unsigned TokLength) {
-  SLocEntryTable.push_back(SLocEntry::get(NextOffset, 
-                                          InstantiationInfo::get(InstantLoc,
-                                                                 SpellingLoc)));
+  InstantiationInfo II = InstantiationInfo::get(ILocStart,ILocEnd, SpellingLoc);
+  SLocEntryTable.push_back(SLocEntry::get(NextOffset, II));
   assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
   NextOffset += TokLength+1;
   return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
@@ -543,7 +543,8 @@
 getInstantiationLocSlowCase(SourceLocation Loc) const {
   do {
     std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
-    Loc =getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc();
+    Loc = getSLocEntry(LocInfo.first).getInstantiation()
+                   .getInstantiationLocStart();
     Loc = Loc.getFileLocWithOffset(LocInfo.second);
   } while (!Loc.isFileID());
 
@@ -568,7 +569,7 @@
   FileID FID;
   SourceLocation Loc;
   do {
-    Loc = E->getInstantiation().getInstantiationLoc();
+    Loc = E->getInstantiation().getInstantiationLocStart();
     
     FID = getFileID(Loc);
     E = &getSLocEntry(FID);
@@ -596,6 +597,16 @@
   return std::make_pair(FID, Offset);
 }
 
+/// getImmediateInstantiationRange - Loc is required to be an instantiation
+/// location.  Return the start/end of the instantiation information.
+std::pair<SourceLocation,SourceLocation>
+SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const {
+  assert(Loc.isMacroID() && "Not an instantiation loc!");
+  const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation();
+  return II.getInstantiationLocRange();
+}
+
+
 
 //===----------------------------------------------------------------------===//
 // Queries about the code at a SourceLocation.
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 72715c9..5f32522 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -151,7 +151,8 @@
 /// out of the critical path of the lexer!
 ///
 Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc, 
-                                 SourceLocation InstantiationLoc,
+                                 SourceLocation InstantiationLocStart,
+                                 SourceLocation InstantiationLocEnd,
                                  unsigned TokLen, Preprocessor &PP) {
   SourceManager &SM = PP.getSourceManager();
 
@@ -170,7 +171,8 @@
   // Set the SourceLocation with the remapping information.  This ensures that
   // GetMappedTokenLoc will remap the tokens as they are lexed.
   L->FileLoc = SM.createInstantiationLoc(SM.getLocForStartOfFile(SpellingFID),
-                                         InstantiationLoc, TokLen);
+                                         InstantiationLocStart,
+                                         InstantiationLocEnd, TokLen);
   
   // Ensure that the lexer thinks it is inside a directive, so that end \n will
   // return an EOM token.
@@ -315,16 +317,24 @@
 static SourceLocation GetMappedTokenLoc(Preprocessor &PP,
                                         SourceLocation FileLoc,
                                         unsigned CharNo, unsigned TokLen) {
+  assert(FileLoc.isMacroID() && "Must be an instantiation");
+  
   // Otherwise, we're lexing "mapped tokens".  This is used for things like
   // _Pragma handling.  Combine the instantiation location of FileLoc with the
   // spelling location.
-  SourceManager &SourceMgr = PP.getSourceManager();
+  SourceManager &SM = PP.getSourceManager();
   
   // Create a new SLoc which is expanded from Instantiation(FileLoc) but whose
   // characters come from spelling(FileLoc)+Offset.
-  SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(FileLoc);
+  SourceLocation SpellingLoc = SM.getSpellingLoc(FileLoc);
   SpellingLoc = SpellingLoc.getFileLocWithOffset(CharNo);
-  return SourceMgr.createInstantiationLoc(SpellingLoc, FileLoc, TokLen);
+  
+  // Figure out the expansion loc range, which is the range covered by the
+  // original _Pragma(...) sequence.
+  std::pair<SourceLocation,SourceLocation> II =
+    SM.getImmediateInstantiationRange(FileLoc);
+  
+  return SM.createInstantiationLoc(SpellingLoc, II.first, II.second, TokLen);
 }
 
 /// getSourceLocation - Return a source location identifier for the specified
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index ec3447a..13e6126 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -127,15 +127,16 @@
 
 /// EnterMacro - Add a Macro to the top of the include stack and start lexing
 /// tokens from it instead of the current buffer.
-void Preprocessor::EnterMacro(Token &Tok, MacroArgs *Args) {
+void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
+                              MacroArgs *Args) {
   PushIncludeMacroStack();
   CurDirLookup = 0;
   
   if (NumCachedTokenLexers == 0) {
-    CurTokenLexer.reset(new TokenLexer(Tok, Args, *this));
+    CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Args, *this));
   } else {
     CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]);
-    CurTokenLexer->Init(Tok, Args);
+    CurTokenLexer->Init(Tok, ILEnd, Args);
   }
 }
 
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 7767543..ae68652 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -165,6 +165,10 @@
   /// invocation.
   MacroArgs *Args = 0;
   
+  // Remember where the end of the instantiation occurred.  For an object-like
+  // macro, this is the identifier.  For a function-like macro, this is the ')'.
+  SourceLocation InstantiationEnd = Identifier.getLocation();
+  
   // If this is a function-like macro, read the arguments.
   if (MI->isFunctionLike()) {
     // C99 6.10.3p10: If the preprocessing token immediately after the the macro
@@ -177,7 +181,7 @@
     // Preprocessor directives used inside macro arguments are not portable, and
     // this enables the warning.
     InMacroArgs = true;
-    Args = ReadFunctionLikeMacroArgs(Identifier, MI);
+    Args = ReadFunctionLikeMacroArgs(Identifier, MI, InstantiationEnd);
     
     // Finished parsing args.
     InMacroArgs = false;
@@ -248,7 +252,7 @@
     // locations.
     SourceLocation Loc =
       SourceMgr.createInstantiationLoc(Identifier.getLocation(), InstantiateLoc,
-                                       Identifier.getLength());
+                                       InstantiationEnd,Identifier.getLength());
     Identifier.setLocation(Loc);
     
     // If this is #define X X, we must mark the result as unexpandible.
@@ -263,7 +267,7 @@
   }
   
   // Start expanding the macro.
-  EnterMacro(Identifier, Args);
+  EnterMacro(Identifier, InstantiationEnd, Args);
   
   // Now that the macro is at the top of the include stack, ask the
   // preprocessor to read the next token from it.
@@ -275,7 +279,8 @@
 /// invoked to read all of the actual arguments specified for the macro
 /// invocation.  This returns null on error.
 MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
-                                                   MacroInfo *MI) {
+                                                   MacroInfo *MI,
+                                                   SourceLocation &MacroEnd) {
   // The number of fixed arguments to parse.
   unsigned NumFixedArgsLeft = MI->getNumArgs();
   bool isVariadic = MI->isVariadic();
@@ -308,8 +313,10 @@
         return 0;
       } else if (Tok.is(tok::r_paren)) {
         // If we found the ) token, the macro arg list is done.
-        if (NumParens-- == 0)
+        if (NumParens-- == 0) {
+          MacroEnd = Tok.getLocation();
           break;
+        }
       } else if (Tok.is(tok::l_paren)) {
         ++NumParens;
       } else if (Tok.is(tok::comma) && NumParens == 0) {
@@ -357,7 +364,7 @@
     ArgTokens.push_back(EOFTok);
     ++NumActuals;
     --NumFixedArgsLeft;
-  };
+  }
   
   // Okay, we either found the r_paren.  Check to see if we parsed too few
   // arguments.
@@ -494,6 +501,7 @@
     Tok.setKind(tok::string_literal);
     Tok.setLength(strlen("\"Mmm dd yyyy\""));
     Tok.setLocation(SourceMgr.createInstantiationLoc(DATELoc, Tok.getLocation(),
+                                                     Tok.getLocation(),
                                                      Tok.getLength()));
   } else if (II == Ident__TIME__) {
     if (!TIMELoc.isValid())
@@ -501,6 +509,7 @@
     Tok.setKind(tok::string_literal);
     Tok.setLength(strlen("\"hh:mm:ss\""));
     Tok.setLocation(SourceMgr.createInstantiationLoc(TIMELoc, Tok.getLocation(),
+                                                     Tok.getLocation(),
                                                      Tok.getLength()));
   } else if (II == Ident__INCLUDE_LEVEL__) {
     Diag(Tok, diag::ext_pp_include_level);
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 87410f9..73d3641 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -117,7 +117,6 @@
   
   // Remember the string.
   std::string StrVal = getSpelling(Tok);
-  SourceLocation StrLoc = Tok.getLocation();
 
   // Read the ')'.
   Lex(Tok);
@@ -126,6 +125,8 @@
     return;
   }
   
+  SourceLocation RParenLoc = Tok.getLocation();
+  
   // The _Pragma is lexically sound.  Destringize according to C99 6.10.9.1:
   // "The string literal is destringized by deleting the L prefix, if present,
   // deleting the leading and trailing double-quotes, replacing each escape
@@ -163,7 +164,7 @@
 
   // Make and enter a lexer object so that we lex and expand the tokens just
   // like any others.
-  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, StrLoc,
+  Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
                                         // do not include the null in the count.
                                         StrVal.size()-1, *this);
 
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index d769720..cf7306a 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -277,7 +277,8 @@
   SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr);
   
   if (InstantiationLoc.isValid())
-    Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc, Len);
+    Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc,
+                                           InstantiationLoc, Len);
   Tok.setLocation(Loc);
   
   // If this is a literal token, set the pointer data.
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 3ca0fcf..f0e2fbd 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -23,7 +23,7 @@
 
 /// Create a TokenLexer for the specified macro with the specified actual
 /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
-void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) {
+void TokenLexer::Init(Token &Tok, SourceLocation ILEnd, MacroArgs *Actuals) {
   // If the client is reusing a TokenLexer, make sure to free any memory
   // associated with it.
   destroy();
@@ -32,7 +32,8 @@
   ActualArgs = Actuals;
   CurToken = 0;
   
-  InstantiateLoc = Tok.getLocation();
+  InstantiateLocStart = Tok.getLocation();
+  InstantiateLocEnd = ILEnd;
   AtStartOfLine = Tok.isAtStartOfLine();
   HasLeadingSpace = Tok.hasLeadingSpace();
   Tokens = &*Macro->tokens_begin();
@@ -68,7 +69,7 @@
   DisableMacroExpansion = disableMacroExpansion;
   NumTokens = NumToks;
   CurToken = 0;
-  InstantiateLoc = SourceLocation();
+  InstantiateLocStart = InstantiateLocEnd = SourceLocation();
   AtStartOfLine = false;
   HasLeadingSpace = false;
       
@@ -313,11 +314,12 @@
   // diagnostics for the expanded token should appear as if they came from
   // InstantiationLoc.  Pull this information together into a new SourceLocation
   // that captures all of this.
-  if (InstantiateLoc.isValid()) {   // Don't do this for token streams.
-    SourceManager &SrcMgr = PP.getSourceManager();
-    Tok.setLocation(SrcMgr.createInstantiationLoc(Tok.getLocation(), 
-                                                  InstantiateLoc,
-                                                  Tok.getLength()));
+  if (InstantiateLocStart.isValid()) {   // Don't do this for token streams.
+    SourceManager &SM = PP.getSourceManager();
+    Tok.setLocation(SM.createInstantiationLoc(Tok.getLocation(), 
+                                              InstantiateLocStart,
+                                              InstantiateLocEnd,
+                                              Tok.getLength()));
   }
   
   // If this is the first token, set the lexical properties of the token to