From 4c94f37cb58691e3f553f1cc2fdfc21c4a712815 Mon Sep 17 00:00:00 2001
From: mae <qt-info@nokia.com>
Date: Wed, 18 Nov 2009 09:23:07 +0100
Subject: [PATCH] Enable preprocessor macro substitution in moc for argument-less macros

The problems tends to show up in combination with namespaces, when
namespaces are declared through a macro. The patch introduces a pragma
Q_MOC_EXPAND_MACROS which will enable macro expansion in the current file.

Task-number: QTBUG-35
Reviewed-by: Alex
---
 src/tools/moc/keywords.cpp               |    6 +-
 src/tools/moc/parser.h                   |    3 +-
 src/tools/moc/ppkeywords.cpp             |  180 ++++++++++++++++++++---------
 src/tools/moc/preprocessor.cpp           |   53 +++++++--
 src/tools/moc/preprocessor.h             |    2 +-
 src/tools/moc/token.cpp                  |    1 +
 src/tools/moc/token.h                    |   24 ++++-
 src/tools/moc/util/generate_keywords.cpp |   26 ++++-
 8 files changed, 220 insertions(+), 75 deletions(-)

diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
index da50694..f2a9305 100644
--- a/src/tools/moc/keywords.cpp
+++ b/src/tools/moc/keywords.cpp
@@ -46,7 +46,7 @@ static const short keyword_trans[][128] = {
     {0,0,0,0,0,0,0,0,0,525,522,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      525,252,523,526,0,38,239,524,25,26,236,234,30,235,27,237,
-     22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
+     22,22,22,22,22,22,22,22,22,22,33,41,23,39,24,43,
      0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
      8,21,8,8,8,8,8,8,8,8,8,31,527,32,238,8,
      0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
@@ -174,7 +174,7 @@ static const short keyword_trans[][128] = {
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,33,0,263,272,0,0,
+     0,0,0,0,0,0,0,0,0,0,34,0,263,272,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -478,8 +478,8 @@ static const struct
     {COMMA, 0, 0, 0, NOTOKEN},
     {LBRACK, 0, 0, 0, NOTOKEN},
     {RBRACK, 0, 0, 0, NOTOKEN},
-    {LBRACK, 0, 58, 35, NOTOKEN},
     {COLON, 19, 0, 0, NOTOKEN},
+    {INCOMPLETE, 0, 58, 35, NOTOKEN},
     {LANGLE_SCOPE, 0, 0, 0, NOTOKEN},
     {LBRACE, 0, 0, 0, NOTOKEN},
     {RBRACE, 0, 0, 0, NOTOKEN},
diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h
index 80c78b6..36398de 100644
--- a/src/tools/moc/parser.h
+++ b/src/tools/moc/parser.h
@@ -50,10 +50,11 @@ QT_BEGIN_NAMESPACE
 class Parser
 {
 public:
-    Parser():index(0), displayWarnings(true){}
+    Parser():index(0), displayWarnings(true), expandMacros(false){}
     Symbols symbols;
     int index;
     bool displayWarnings;
+    bool expandMacros;
 
     QStack<QByteArray> currentFilenames;
 
diff --git a/src/tools/moc/ppkeywords.cpp b/src/tools/moc/ppkeywords.cpp
index 6c8f0b3..193bdb3 100644
--- a/src/tools/moc/ppkeywords.cpp
+++ b/src/tools/moc/ppkeywords.cpp
@@ -43,18 +43,18 @@
 // DO NOT EDIT.
 
 static const short pp_keyword_trans[][128] = {
-    {0,0,0,0,0,0,0,0,0,98,12,0,0,0,0,0,
+    {0,0,0,0,0,0,0,0,0,104,12,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     98,76,96,13,0,60,62,97,9,10,58,56,11,57,102,59,
-     6,6,6,6,6,6,6,6,6,6,92,0,7,81,8,91,
+     104,82,102,13,0,66,68,103,9,10,64,62,11,63,108,65,
+     6,6,6,6,6,6,6,6,6,6,98,0,7,87,8,97,
      0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-     1,1,1,1,1,1,1,1,1,1,1,0,101,0,61,1,
+     1,1,1,1,1,1,1,1,1,1,1,0,107,0,67,1,
      0,1,2,3,4,1,1,1,1,1,1,1,1,1,5,1,
-     1,1,1,1,1,1,1,1,1,1,1,0,68,0,71,0},
+     1,1,1,1,1,1,1,1,1,1,1,0,74,0,77,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,0,0,79,87,0,0,
+     0,0,0,0,0,113,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,111,0,85,93,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -62,26 +62,26 @@ static const short pp_keyword_trans[][128] = {
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,0,0,0,88,80,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,94,86,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,93,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,14,34,0,0,0,20,0,0,0,0,0,0,
-     0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0},
+     44,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,21,0,0,0,0,0,0,0,44,0,
+     0,0,0,0,0,0,21,0,0,0,0,0,0,0,50,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -109,24 +109,64 @@ static const short pp_keyword_trans[][128] = {
      0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,99,
+     0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,117,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,118,129,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,106,0,0,0,0,105,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,120,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,100,0,0,121,114,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,95,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,123,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     0,65,0,0,0,0,0,0,0,0,0,0,0,0,0,69,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,71,0,0,0,0,0,0,0,0,0,0,0,0,0,75,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-     103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0},
+    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+     0,0,0,0,0,0,0,0,0,0,116,0,0,0,109,0,
+     131,131,131,131,131,131,131,131,131,131,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -143,10 +183,10 @@ static const struct
 } pp_keywords[] = {
     {PP_NOTOKEN, 0, 0, 0, PP_NOTOKEN},
     {PP_CHARACTER, 0, 0, 0, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 105, 63, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 111, 72, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 101, 50, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 111, 77, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 105, 69, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 111, 78, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 101, 56, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 111, 83, PP_NOTOKEN},
     {PP_DIGIT, 0, 0, 0, PP_NOTOKEN},
     {PP_LANGLE, 1, 0, 0, PP_NOTOKEN},
     {PP_RANGLE, 2, 0, 0, PP_NOTOKEN},
@@ -185,64 +225,92 @@ static const struct
     {PP_HASH, 0, 105, 42, PP_HASH},
     {PP_HASH, 0, 102, 43, PP_HASH},
     {PP_ENDIF, 0, 0, 0, PP_HASH},
-    {PP_HASH, 0, 99, 45, PP_HASH},
-    {PP_HASH, 0, 108, 46, PP_HASH},
-    {PP_HASH, 0, 117, 47, PP_HASH},
-    {PP_HASH, 0, 100, 48, PP_HASH},
-    {PP_HASH, 0, 101, 49, PP_HASH},
+    {PP_HASH, 0, 114, 45, PP_HASH},
+    {PP_HASH, 0, 97, 46, PP_HASH},
+    {PP_HASH, 0, 103, 47, PP_HASH},
+    {PP_HASH, 0, 109, 48, PP_HASH},
+    {PP_HASH, 0, 97, 49, PP_HASH},
+    {PP_PRAGMA, 0, 0, 0, PP_HASH},
+    {PP_HASH, 0, 99, 51, PP_HASH},
+    {PP_HASH, 0, 108, 52, PP_HASH},
+    {PP_HASH, 0, 117, 53, PP_HASH},
+    {PP_HASH, 0, 100, 54, PP_HASH},
+    {PP_HASH, 0, 101, 55, PP_HASH},
     {PP_INCLUDE, 0, 0, 0, PP_HASH},
-    {PP_CHARACTER, 0, 102, 51, PP_CHARACTER},
-    {PP_CHARACTER, 0, 105, 52, PP_CHARACTER},
-    {PP_CHARACTER, 0, 110, 53, PP_CHARACTER},
-    {PP_CHARACTER, 0, 101, 54, PP_CHARACTER},
-    {PP_CHARACTER, 0, 100, 55, PP_CHARACTER},
+    {PP_CHARACTER, 0, 102, 57, PP_CHARACTER},
+    {PP_CHARACTER, 0, 105, 58, PP_CHARACTER},
+    {PP_CHARACTER, 0, 110, 59, PP_CHARACTER},
+    {PP_CHARACTER, 0, 101, 60, PP_CHARACTER},
+    {PP_CHARACTER, 0, 100, 61, PP_CHARACTER},
     {PP_DEFINED, 0, 0, 0, PP_CHARACTER},
-    {PP_PLUS, 0, 0, 0, PP_NOTOKEN},
-    {PP_MINUS, 0, 0, 0, PP_NOTOKEN},
-    {PP_STAR, 0, 0, 0, PP_NOTOKEN},
-    {PP_SLASH, 8, 0, 0, PP_NOTOKEN},
-    {PP_PERCENT, 0, 58, 94, PP_NOTOKEN},
-    {PP_HAT, 0, 0, 0, PP_NOTOKEN},
-    {PP_AND, 0, 38, 89, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 116, 64, PP_CHARACTER},
-    {PP_CHARACTER, 9, 0, 0, PP_CHARACTER},
-    {PP_CHARACTER, 0, 110, 66, PP_CHARACTER},
-    {PP_CHARACTER, 0, 100, 67, PP_CHARACTER},
+    {PP_PLUS, 8, 0, 0, PP_NOTOKEN},
+    {PP_MINUS, 9, 0, 0, PP_NOTOKEN},
+    {PP_STAR, 0, 61, 119, PP_NOTOKEN},
+    {PP_SLASH, 10, 0, 0, PP_NOTOKEN},
+    {PP_PERCENT, 11, 0, 0, PP_NOTOKEN},
+    {PP_HAT, 0, 61, 122, PP_NOTOKEN},
+    {PP_AND, 12, 0, 0, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 116, 70, PP_CHARACTER},
+    {PP_CHARACTER, 13, 0, 0, PP_CHARACTER},
+    {PP_CHARACTER, 0, 110, 72, PP_CHARACTER},
+    {PP_CHARACTER, 0, 100, 73, PP_CHARACTER},
     {PP_AND, 0, 0, 0, PP_CHARACTER},
-    {PP_OR, 0, 124, 90, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 114, 70, PP_CHARACTER},
+    {PP_OR, 14, 0, 0, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 114, 76, PP_CHARACTER},
     {PP_OR, 0, 0, 0, PP_CHARACTER},
     {PP_TILDE, 0, 0, 0, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 109, 73, PP_CHARACTER},
-    {PP_CHARACTER, 0, 112, 74, PP_CHARACTER},
-    {PP_CHARACTER, 0, 108, 75, PP_CHARACTER},
+    {PP_CHARACTER, 0, 109, 79, PP_CHARACTER},
+    {PP_CHARACTER, 0, 112, 80, PP_CHARACTER},
+    {PP_CHARACTER, 0, 108, 81, PP_CHARACTER},
     {PP_TILDE, 0, 0, 0, PP_CHARACTER},
-    {PP_NOT, 0, 61, 83, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 116, 78, PP_CHARACTER},
-    {PP_NOT, 0, 95, 84, PP_CHARACTER},
-    {PP_LTLT, 0, 0, 0, PP_NOTOKEN},
-    {PP_GTGT, 0, 0, 0, PP_NOTOKEN},
-    {PP_INCOMPLETE, 0, 61, 82, PP_NOTOKEN},
+    {PP_NOT, 0, 61, 89, PP_NOTOKEN},
+    {PP_CHARACTER, 0, 116, 84, PP_CHARACTER},
+    {PP_NOT, 0, 95, 90, PP_CHARACTER},
+    {PP_LTLT, 0, 61, 126, PP_NOTOKEN},
+    {PP_GTGT, 0, 61, 125, PP_NOTOKEN},
+    {PP_INCOMPLETE, 0, 61, 88, PP_NOTOKEN},
     {PP_EQEQ, 0, 0, 0, PP_NOTOKEN},
     {PP_NE, 0, 0, 0, PP_NOTOKEN},
-    {PP_CHARACTER, 0, 101, 85, PP_CHARACTER},
-    {PP_CHARACTER, 0, 113, 86, PP_CHARACTER},
+    {PP_CHARACTER, 0, 101, 91, PP_CHARACTER},
+    {PP_CHARACTER, 0, 113, 92, PP_CHARACTER},
     {PP_NE, 0, 0, 0, PP_CHARACTER},
     {PP_LE, 0, 0, 0, PP_NOTOKEN},
     {PP_GE, 0, 0, 0, PP_NOTOKEN},
     {PP_ANDAND, 0, 0, 0, PP_NOTOKEN},
     {PP_OROR, 0, 0, 0, PP_NOTOKEN},
     {PP_QUESTION, 0, 0, 0, PP_NOTOKEN},
-    {PP_COLON, 0, 0, 0, PP_NOTOKEN},
+    {PP_COLON, 0, 58, 115, PP_NOTOKEN},
     {PP_HASHHASH, 0, 0, 0, PP_NOTOKEN},
-    {PP_INCOMPLETE, 0, 37, 95, PP_NOTOKEN},
-    {PP_INCOMPLETE, 0, 58, 93, PP_NOTOKEN},
+    {PP_INCOMPLETE, 0, 37, 101, PP_NOTOKEN},
+    {PP_INCOMPLETE, 0, 58, 99, PP_NOTOKEN},
     {PP_QUOTE, 0, 0, 0, PP_NOTOKEN},
     {PP_SINGLEQUOTE, 0, 0, 0, PP_NOTOKEN},
     {PP_WHITESPACE, 0, 0, 0, PP_NOTOKEN},
     {PP_CPP_COMMENT, 0, 0, 0, PP_NOTOKEN},
     {PP_C_COMMENT, 0, 0, 0, PP_NOTOKEN},
     {PP_BACKSLASH, 0, 0, 0, PP_NOTOKEN},
-    {PP_INCOMPLETE, 10, 0, 0, PP_NOTOKEN},
+    {PP_INCOMPLETE, 15, 0, 0, PP_NOTOKEN},
+    {PP_INCOMPLETE, 0, 46, 110, PP_NOTOKEN},
+    {PP_ELIPSIS, 0, 0, 0, PP_NOTOKEN},
+    {PP_INCOMPLETE, 0, 58, 112, PP_NOTOKEN},
+    {PP_LANGLE_SCOPE, 0, 0, 0, PP_NOTOKEN},
+    {PP_LBRACE, 0, 0, 0, PP_NOTOKEN},
+    {PP_RBRACE, 0, 0, 0, PP_NOTOKEN},
+    {PP_SCOPE, 0, 0, 0, PP_NOTOKEN},
+    {PP_DOTSTAR, 0, 0, 0, PP_NOTOKEN},
+    {PP_PLUS_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_MINUS_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_STAR_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_SLASH_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_PERCENT_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_HAT_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_AND_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_OR_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_GTGT_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_LTLT_EQ, 0, 0, 0, PP_NOTOKEN},
+    {PP_INCR, 0, 0, 0, PP_NOTOKEN},
+    {PP_DECR, 0, 0, 0, PP_NOTOKEN},
+    {PP_ARROW, 0, 42, 130, PP_NOTOKEN},
+    {PP_ARROW_STAR, 0, 0, 0, PP_NOTOKEN},
     {PP_FLOATING_LITERAL, 0, 0, 0, PP_NOTOKEN}
 };
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
index 53e924c..c27e687 100644
--- a/src/tools/moc/preprocessor.cpp
+++ b/src/tools/moc/preprocessor.cpp
@@ -510,19 +510,29 @@ static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode m
     return symbols;
 }
 
-void Preprocessor::substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset)
+bool Preprocessor::substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset)
 {
     Symbols saveSymbols = symbols;
     int saveIndex = index;
 
     symbols = macros.value(macro).symbols;
     index = 0;
+    
+    // do not substitute macros with arguments
+    // ### TODO make it possible to substitue macros with arguments
+    if (symbols.count() > 0  && symbols.at(0).token == PP_LPAREN) {
+        symbols = saveSymbols;
+        index = saveIndex;
+        return false;
+    }
+
 
     safeset += macro;
     substituteUntilNewline(substituted, safeset);
 
     symbols = saveSymbols;
     index = saveIndex;
+    return true;
 }
 
 
@@ -838,6 +848,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
 
             Symbols saveSymbols = symbols;
             int saveIndex = index;
+            bool saveExpandMacros = expandMacros;
 
             // phase 1: get rid of backslash-newlines
             input = cleaned(input);
@@ -855,6 +866,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
 
             symbols = saveSymbols;
             index = saveIndex;
+            expandMacros = saveExpandMacros;
             continue;
         }
         case PP_DEFINE:
@@ -870,6 +882,17 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
             macros.insert(name, macro);
             continue;
         }
+
+        case PP_PRAGMA:
+        {
+            if (test(PP_IDENTIFIER)) {
+                if (lexem() == "Q_MOC_EXPAND_MACROS")
+                    expandMacros = true; // expand macros in this source file
+            }
+            until(PP_NEWLINE);
+            continue;
+        }
+
         case PP_UNDEF: {
             next(IDENTIFIER);
             QByteArray name = lexem();
@@ -878,18 +901,24 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
             continue;
         }
         case PP_IDENTIFIER:
-        {
-//             if (macros.contains(symbol()))
-//                 ;
-        }
-            // we _could_ easily substitute macros by the following
-            // four lines, but we choose not to.
-            /*
-            if (macros.contains(sym.lexem())) {
-                preprocessed += substitute(macros, symbols, i);
-                continue;
+            // substitute macros
+            if (expandMacros && macros.contains(lexem())) {
+                MacroName macro = symbol();
+                Symbols symbols;
+                if (substituteMacro(macro, symbols)) {
+                    QByteArray substitution;
+                    foreach(Symbol symbol, symbols) {
+                        substitution += ' ';
+                        substitution += symbol.lexem();
+                    }
+                    if (!substitution.isEmpty()) {
+                        Symbols substitutedSymbols = tokenize(substitution, symbols.first().lineNum);
+                        for (int i = 0; i < substitutedSymbols.size()-1; ++i)
+                            preprocessed += substitutedSymbols.at(i);
+                    }
+                    continue;
+                }
             }
-            */
             break;
         case PP_HASH:
             until(PP_NEWLINE);
diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h
index 48ca6d2..ec16ce9 100644
--- a/src/tools/moc/preprocessor.h
+++ b/src/tools/moc/preprocessor.h
@@ -85,7 +85,7 @@ public:
     void skipUntilEndif();
     bool skipBranch();
 
-    void substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
+    bool substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
     void substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
 
     int evaluateCondition();
diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp
index 6d1fdca..c27e3e9 100644
--- a/src/tools/moc/token.cpp
+++ b/src/tools/moc/token.cpp
@@ -55,6 +55,7 @@ const char *tokenTypeName(Token t)
         case BOOLEAN_LITERAL: return "BOOLEAN_LITERAL";
         case HEADER_NAME: return "HEADER_NAME";
         case LANGLE: return "LANGLE";
+        case LANGLE_SCOPE: return "LANGLE_SCOPE";
         case RANGLE: return "RANGLE";
         case LPAREN: return "LPAREN";
         case RPAREN: return "RPAREN";
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
index 4ae5100..29219f7 100644
--- a/src/tools/moc/token.h
+++ b/src/tools/moc/token.h
@@ -211,6 +211,7 @@ enum Token {
     PP_ELIF,
     PP_ELSE,
     PP_ENDIF,
+    PP_PRAGMA,
     PP_INCLUDE,
     PP_HASHHASH,
     PP_HASH,
@@ -259,7 +260,28 @@ enum Token {
     PP_NEWLINE = NEWLINE,
     PP_CPP_COMMENT = CPP_COMMENT,
     PP_C_COMMENT = C_COMMENT,
-    PP_BACKSLASH = BACKSLASH
+    PP_BACKSLASH = BACKSLASH,
+
+    PP_ELIPSIS          = ELIPSIS,
+    PP_LANGLE_SCOPE     = LANGLE_SCOPE,
+    PP_LBRACE           = LBRACE,
+    PP_RBRACE           = RBRACE,
+    PP_SCOPE            = SCOPE,
+    PP_DOTSTAR          = DOTSTAR,
+    PP_PLUS_EQ          = PLUS_EQ,
+    PP_MINUS_EQ         = MINUS_EQ,
+    PP_STAR_EQ          = STAR_EQ,
+    PP_SLASH_EQ         = SLASH_EQ,
+    PP_PERCENT_EQ       = PERCENT_EQ,
+    PP_HAT_EQ           = HAT_EQ,
+    PP_AND_EQ           = AND_EQ,
+    PP_OR_EQ            = OR_EQ,
+    PP_GTGT_EQ          = GTGT_EQ,
+    PP_LTLT_EQ          = LTLT_EQ,
+    PP_INCR             = INCR,
+    PP_DECR             = DECR,
+    PP_ARROW_STAR       = ARROW_STAR,
+    PP_ARROW            = ARROW
 };
 
 // for debugging only
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
index 490d03c..0be75af 100644
--- a/src/tools/moc/util/generate_keywords.cpp
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -64,6 +64,7 @@ static const Keyword pp_keywords[] = {
     { "#elif", "PP_ELIF"},
     { "#else", "PP_ELSE"},
     { "#endif", "PP_ENDIF"},
+    { "#pragma", "PP_PRAGMA"},
     { "#include", "PP_INCLUDE"},
     { "defined", "PP_DEFINED"},
     { "+", "PP_PLUS" },
@@ -101,6 +102,29 @@ static const Keyword pp_keywords[] = {
     { "//", "PP_CPP_COMMENT" },
     { "/*", "PP_C_COMMENT" },
     { "\\", "PP_BACKSLASH" },
+
+    { "...", "PP_ELIPSIS" },
+    { "<::", "PP_LANGLE_SCOPE" },
+    { "<%", "PP_LBRACE" },
+    { "%>", "PP_RBRACE" },
+    { "::", "PP_SCOPE" },
+    { ".*", "PP_DOTSTAR" },
+    { "+=", "PP_PLUS_EQ" },
+    { "-=", "PP_MINUS_EQ" },
+    { "*=", "PP_STAR_EQ" },
+    { "/=", "PP_SLASH_EQ" },
+    { "%=", "PP_PERCENT_EQ" },
+    { "^=", "PP_HAT_EQ" },
+    { "&=", "PP_AND_EQ" },
+    { "|=", "PP_OR_EQ" },
+    { ">>=", "PP_GTGT_EQ" },
+    { "<<=", "PP_LTLT_EQ" },
+    { "++", "PP_INCR" },
+    { "--", "PP_DECR" },
+    { "->*", "PP_ARROW_STAR" },
+    { "->", "PP_ARROW" },
+
+
     { 0, "PP_NOTOKEN"}
 };
 
@@ -113,7 +137,7 @@ static const Keyword keywords[] = {
     { ",", "COMMA" },
     { "[", "LBRACK" },
     { "]", "RBRACK" },
-    { "<:", "LBRACK" },
+    { "...", "ELIPSIS" },
     { ":>", "RBRACK" },
     { "<::", "LANGLE_SCOPE" },
     { "{", "LBRACE" },
-- 
1.6.0.4

