]> granicus.if.org Git - clang/commitdiff
improve MacroInfo to track the source range of the macro definition,
authorChris Lattner <sabre@nondot.org>
Tue, 21 Apr 2009 04:46:33 +0000 (04:46 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 21 Apr 2009 04:46:33 +0000 (04:46 +0000)
patch by Alexei Svitkine!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69659 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/MacroInfo.h
lib/Lex/PPDirectives.cpp

index ba1cfde405db3ef95d9941e767f2d7810855c04e..ccd13c80d354699a8f444ba4851285caea0f4118 100644 (file)
@@ -31,6 +31,8 @@ class MacroInfo {
 
   /// Location - This is the place the macro is defined.
   SourceLocation Location;
+  /// EndLocation - The location of the last token in the macro.
+  SourceLocation EndLocation;
 
   /// Arguments - The list of arguments for a function-like macro.  This can be
   /// empty, for, e.g. "#define X()".  In a C99-style variadic macro, this
@@ -98,7 +100,14 @@ public:
   /// getDefinitionLoc - Return the location that the macro was defined at.
   ///
   SourceLocation getDefinitionLoc() const { return Location; }
-  
+
+  /// setDefinitionEndLoc - Set the location of the last token in the macro.
+  ///
+  void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
+  /// getDefinitionEndLoc - Return the location of the last token in the macro.
+  ///
+  SourceLocation getDefinitionEndLoc() const { return EndLocation; }
+
   /// isIdenticalTo - Return true if the specified macro definition is equal to
   /// this macro in spelling, arguments, and whitespace.  This is used to emit
   /// duplicate definition warnings.  This implements the rules in C99 6.10.3.
index a6e1e7ee2ca0435abd53b0df24abfd299cbe29ce..ca8693bf61f49c129d97c5b83817c450f98c35d0 100644 (file)
@@ -1275,6 +1275,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
   if (MacroNameTok.is(tok::eom))
     return;
 
+  Token LastTok = MacroNameTok;
+
   // If we are supposed to keep comments in #defines, reenable comment saving
   // mode.
   if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
@@ -1342,11 +1344,15 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
     else
       Diag(Tok, diag::warn_missing_whitespace_after_macro_name);
   }
-  
+
+  if (!Tok.is(tok::eom))
+    LastTok = Tok;
+
   // Read the rest of the macro body.
   if (MI->isObjectLike()) {
     // Object-like macros are very simple, just read their body.
     while (Tok.isNot(tok::eom)) {
+      LastTok = Tok;
       MI->AddTokenToBody(Tok);
       // Get the next token of the macro.
       LexUnexpandedToken(Tok);
@@ -1356,6 +1362,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
     // Otherwise, read the body of a function-like macro.  This has to validate
     // the # (stringize) operator.
     while (Tok.isNot(tok::eom)) {
+      LastTok = Tok;
       MI->AddTokenToBody(Tok);
 
       // Check C99 6.10.3.2p1: ensure that # operators are followed by macro
@@ -1412,6 +1419,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
   // used yet.
   if (isInPrimaryFile())
     MI->setIsUsed(false);
+
+  MI->setDefinitionEndLoc(LastTok.getLocation());
   
   // Finally, if this identifier already had a macro defined for it, verify that
   // the macro bodies are identical and free the old definition.