<div dir="ltr">Is it possible to emit some -Wmicrosoft warning in cases where this is necessary?</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 22, 2016 at 2:26 PM, Ehsan Akhgari via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ehsan<br>
Date: Fri Jan 22 13:26:44 2016<br>
New Revision: 258530<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=258530&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=258530&view=rev</a><br>
Log:<br>
[MSVC Compat] Accept elided commas in macro function arguments<br>
<br>
Summary:<br>
This fixes PR25875.  When the trailing comma in a macro argument list is<br>
elided, we need to treat it similarly to the case where a variadic macro<br>
misses one actual argument.<br>
<br>
Reviewers: rnk, rsmith<br>
<br>
Subscribers: cfe-commits<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D15670" rel="noreferrer" target="_blank">http://reviews.llvm.org/D15670</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Lex/Token.h<br>
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
    cfe/trunk/lib/Lex/TokenLexer.cpp<br>
    cfe/trunk/test/Preprocessor/microsoft-ext.c<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Token.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Token.h?rev=258530&r1=258529&r2=258530&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Token.h?rev=258530&r1=258529&r2=258530&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Token.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Token.h Fri Jan 22 13:26:44 2016<br>
@@ -85,6 +85,7 @@ public:<br>
     IgnoredComma = 0x80,   // This comma is not a macro argument separator (MS).<br>
     StringifiedInMacro = 0x100, // This string or character literal is formed by<br>
                                 // macro stringizing or charizing operator.<br>
+    CommaAfterElided = 0x200, // The comma following this token was elided (MS).<br>
   };<br>
<br>
   tok::TokenKind getKind() const { return Kind; }<br>
@@ -297,6 +298,11 @@ public:<br>
   bool stringifiedInMacro() const {<br>
     return (Flags & StringifiedInMacro) ? true : false;<br>
   }<br>
+<br>
+  /// Returns true if the comma after this token was elided.<br>
+  bool commaAfterElided() const {<br>
+    return (Flags & CommaAfterElided) ? true : false;<br>
+  }<br>
 };<br>
<br>
 /// \brief Information about the conditional stack (\#if directives)<br>
<br>
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=258530&r1=258529&r2=258530&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=258530&r1=258529&r2=258530&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Jan 22 13:26:44 2016<br>
@@ -723,6 +723,7 @@ MacroArgs *Preprocessor::ReadFunctionLik<br>
   // heap allocations in the common case.<br>
   SmallVector<Token, 64> ArgTokens;<br>
   bool ContainsCodeCompletionTok = false;<br>
+  bool FoundElidedComma = false;<br>
<br>
   SourceLocation TooManyArgsLoc;<br>
<br>
@@ -765,6 +766,10 @@ MacroArgs *Preprocessor::ReadFunctionLik<br>
         // If we found the ) token, the macro arg list is done.<br>
         if (NumParens-- == 0) {<br>
           MacroEnd = Tok.getLocation();<br>
+          if (!ArgTokens.empty() &&<br>
+              ArgTokens.back().commaAfterElided()) {<br>
+            FoundElidedComma = true;<br>
+          }<br>
           break;<br>
         }<br>
       } else if (Tok.is(tok::l_paren)) {<br>
@@ -909,7 +914,7 @@ MacroArgs *Preprocessor::ReadFunctionLik<br>
       // then we have an empty "()" argument empty list.  This is fine, even if<br>
       // the macro expects one argument (the argument is just empty).<br>
       isVarargsElided = MI->isVariadic();<br>
-    } else if (MI->isVariadic() &&<br>
+    } else if ((FoundElidedComma || MI->isVariadic()) &&<br>
                (NumActuals+1 == MinArgsExpected ||  // A(x, ...) -> A(X)<br>
                 (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A()<br>
       // Varargs where the named vararg parameter is missing: OK as extension.<br>
<br>
Modified: cfe/trunk/lib/Lex/TokenLexer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=258530&r1=258529&r2=258530&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenLexer.cpp?rev=258530&r1=258529&r2=258530&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/TokenLexer.cpp (original)<br>
+++ cfe/trunk/lib/Lex/TokenLexer.cpp Fri Jan 22 13:26:44 2016<br>
@@ -154,12 +154,17 @@ bool TokenLexer::MaybeRemoveCommaBeforeV<br>
   // Remove the comma.<br>
   ResultToks.pop_back();<br>
<br>
-  // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"),<br>
-  // then removal of the comma should produce a placemarker token (in C99<br>
-  // terms) which we model by popping off the previous ##, giving us a plain<br>
-  // "X" when __VA_ARGS__ is empty.<br>
-  if (!ResultToks.empty() && ResultToks.back().is(tok::hashhash))<br>
-    ResultToks.pop_back();<br>
+  if (!ResultToks.empty()) {<br>
+    // If the comma was right after another paste (e.g. "X##,##__VA_ARGS__"),<br>
+    // then removal of the comma should produce a placemarker token (in C99<br>
+    // terms) which we model by popping off the previous ##, giving us a plain<br>
+    // "X" when __VA_ARGS__ is empty.<br>
+    if (ResultToks.back().is(tok::hashhash))<br>
+      ResultToks.pop_back();<br>
+<br>
+    // Remember that this comma was elided.<br>
+    ResultToks.back().setFlag(Token::CommaAfterElided);<br>
+  }<br>
<br>
   // Never add a space, even if the comma, ##, or arg had a space.<br>
   NextTokGetsSpace = false;<br>
<br>
Modified: cfe/trunk/test/Preprocessor/microsoft-ext.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-ext.c?rev=258530&r1=258529&r2=258530&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-ext.c?rev=258530&r1=258529&r2=258530&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Preprocessor/microsoft-ext.c (original)<br>
+++ cfe/trunk/test/Preprocessor/microsoft-ext.c Fri Jan 22 13:26:44 2016<br>
@@ -34,3 +34,12 @@ ACTION_TEMPLATE(InvokeArgument,<br>
<br>
 MAKE_FUNC(MAK, ER, int a, _COMMA, int b);<br>
 // CHECK: void func(int a , int b) {}<br>
+<br>
+#define macro(a, b) (a - b)<br>
+void function(int a);<br>
+#define COMMA_ELIDER(...) \<br>
+  macro(x, __VA_ARGS__); \<br>
+  function(x, __VA_ARGS__);<br>
+COMMA_ELIDER();<br>
+// CHECK: (x - );<br>
+// CHECK: function(x);<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>