diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index adc6b240e9619fb63b3052f5e74a0e39694683c9..053200de5b8023bc835215cc4d8e88690ed59e1c 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -569,7 +569,8 @@ public: /// /// ILEnd specifies the location of the ')' for a function-like macro or the /// identifier for an object-like macro. - void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroArgs *Args); + void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro, + MacroArgs *Args); /// EnterTokenStream - Add a "macro" context to the top of the include stack, /// which will cause the lexer to start returning the specified tokens. diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 1330ad5f31436ac4fb838d3c281c5392ee6fa12e..6f11e126e97addbdbf9ccc65d3777429493d4778 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -22,7 +22,7 @@ namespace clang { class Token; class MacroArgs; -/// TokenLexer - This implements a lexer that returns token from a macro body +/// TokenLexer - This implements a lexer that returns tokens from a macro body /// or token stream instead of lexing from a character buffer. This is used for /// macro expansion and _Pragma handling, for example. /// @@ -98,17 +98,18 @@ public: /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. /// ILEnd specifies the location of the ')' for a function-like macro or the /// identifier for an object-like macro. - TokenLexer(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs, - Preprocessor &pp) + TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, + MacroArgs *ActualArgs, Preprocessor &pp) : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) { - Init(Tok, ILEnd, ActualArgs); + Init(Tok, ILEnd, MI, ActualArgs); } /// Init - Initialize this TokenLexer to expand from the specified macro /// with the specified argument information. Note that this ctor takes /// ownership of the ActualArgs pointer. ILEnd specifies the location of the /// ')' for a function-like macro or the identifier for an object-like macro. - void Init(Token &Tok, SourceLocation ILEnd, MacroArgs *ActualArgs); + void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI, + MacroArgs *ActualArgs); /// Create a TokenLexer for the specified token stream. If 'OwnsTokens' is /// specified, this takes ownership of the tokens and delete[]'s them when diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index e824320cf732a79f167ec36f6e70d192903e01da..d827f58a485f511db8bae5a53cbc47cc811de7f8 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -157,15 +157,15 @@ void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL, /// 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, SourceLocation ILEnd, - MacroArgs *Args) { + MacroInfo *Macro, MacroArgs *Args) { PushIncludeMacroStack(); CurDirLookup = 0; if (NumCachedTokenLexers == 0) { - CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Args, *this)); + CurTokenLexer.reset(new TokenLexer(Tok, ILEnd, Macro, Args, *this)); } else { CurTokenLexer.reset(TokenLexerCache[--NumCachedTokenLexers]); - CurTokenLexer->Init(Tok, ILEnd, Args); + CurTokenLexer->Init(Tok, ILEnd, Macro, Args); } if (CurLexerKind != CLK_LexAfterModuleImport) CurLexerKind = CLK_TokenLexer; diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 3f27236cac3c1ada9136e7f700c7b126215b74ae..5c5bc00fe2d5f31849a0b03023b18aadb005956f 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -341,7 +341,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } // Start expanding the macro. - EnterMacro(Identifier, ExpansionEnd, Args); + EnterMacro(Identifier, ExpansionEnd, MI, Args); // Now that the macro is at the top of the include stack, ask the // preprocessor to read the next token from it. diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp index ade40dad77d9ae2e735bc52780cd13136f0fd79b..819bb3f43ea42bf1fb50a1156f36912be5f0f1d9 100644 --- a/lib/Lex/TokenLexer.cpp +++ b/lib/Lex/TokenLexer.cpp @@ -23,12 +23,13 @@ using namespace clang; /// 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, SourceLocation ELEnd, MacroArgs *Actuals) { +void TokenLexer::Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI, + MacroArgs *Actuals) { // If the client is reusing a TokenLexer, make sure to free any memory // associated with it. destroy(); - Macro = PP.getMacroInfo(Tok.getIdentifierInfo()); + Macro = MI; ActualArgs = Actuals; CurToken = 0; diff --git a/test/Preprocessor/macro_arg_directive.c b/test/Preprocessor/macro_arg_directive.c index 5c9943d60530d4db62c58692a45c7561d6cb3607..5bc2236f0c45710b9435fbad804216179ef574ef 100644 --- a/test/Preprocessor/macro_arg_directive.c +++ b/test/Preprocessor/macro_arg_directive.c @@ -1,5 +1,12 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify +#define a(x) enum { x } +a(n = +#undef a +#define a 5 + a); +_Static_assert(n == 5, ""); + // header1.h void fail(const char *); #define MUNCH(...) \