From: Chris Lattner Date: Tue, 21 Apr 2009 04:46:33 +0000 (+0000) Subject: improve MacroInfo to track the source range of the macro definition, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2451b528fe114595d0f10ef2c05047928558ab0f;p=clang improve MacroInfo to track the source range of the macro definition, patch by Alexei Svitkine! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69659 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index ba1cfde405..ccd13c80d3 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -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. diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index a6e1e7ee2c..ca8693bf61 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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.