From 424dd77e18468a0516f1dbce10bcd3c25f979cf5 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Wed, 25 Mar 2009 11:50:17 +0100
Subject: [PATCH] Added support for Q_SIGNAL and Q_SLOT.

---
 src/libs/cplusplus/pp-engine.cpp          |  4 +++
 src/shared/cplusplus/AST.h                |  2 ++
 src/shared/cplusplus/CheckDeclaration.cpp | 15 ++++++++++++
 src/shared/cplusplus/Keywords.cpp         | 30 +++++++++++++++++++++++
 src/shared/cplusplus/Parser.cpp           |  9 +++++--
 src/shared/cplusplus/Token.cpp            |  2 +-
 src/shared/cplusplus/Token.h              |  2 ++
 7 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 626c888d9eb..cc1cd5fff95 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -1388,6 +1388,10 @@ bool Preprocessor::isQtReservedWord(const QByteArray &macroId) const
         return true;
     else if (size == 7 && macroId.at(0) == 'Q' && macroId == "Q_SLOTS")
         return true;
+    else if (size == 8 && macroId.at(0) == 'Q' && macroId == "Q_SIGNAL")
+        return true;
+    else if (size == 6 && macroId.at(0) == 'Q' && macroId == "Q_SLOT")
+        return true;
     else if (size == 6 && macroId.at(0) == 'S' && macroId == "SIGNAL")
         return true;
     else if (size == 4 && macroId.at(0) == 'S' && macroId == "SLOT")
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 3f3f802506f..44d5cd695a4 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -396,6 +396,7 @@ protected:
 class CPLUSPLUS_EXPORT SimpleDeclarationAST: public DeclarationAST
 {
 public:
+    unsigned qt_invokable_token;
     SpecifierAST *decl_specifier_seq;
     DeclaratorListAST *declarators;
     unsigned semicolon_token;
@@ -1071,6 +1072,7 @@ protected:
 class CPLUSPLUS_EXPORT FunctionDefinitionAST: public DeclarationAST
 {
 public:
+    unsigned qt_invokable_token;
     SpecifierAST *decl_specifier_seq;
     DeclaratorAST *declarator;
     CtorInitializerAST *ctor_initializer;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 06b85f8c5b1..c6de2cf4aa0 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -154,6 +154,9 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
         }
     }
 
+    const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
+    const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;
+
     List<Declaration *> **decl_it = &ast->symbols;
     for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
         Name *name = 0;
@@ -172,6 +175,10 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
             fun->setScope(_scope);
             fun->setName(name);
             fun->setMethodKey(semantic()->currentMethodKey());
+            if (isQ_SIGNAL)
+                fun->setMethodKey(Function::SignalMethod);
+            else if (isQ_SLOT)
+                fun->setMethodKey(Function::SlotMethod);
             fun->setVisibility(semantic()->currentVisibility());
         } else if (semantic()->currentMethodKey() != Function::NormalMethod) {
             translationUnit()->warning(ast->firstToken(),
@@ -259,6 +266,14 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
     fun->setVisibility(semantic()->currentVisibility());
     fun->setMethodKey(semantic()->currentMethodKey());
 
+    const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
+    const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;
+
+    if (isQ_SIGNAL)
+        fun->setMethodKey(Function::SignalMethod);
+    else if (isQ_SLOT)
+        fun->setMethodKey(Function::SlotMethod);
+
     checkFunctionArguments(fun);
 
     ast->symbol = fun;
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index 28cd42227b8..57d3b56961b 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -532,6 +532,19 @@ static inline int classify6(const char *s, bool q) {
       }
     }
   }
+  else if (q && s[0] == 'Q') {
+    if (s[1] == '_') {
+      if (s[2] == 'S') {
+        if (s[3] == 'L') {
+          if (s[4] == 'O') {
+            if (s[5] == 'T') {
+              return T_Q_SLOT;
+            }
+          }
+        }
+      }
+    }
+  }
   return T_IDENTIFIER;
 }
 
@@ -850,6 +863,23 @@ static inline int classify8(const char *s, bool) {
       }
     }
   }
+  else if (s[0] == 'Q') {
+    if (s[1] == '_') {
+      if (s[2] == 'S') {
+        if (s[3] == 'I') {
+          if (s[4] == 'G') {
+            if (s[5] == 'N') {
+              if (s[6] == 'A') {
+                if (s[7] == 'L') {
+                  return T_Q_SIGNAL;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
   return T_IDENTIFIER;
 }
 
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 423a05e05be..5bae822f350 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2381,10 +2381,12 @@ bool Parser::parseBuiltinTypeSpecifier(SpecifierAST *&node)
 bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
                                     bool acceptStructDeclarator)
 {
+    unsigned qt_invokable_token = 0;
+    if (acceptStructDeclarator && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT))
+        qt_invokable_token = consumeToken();
+
     // parse a simple declaration, a function definition,
     // or a contructor declaration.
-    cursor();
-
     bool has_type_specifier = false;
     bool has_complex_type_specifier = false;
     unsigned startOfNamedTypeSpecifier = 0;
@@ -2498,6 +2500,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
             }
         }
         SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST;
+        ast->qt_invokable_token = qt_invokable_token;
         ast->decl_specifier_seq = decl_specifier_seq;
         ast->declarators = declarator_list;
         match(T_SEMICOLON, &ast->semicolon_token);
@@ -2510,6 +2513,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
 
         if (LA() == T_LBRACE) {
             FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
+            ast->qt_invokable_token = qt_invokable_token;
             ast->decl_specifier_seq = decl_specifier_seq;
             ast->declarator = firstDeclarator;
             ast->ctor_initializer = ctor_initializer;
@@ -2518,6 +2522,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
             return true; // recognized a function definition.
         } else if (LA() == T_TRY) {
             FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
+            ast->qt_invokable_token = qt_invokable_token;
             ast->decl_specifier_seq = decl_specifier_seq;
             ast->declarator = firstDeclarator;
             ast->ctor_initializer = ctor_initializer;
diff --git a/src/shared/cplusplus/Token.cpp b/src/shared/cplusplus/Token.cpp
index 70d4af8e9a4..0fdb0cee2b6 100644
--- a/src/shared/cplusplus/Token.cpp
+++ b/src/shared/cplusplus/Token.cpp
@@ -90,7 +90,7 @@ static const char *token_names[] = {
     ("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
     ("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
 
-    ("SIGNAL"), ("SLOT"), ("Q_SIGNALS"), ("Q_SLOTS")
+    ("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots")
 };
 
 Token::Token() :
diff --git a/src/shared/cplusplus/Token.h b/src/shared/cplusplus/Token.h
index 260eaac43d6..69ba4c37826 100644
--- a/src/shared/cplusplus/Token.h
+++ b/src/shared/cplusplus/Token.h
@@ -232,6 +232,8 @@ enum Kind {
     // Qt keywords
     T_SIGNAL = T_FIRST_QT_KEYWORD,
     T_SLOT,
+    T_Q_SIGNAL,
+    T_Q_SLOT,
     T_SIGNALS,
     T_SLOTS,
 
-- 
GitLab