moc: parse properly the gcc extension for variadic macro
authorOlivier Goffart <ogoffart@woboq.com>
Fri, 12 Oct 2012 11:37:21 +0000 (13:37 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Sun, 14 Oct 2012 18:53:42 +0000 (20:53 +0200)
Task-number: QTBUG-27547

Change-Id: I983b96b09c405e5330327092e56164b9921a2d0f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/tools/moc/preprocessor.cpp
tests/auto/tools/moc/parse-defines.h
tests/auto/tools/moc/tst_moc.cpp

index 40bba33..566be9c 100644 (file)
@@ -1201,8 +1201,18 @@ void Preprocessor::parseDefineArguments(Macro *m)
         t = next();
         if (t == PP_RPAREN)
             break;
-        if (t != PP_COMMA)
-            error("Unexpected character in macro argument list.");
+        if (t == PP_COMMA)
+            continue;
+        if (lexem() == "...") {
+            //GCC extension:    #define FOO(x, y...) x(y)
+            // The last argument was already parsed. Just mark the macro as variadic.
+            m->isVariadic = true;
+            while (test(PP_WHITESPACE));
+            if (!test(PP_RPAREN))
+                error("missing ')' in macro argument list");
+            break;
+        }
+        error("Unexpected character in macro argument list.");
     }
     m->arguments = arguments;
     while (test(PP_WHITESPACE));
index bc22444..eb47253 100644 (file)
 
 #if defined(Q_COMPILER_VARIADIC_MACROS)
 #define PD_VARARG(x, ...) x(__VA_ARGS__)
+
+#if defined(Q_CC_GNU) || defined(Q_MOC_RUN)
+//GCC extension for variadic macros
+#define PD_VARARGEXT(x, y...) x(y)
+#else
+#define PD_VARARGEXT(x, ...) x(__VA_ARGS__)
+#endif
+
 #endif
 
 PD_BEGIN_NAMESPACE
@@ -95,6 +103,10 @@ public slots:
     PD_VARARG(void vararg1) {}
     PD_VARARG(void vararg2, int) {}
     PD_VARARG(void vararg3, int, int) {}
+
+    PD_VARARGEXT(void vararg4) {}
+    PD_VARARGEXT(void vararg5, int) {}
+    PD_VARARGEXT(void vararg6, int, int) {}
 #endif
 };
 
index 0cd6c29..d861b84 100644 (file)
@@ -2744,6 +2744,12 @@ void tst_Moc::parseDefines()
     QVERIFY(index != -1);
     index = mo->indexOfSlot("vararg3(int,int)");
     QVERIFY(index != -1);
+    index = mo->indexOfSlot("vararg4()");
+    QVERIFY(index != -1);
+    index = mo->indexOfSlot("vararg5(int)");
+    QVERIFY(index != -1);
+    index = mo->indexOfSlot("vararg6(int,int)");
+    QVERIFY(index != -1);
 #endif
 
     int count = 0;