]> granicus.if.org Git - clang/commitdiff
Make preprocessor act in a GCC-compatible fashion when a macro is redefined
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Aug 2012 13:38:46 +0000 (13:38 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Aug 2012 13:38:46 +0000 (13:38 +0000)
within its own argument list. The original definition is used for the immediate
expansion, but the new definition is used for any subsequent occurences within
the argument list or after the expansion.

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

include/clang/Lex/Preprocessor.h
include/clang/Lex/TokenLexer.h
lib/Lex/PPLexerChange.cpp
lib/Lex/PPMacroExpansion.cpp
lib/Lex/TokenLexer.cpp
test/Preprocessor/macro_arg_directive.c

index adc6b240e9619fb63b3052f5e74a0e39694683c9..053200de5b8023bc835215cc4d8e88690ed59e1c 100644 (file)
@@ -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.
index 1330ad5f31436ac4fb838d3c281c5392ee6fa12e..6f11e126e97addbdbf9ccc65d3777429493d4778 100644 (file)
@@ -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
index e824320cf732a79f167ec36f6e70d192903e01da..d827f58a485f511db8bae5a53cbc47cc811de7f8 100644 (file)
@@ -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;
index 3f27236cac3c1ada9136e7f700c7b126215b74ae..5c5bc00fe2d5f31849a0b03023b18aadb005956f 100644 (file)
@@ -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.
index ade40dad77d9ae2e735bc52780cd13136f0fd79b..819bb3f43ea42bf1fb50a1156f36912be5f0f1d9 100644 (file)
@@ -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;
 
index 5c9943d60530d4db62c58692a45c7561d6cb3607..5bc2236f0c45710b9435fbad804216179ef574ef 100644 (file)
@@ -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(...) \