From 50b17b7cce92e0ac61e30510347d50dd31bffe33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Matos?= <ripzonetriton@gmail.com>
Date: Sun, 26 Aug 2012 22:23:15 +0100
Subject: [PATCH] Emulate MSVC's preprocessor macro argument separator
 behavior.

Specifically, commas that come from nested macro expansions are not considered as argument separators.
---
 include/clang/Lex/Token.h    | 3 ++-
 lib/Lex/PPMacroExpansion.cpp | 6 +++++-
 lib/Lex/TokenLexer.cpp       | 6 ++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 9c5a023..34025cf 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -76,7 +76,8 @@ public:
     DisableExpand = 0x04,  // This identifier may never be macro expanded.
     NeedsCleaning = 0x08,   // Contained an escaped newline or trigraph.
     LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
-    HasUDSuffix = 0x20     // This string or character literal has a ud-suffix.
+    HasUDSuffix = 0x20,    // This string or character literal has a ud-suffix.
+    IgnoredComma = 0x40 // Flags ignored commas from nested macro expansions.
   };
 
   tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index eb4da22..09b993b 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -399,7 +399,11 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
         }
       } else if (Tok.is(tok::l_paren)) {
         ++NumParens;
-      } else if (Tok.is(tok::comma) && NumParens == 0) {
+      // In Microsoft-compatibility mode, commas from nested macro expan-
+      // sions should not be considered as argument separators. We test
+      // for this with the IgnoredComma token flag.
+      } else if (Tok.is(tok::comma)
+          && !(Tok.getFlags() & Token::IgnoredComma) && NumParens == 0) {
         // Comma ends this argument if there are more fixed arguments expected.
         // However, if this is a variadic macro, and this is part of the
         // variadic part, then the comma is just an argument token.
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index ade40da..5c84c6f 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -224,6 +224,12 @@ void TokenLexer::ExpandFunctionArguments() {
           Token &Tok = ResultToks[i];
           if (Tok.is(tok::hashhash))
             Tok.setKind(tok::unknown);
+          // In Microsoft-compatibility mode, we follow MSVC's preprocessing
+          // behaviour by not considering commas from nested macro expansions
+          // as argument separators. Set a flag on the token so we can test
+          // for this later when the macro expansion is processed.
+          if (Tok.is(tok::comma) && PP.getLangOpts().MicrosoftMode)
+            Tok.setFlag(Token::IgnoredComma);
         }
 
         if(ExpandLocStart.isValid()) {
-- 
1.7.11

