From e609e9a70176d5cad7c823f60ab2a7f736d32e41 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Tue, 23 Feb 2010 17:43:40 +0100
Subject: [PATCH] Simplified ObjC selectors in the AST.

---
 src/libs/cplusplus/FindUsages.cpp             | 19 ++--
 src/libs/cplusplus/FindUsages.h               |  3 +-
 src/libs/cplusplus/ResolveExpression.cpp      |  4 +-
 src/shared/cplusplus/AST.cpp                  | 29 ++----
 src/shared/cplusplus/AST.h                    | 91 ++++++-------------
 src/shared/cplusplus/ASTClone.cpp             | 41 ++++-----
 src/shared/cplusplus/ASTMatch0.cpp            | 40 ++++----
 src/shared/cplusplus/ASTMatcher.cpp           | 60 +++++-------
 src/shared/cplusplus/ASTMatcher.h             |  3 +-
 src/shared/cplusplus/ASTPatternBuilder.h      | 12 ---
 src/shared/cplusplus/ASTVisit.cpp             | 37 +++-----
 src/shared/cplusplus/ASTVisitor.h             |  6 +-
 src/shared/cplusplus/ASTfwd.h                 |  2 -
 src/shared/cplusplus/CheckDeclarator.cpp      | 16 ++--
 src/shared/cplusplus/CheckName.cpp            | 31 +------
 src/shared/cplusplus/CheckName.h              |  4 +-
 src/shared/cplusplus/Parser.cpp               | 44 +++++----
 src/shared/cplusplus/Semantic.cpp             |  3 -
 src/shared/cplusplus/Semantic.h               |  1 -
 tests/auto/cplusplus/ast/tst_ast.cpp          | 19 ++--
 .../auto/cplusplus/semantic/tst_semantic.cpp  |  7 +-
 21 files changed, 177 insertions(+), 295 deletions(-)

diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index a8d0e456b6f..83a6b571351 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -463,29 +463,26 @@ bool FindUsages::visit(SimpleDeclarationAST *ast)
     return false;
 }
 
-bool FindUsages::visit(ObjCSelectorWithoutArgumentsAST *ast)
+bool FindUsages::visit(ObjCSelectorAST *ast)
 {
-    const Identifier *id = identifier(ast->name_token);
+#if 1
+    const Identifier *id = ast->name->identifier();
     if (id == _id) {
         LookupContext context = currentContext(ast);
-        const QList<Symbol *> candidates = context.resolve(ast->selector_name);
-        reportResult(ast->name_token, candidates);
+        const QList<Symbol *> candidates = context.resolve(ast->name);
+        reportResult(ast->firstToken(), candidates);
     }
-
-    return false;
-}
-
-bool FindUsages::visit(ObjCSelectorWithArgumentsAST *ast)
-{
+#else
     for (ObjCSelectorArgumentListAST *iter = ast->selector_argument_list; iter;
          iter = iter->next) {
         const Identifier *id = identifier(iter->value->name_token);
         if (id == _id) {
             LookupContext context = currentContext(iter->value);
-            const QList<Symbol *> candidates = context.resolve(ast->selector_name);
+            const QList<Symbol *> candidates = context.resolve(ast->name);
             reportResult(iter->value->name_token, candidates);
         }
     }
+#endif
 
     return false;
 }
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
index 313676fc909..ef964deb9ed 100644
--- a/src/libs/cplusplus/FindUsages.h
+++ b/src/libs/cplusplus/FindUsages.h
@@ -99,8 +99,7 @@ protected:
     virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
     virtual bool visit(FunctionDeclaratorAST *ast);
     virtual bool visit(SimpleDeclarationAST *);
-    virtual bool visit(ObjCSelectorWithoutArgumentsAST *ast);
-    virtual bool visit(ObjCSelectorWithArgumentsAST *ast);
+    virtual bool visit(ObjCSelectorAST *ast);
 
 private:
     const Identifier *_id;
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 2425fef4226..4102043e747 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -803,12 +803,12 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
             }
         }
 
-        if (klassName&&ast->selector && ast->selector->selector_name) {
+        if (klassName&&ast->selector && ast->selector->name) {
             ResolveObjCClass resolveObjCClass;
             QList<Symbol *> resolvedSymbols = resolveObjCClass(klassName, result, _context);
             foreach (Symbol *resolvedSymbol, resolvedSymbols)
                 if (ObjCClass *klass = resolvedSymbol->asObjCClass())
-                    _results.append(resolveMember(ast->selector->selector_name, klass));
+                    _results.append(resolveMember(ast->selector->name, klass));
         }
     }
 
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index c85e4a7b6f6..91631c8a05a 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1498,6 +1498,15 @@ unsigned SimpleNameAST::lastToken() const
     return identifier_token + 1;
 }
 
+unsigned ObjCSelectorAST::firstToken() const
+{
+    return selector_argument_list->firstToken();
+}
+
+unsigned ObjCSelectorAST::lastToken() const
+{
+    return selector_argument_list->lastToken();
+}
 
 unsigned SimpleSpecifierAST::firstToken() const
 {
@@ -2089,16 +2098,6 @@ unsigned ObjCEncodeExpressionAST::lastToken() const
     return encode_token + 1;
 }
 
-unsigned ObjCSelectorWithoutArgumentsAST::firstToken() const
-{
-    return name_token;
-}
-
-unsigned ObjCSelectorWithoutArgumentsAST::lastToken() const
-{
-    return name_token + 1;
-}
-
 unsigned ObjCSelectorArgumentAST::firstToken() const
 {
     return name_token;
@@ -2112,16 +2111,6 @@ unsigned ObjCSelectorArgumentAST::lastToken() const
         return name_token + 1;
 }
 
-unsigned ObjCSelectorWithArgumentsAST::firstToken() const
-{
-    return selector_argument_list->firstToken();
-}
-
-unsigned ObjCSelectorWithArgumentsAST::lastToken() const
-{
-    return selector_argument_list->lastToken();
-}
-
 unsigned ObjCSelectorExpressionAST::firstToken() const
 {
     return selector_token;
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index cccba947eeb..9b30e6c8ca0 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -238,8 +238,6 @@ public:
     virtual ObjCSelectorAST *asObjCSelector() { return 0; }
     virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return 0; }
     virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return 0; }
-    virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return 0; }
-    virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return 0; }
     virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return 0; }
     virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; }
     virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; }
@@ -371,15 +369,41 @@ public:
     virtual PostfixDeclaratorAST *clone(MemoryPool *pool) const = 0;
 };
 
-class CPLUSPLUS_EXPORT ObjCSelectorAST: public AST
+class CPLUSPLUS_EXPORT ObjCSelectorArgumentAST: public AST
 {
-public: // annotation
-    const Name *selector_name;
+public:
+    unsigned name_token;
+    unsigned colon_token;
+
+public:
+    virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCSelectorArgumentAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
+};
+
+class CPLUSPLUS_EXPORT ObjCSelectorAST: public NameAST
+{
+public:
+    ObjCSelectorArgumentListAST *selector_argument_list;
 
 public:
     virtual ObjCSelectorAST *asObjCSelector() { return this; }
 
-    virtual ObjCSelectorAST *clone(MemoryPool *pool) const = 0;
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCSelectorAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+    virtual bool match0(AST *, ASTMatcher *);
 };
 
 class CPLUSPLUS_EXPORT SimpleSpecifierAST: public SpecifierAST
@@ -2766,61 +2790,6 @@ protected:
     virtual bool match0(AST *, ASTMatcher *);
 };
 
-class CPLUSPLUS_EXPORT ObjCSelectorWithoutArgumentsAST: public ObjCSelectorAST
-{
-public:
-    unsigned name_token;
-
-public:
-    virtual ObjCSelectorWithoutArgumentsAST *asObjCSelectorWithoutArguments() { return this; }
-
-    virtual unsigned firstToken() const;
-    virtual unsigned lastToken() const;
-
-    virtual ObjCSelectorWithoutArgumentsAST *clone(MemoryPool *pool) const;
-
-protected:
-    virtual void accept0(ASTVisitor *visitor);
-    virtual bool match0(AST *, ASTMatcher *);
-};
-
-class CPLUSPLUS_EXPORT ObjCSelectorArgumentAST: public AST
-{
-public:
-    unsigned name_token;
-    unsigned colon_token;
-
-public:
-    virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return this; }
-
-    virtual unsigned firstToken() const;
-    virtual unsigned lastToken() const;
-
-    virtual ObjCSelectorArgumentAST *clone(MemoryPool *pool) const;
-
-protected:
-    virtual void accept0(ASTVisitor *visitor);
-    virtual bool match0(AST *, ASTMatcher *);
-};
-
-class CPLUSPLUS_EXPORT ObjCSelectorWithArgumentsAST: public ObjCSelectorAST
-{
-public:
-    ObjCSelectorArgumentListAST *selector_argument_list;
-
-public:
-    virtual ObjCSelectorWithArgumentsAST *asObjCSelectorWithArguments() { return this; }
-
-    virtual unsigned firstToken() const;
-    virtual unsigned lastToken() const;
-
-    virtual ObjCSelectorWithArgumentsAST *clone(MemoryPool *pool) const;
-
-protected:
-    virtual void accept0(ASTVisitor *visitor);
-    virtual bool match0(AST *, ASTMatcher *);
-};
-
 class CPLUSPLUS_EXPORT ObjCSelectorExpressionAST: public ExpressionAST
 {
 public:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 984b7d95265..4b9ee114681 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -40,6 +40,23 @@
 
 using namespace CPlusPlus;
 
+ObjCSelectorArgumentAST *ObjCSelectorArgumentAST::clone(MemoryPool *pool) const
+{
+    ObjCSelectorArgumentAST *ast = new (pool) ObjCSelectorArgumentAST;
+    ast->name_token = name_token;
+    ast->colon_token = colon_token;
+    return ast;
+}
+
+ObjCSelectorAST *ObjCSelectorAST::clone(MemoryPool *pool) const
+{
+    ObjCSelectorAST *ast = new (pool) ObjCSelectorAST;
+    for (ObjCSelectorArgumentListAST *iter = selector_argument_list, **ast_iter = &ast->selector_argument_list;
+         iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
+        *ast_iter = new (pool) ObjCSelectorArgumentListAST((iter->value) ? iter->value->clone(pool) : 0);
+    return ast;
+}
+
 SimpleSpecifierAST *SimpleSpecifierAST::clone(MemoryPool *pool) const
 {
     SimpleSpecifierAST *ast = new (pool) SimpleSpecifierAST;
@@ -1351,30 +1368,6 @@ ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const
     return ast;
 }
 
-ObjCSelectorWithoutArgumentsAST *ObjCSelectorWithoutArgumentsAST::clone(MemoryPool *pool) const
-{
-    ObjCSelectorWithoutArgumentsAST *ast = new (pool) ObjCSelectorWithoutArgumentsAST;
-    ast->name_token = name_token;
-    return ast;
-}
-
-ObjCSelectorArgumentAST *ObjCSelectorArgumentAST::clone(MemoryPool *pool) const
-{
-    ObjCSelectorArgumentAST *ast = new (pool) ObjCSelectorArgumentAST;
-    ast->name_token = name_token;
-    ast->colon_token = colon_token;
-    return ast;
-}
-
-ObjCSelectorWithArgumentsAST *ObjCSelectorWithArgumentsAST::clone(MemoryPool *pool) const
-{
-    ObjCSelectorWithArgumentsAST *ast = new (pool) ObjCSelectorWithArgumentsAST;
-    for (ObjCSelectorArgumentListAST *iter = selector_argument_list, **ast_iter = &ast->selector_argument_list;
-         iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) ObjCSelectorArgumentListAST((iter->value) ? iter->value->clone(pool) : 0);
-    return ast;
-}
-
 ObjCSelectorExpressionAST *ObjCSelectorExpressionAST::clone(MemoryPool *pool) const
 {
     ObjCSelectorExpressionAST *ast = new (pool) ObjCSelectorExpressionAST;
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index 8ffc5e6cbd2..86c0db3b68b 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -41,6 +41,22 @@
 
 using namespace CPlusPlus;
 
+bool ObjCSelectorArgumentAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorArgumentAST *_other = pattern->asObjCSelectorArgument())
+        return matcher->match(this, _other);
+
+    return false;
+}
+
+bool ObjCSelectorAST::match0(AST *pattern, ASTMatcher *matcher)
+{
+    if (ObjCSelectorAST *_other = pattern->asObjCSelector())
+        return matcher->match(this, _other);
+
+    return false;
+}
+
 bool SimpleSpecifierAST::match0(AST *pattern, ASTMatcher *matcher)
 {
     if (SimpleSpecifierAST *_other = pattern->asSimpleSpecifier())
@@ -937,30 +953,6 @@ bool ObjCEncodeExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
     return false;
 }
 
-bool ObjCSelectorWithoutArgumentsAST::match0(AST *pattern, ASTMatcher *matcher)
-{
-    if (ObjCSelectorWithoutArgumentsAST *_other = pattern->asObjCSelectorWithoutArguments())
-        return matcher->match(this, _other);
-
-    return false;
-}
-
-bool ObjCSelectorArgumentAST::match0(AST *pattern, ASTMatcher *matcher)
-{
-    if (ObjCSelectorArgumentAST *_other = pattern->asObjCSelectorArgument())
-        return matcher->match(this, _other);
-
-    return false;
-}
-
-bool ObjCSelectorWithArgumentsAST::match0(AST *pattern, ASTMatcher *matcher)
-{
-    if (ObjCSelectorWithArgumentsAST *_other = pattern->asObjCSelectorWithArguments())
-        return matcher->match(this, _other);
-
-    return false;
-}
-
 bool ObjCSelectorExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
 {
     if (ObjCSelectorExpressionAST *_other = pattern->asObjCSelectorExpression())
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index e891d606ce7..0c229332189 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -47,6 +47,31 @@ ASTMatcher::ASTMatcher()
 ASTMatcher::~ASTMatcher()
 { }
 
+bool ASTMatcher::match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern)
+{
+    (void) node;
+    (void) pattern;
+
+    pattern->name_token = node->name_token;
+
+    pattern->colon_token = node->colon_token;
+
+    return true;
+}
+
+bool ASTMatcher::match(ObjCSelectorAST *node, ObjCSelectorAST *pattern)
+{
+    (void) node;
+    (void) pattern;
+
+    if (! pattern->selector_argument_list)
+        pattern->selector_argument_list = node->selector_argument_list;
+    else if (! AST::match(node->selector_argument_list, pattern->selector_argument_list, this))
+        return false;
+
+    return true;
+}
+
 bool ASTMatcher::match(SimpleSpecifierAST *node, SimpleSpecifierAST *pattern)
 {
     (void) node;
@@ -2272,41 +2297,6 @@ bool ASTMatcher::match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *p
     return true;
 }
 
-bool ASTMatcher::match(ObjCSelectorWithoutArgumentsAST *node, ObjCSelectorWithoutArgumentsAST *pattern)
-{
-    (void) node;
-    (void) pattern;
-
-    pattern->name_token = node->name_token;
-
-    return true;
-}
-
-bool ASTMatcher::match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern)
-{
-    (void) node;
-    (void) pattern;
-
-    pattern->name_token = node->name_token;
-
-    pattern->colon_token = node->colon_token;
-
-    return true;
-}
-
-bool ASTMatcher::match(ObjCSelectorWithArgumentsAST *node, ObjCSelectorWithArgumentsAST *pattern)
-{
-    (void) node;
-    (void) pattern;
-
-    if (! pattern->selector_argument_list)
-        pattern->selector_argument_list = node->selector_argument_list;
-    else if (! AST::match(node->selector_argument_list, pattern->selector_argument_list, this))
-        return false;
-
-    return true;
-}
-
 bool ASTMatcher::match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAST *pattern)
 {
     (void) node;
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index d0b1e1cffff..7d4f5b5b96f 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -146,14 +146,13 @@ public:
     virtual bool match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclarationAST *pattern);
     virtual bool match(ObjCProtocolForwardDeclarationAST *node, ObjCProtocolForwardDeclarationAST *pattern);
     virtual bool match(ObjCProtocolRefsAST *node, ObjCProtocolRefsAST *pattern);
+    virtual bool match(ObjCSelectorAST *node, ObjCSelectorAST *pattern);
     virtual bool match(ObjCMessageExpressionAST *node, ObjCMessageExpressionAST *pattern);
     virtual bool match(ObjCMessageArgumentAST *node, ObjCMessageArgumentAST *pattern);
     virtual bool match(ObjCProtocolExpressionAST *node, ObjCProtocolExpressionAST *pattern);
     virtual bool match(ObjCTypeNameAST *node, ObjCTypeNameAST *pattern);
     virtual bool match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *pattern);
-    virtual bool match(ObjCSelectorWithoutArgumentsAST *node, ObjCSelectorWithoutArgumentsAST *pattern);
     virtual bool match(ObjCSelectorArgumentAST *node, ObjCSelectorArgumentAST *pattern);
-    virtual bool match(ObjCSelectorWithArgumentsAST *node, ObjCSelectorWithArgumentsAST *pattern);
     virtual bool match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAST *pattern);
     virtual bool match(ObjCInstanceVariablesDeclarationAST *node, ObjCInstanceVariablesDeclarationAST *pattern);
     virtual bool match(ObjCVisibilityDeclarationAST *node, ObjCVisibilityDeclarationAST *pattern);
diff --git a/src/shared/cplusplus/ASTPatternBuilder.h b/src/shared/cplusplus/ASTPatternBuilder.h
index aa95d8fe352..5d8da60a001 100644
--- a/src/shared/cplusplus/ASTPatternBuilder.h
+++ b/src/shared/cplusplus/ASTPatternBuilder.h
@@ -788,24 +788,12 @@ public:
         return __ast;
     }
 
-    ObjCSelectorWithoutArgumentsAST *ObjCSelectorWithoutArguments()
-    {
-        ObjCSelectorWithoutArgumentsAST *__ast = new (&pool) ObjCSelectorWithoutArgumentsAST;
-        return __ast;
-    }
-
     ObjCSelectorArgumentAST *ObjCSelectorArgument()
     {
         ObjCSelectorArgumentAST *__ast = new (&pool) ObjCSelectorArgumentAST;
         return __ast;
     }
 
-    ObjCSelectorWithArgumentsAST *ObjCSelectorWithArguments()
-    {
-        ObjCSelectorWithArgumentsAST *__ast = new (&pool) ObjCSelectorWithArgumentsAST;
-        return __ast;
-    }
-
     ObjCSelectorExpressionAST *ObjCSelectorExpression(ObjCSelectorAST *selector = 0)
     {
         ObjCSelectorExpressionAST *__ast = new (&pool) ObjCSelectorExpressionAST;
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index b7fccf6e48c..92e38f8265c 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -41,6 +41,21 @@
 
 using namespace CPlusPlus;
 
+void ObjCSelectorArgumentAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCSelectorAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(selector_argument_list, visitor);
+    }
+    visitor->endVisit(this);
+}
+
 void SimpleSpecifierAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
@@ -995,28 +1010,6 @@ void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
-void ObjCSelectorWithoutArgumentsAST::accept0(ASTVisitor *visitor)
-{
-    if (visitor->visit(this)) {
-    }
-    visitor->endVisit(this);
-}
-
-void ObjCSelectorArgumentAST::accept0(ASTVisitor *visitor)
-{
-    if (visitor->visit(this)) {
-    }
-    visitor->endVisit(this);
-}
-
-void ObjCSelectorWithArgumentsAST::accept0(ASTVisitor *visitor)
-{
-    if (visitor->visit(this)) {
-        accept(selector_argument_list, visitor);
-    }
-    visitor->endVisit(this);
-}
-
 void ObjCSelectorExpressionAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index aedf1295947..e343c4e9be9 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -211,14 +211,13 @@ public:
     virtual bool visit(ObjCProtocolDeclarationAST *) { return true; }
     virtual bool visit(ObjCProtocolForwardDeclarationAST *) { return true; }
     virtual bool visit(ObjCProtocolRefsAST *) { return true; }
+    virtual bool visit(ObjCSelectorAST *) { return true; }
     virtual bool visit(ObjCMessageExpressionAST *) { return true; }
     virtual bool visit(ObjCMessageArgumentAST *) { return true; }
     virtual bool visit(ObjCProtocolExpressionAST *) { return true; }
     virtual bool visit(ObjCTypeNameAST *) { return true; }
     virtual bool visit(ObjCEncodeExpressionAST *) { return true; }
-    virtual bool visit(ObjCSelectorWithoutArgumentsAST *) { return true; }
     virtual bool visit(ObjCSelectorArgumentAST *) { return true; }
-    virtual bool visit(ObjCSelectorWithArgumentsAST *) { return true; }
     virtual bool visit(ObjCSelectorExpressionAST *) { return true; }
     virtual bool visit(ObjCInstanceVariablesDeclarationAST *) { return true; }
     virtual bool visit(ObjCVisibilityDeclarationAST *) { return true; }
@@ -342,14 +341,13 @@ public:
     virtual void endVisit(ObjCProtocolDeclarationAST *) { }
     virtual void endVisit(ObjCProtocolForwardDeclarationAST *) { }
     virtual void endVisit(ObjCProtocolRefsAST *) { }
+    virtual void endVisit(ObjCSelectorAST *) { }
     virtual void endVisit(ObjCMessageExpressionAST *) { }
     virtual void endVisit(ObjCMessageArgumentAST *) { }
     virtual void endVisit(ObjCProtocolExpressionAST *) { }
     virtual void endVisit(ObjCTypeNameAST *) { }
     virtual void endVisit(ObjCEncodeExpressionAST *) { }
-    virtual void endVisit(ObjCSelectorWithoutArgumentsAST *) { }
     virtual void endVisit(ObjCSelectorArgumentAST *) { }
-    virtual void endVisit(ObjCSelectorWithArgumentsAST *) { }
     virtual void endVisit(ObjCSelectorExpressionAST *) { }
     virtual void endVisit(ObjCInstanceVariablesDeclarationAST *) { }
     virtual void endVisit(ObjCVisibilityDeclarationAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 9bce5ec76e0..4ea1d04c9de 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -145,8 +145,6 @@ class ObjCProtocolRefsAST;
 class ObjCSelectorAST;
 class ObjCSelectorArgumentAST;
 class ObjCSelectorExpressionAST;
-class ObjCSelectorWithArgumentsAST;
-class ObjCSelectorWithoutArgumentsAST;
 class ObjCSynchronizedStatementAST;
 class ObjCSynthesizedPropertiesDeclarationAST;
 class ObjCSynthesizedPropertyAST;
diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp
index 860e7d3078d..688fc405b2b 100644
--- a/src/shared/cplusplus/CheckDeclarator.cpp
+++ b/src/shared/cplusplus/CheckDeclarator.cpp
@@ -263,7 +263,7 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
 
     semantic()->check(ast->selector, _scope);
 
-    ObjCMethod *method = control()->newObjCMethod(location, ast->selector->selector_name);
+    ObjCMethod *method = control()->newObjCMethod(location, ast->selector->name);
     ast->symbol = method;
     method->setScope(_scope);
     method->setVisibility(semantic()->currentVisibility());
@@ -271,17 +271,15 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
     if (semantic()->isObjCClassMethod(tokenKind(ast->method_type_token)))
         method->setStorage(Symbol::Static);
 
-    if (ast->selector->asObjCSelectorWithArguments()) {
-        for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
-            ObjCMessageArgumentDeclarationAST *argDecl = it->value;
+    for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
+        ObjCMessageArgumentDeclarationAST *argDecl = it->value;
 
-            semantic()->check(argDecl, method->arguments());
-        }
-
-        if (ast->dot_dot_dot_token)
-            method->setVariadic(true);
+        semantic()->check(argDecl, method->arguments());
     }
 
+    if (ast->dot_dot_dot_token)
+        method->setVariadic(true);
+
     _fullySpecifiedType = FullySpecifiedType(method);
 
     return false;
diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp
index 98b5adea253..38675d5c09f 100644
--- a/src/shared/cplusplus/CheckName.cpp
+++ b/src/shared/cplusplus/CheckName.cpp
@@ -100,17 +100,6 @@ const Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_l
     return switchName(previousName);
 }
 
-const Name *CheckName::check(ObjCSelectorAST *args, Scope *scope)
-{
-    const Name *previousName = switchName(0);
-    Scope *previousScope = switchScope(scope);
-
-    accept(args);
-
-    (void) switchScope(previousScope);
-    return switchName(previousName);
-}
-
 void CheckName::check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope)
 {
     const Name *previousName = switchName(0);
@@ -375,21 +364,7 @@ bool CheckName::visit(TemplateIdAST *ast)
     return false;
 }
 
-bool CheckName::visit(ObjCSelectorWithoutArgumentsAST *ast)
-{
-    if (ast->name_token) {
-        std::vector<const Name *> names;
-        const Identifier *id = control()->findOrInsertIdentifier(spell(ast->name_token));
-        const NameId *nameId = control()->nameId(id);
-        names.push_back(nameId);
-        _name = control()->selectorNameId(&names[0], names.size(), false);
-        ast->selector_name = _name;
-    }
-
-    return false;
-}
-
-bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast)
+bool CheckName::visit(ObjCSelectorAST *ast)
 {
     std::vector<const Name *> names;
     for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) {
@@ -405,7 +380,7 @@ bool CheckName::visit(ObjCSelectorWithArgumentsAST *ast)
 
     if (!names.empty()) {
         _name = control()->selectorNameId(&names[0], names.size(), true);
-        ast->selector_name = _name;
+        ast->name = _name;
     }
 
     return false;
@@ -431,5 +406,3 @@ bool CheckName::visit(ObjCMessageArgumentDeclarationAST *ast)
 
     return false;
 }
-
-
diff --git a/src/shared/cplusplus/CheckName.h b/src/shared/cplusplus/CheckName.h
index 1484cb7848e..54398356e32 100644
--- a/src/shared/cplusplus/CheckName.h
+++ b/src/shared/cplusplus/CheckName.h
@@ -63,7 +63,6 @@ public:
 
     const Name *check(NameAST *name, Scope *scope);
     const Name *check(NestedNameSpecifierListAST *name, Scope *scope);
-    const Name *check(ObjCSelectorAST *args, Scope *scope);
     void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope);
 
 protected:
@@ -80,8 +79,7 @@ protected:
     virtual bool visit(TemplateIdAST *ast);
 
     // ObjC
-    virtual bool visit(ObjCSelectorWithoutArgumentsAST *ast);
-    virtual bool visit(ObjCSelectorWithArgumentsAST *ast);
+    virtual bool visit(ObjCSelectorAST *ast);
     virtual bool visit(ObjCMessageArgumentDeclarationAST *ast);
 
 private:
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 08ff9615d13..a7a70a45348 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -3620,7 +3620,7 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
     if (LA() == T_COLON) {
-        ObjCSelectorWithArgumentsAST *args = new (_pool) ObjCSelectorWithArgumentsAST;
+        ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
         ast->selector = args;
         ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST;
         args->selector_argument_list = last;
@@ -3636,9 +3636,11 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
             match(T_COLON, &last->value->colon_token);
         }
     } else {
-        ObjCSelectorWithoutArgumentsAST *args = new (_pool) ObjCSelectorWithoutArgumentsAST;
+        ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
         ast->selector = args;
-        args->name_token = identifier_token;
+        args->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
+        args->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
+        args->selector_argument_list->value->name_token = identifier_token;
     }
 
     match(T_RPAREN, &ast->rparen_token);
@@ -3727,7 +3729,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
             }
         }
 
-        ObjCSelectorWithArgumentsAST *selWithArgs = new (_pool) ObjCSelectorWithArgumentsAST;
+        ObjCSelectorAST *selWithArgs = new (_pool) ObjCSelectorAST;
         selWithArgs->selector_argument_list = selAst;
 
         selNode = selWithArgs;
@@ -3738,8 +3740,10 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
         unsigned name_token = 0;
         if (!parseObjCSelector(name_token))
             return false;
-        ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
-        sel->name_token = name_token;
+        ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
+        sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
+        sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
+        sel->selector_argument_list->value->name_token = name_token;
         selNode = sel;
         argNode = 0;
         return true;
@@ -5127,7 +5131,7 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
         ObjCMessageArgumentDeclarationAST *declaration = 0;
         parseObjCKeywordDeclaration(argument, declaration);
 
-        ObjCSelectorWithArgumentsAST *sel = new (_pool) ObjCSelectorWithArgumentsAST;
+        ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
         ast->selector = sel;
         ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST;
         sel->selector_argument_list = lastSel;
@@ -5160,8 +5164,10 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
             parseParameterDeclaration(parameter_declaration);
         }
     } else if (lookAtObjCSelector()) {
-        ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
-        parseObjCSelector(sel->name_token);
+        ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
+        sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
+        sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
+        parseObjCSelector(sel->selector_argument_list->value->name_token);
         ast->selector = sel;
     } else {
         _translationUnit->error(cursor(), "expected a selector");
@@ -5206,21 +5212,23 @@ bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node)
     case Token_getter: {
         node->attribute_identifier_token = consumeToken();
         match(T_EQUAL, &node->equals_token);
-        ObjCSelectorWithoutArgumentsAST *selector = new (_pool) ObjCSelectorWithoutArgumentsAST;
-        match(T_IDENTIFIER, &selector->name_token);
-        node->method_selector = selector;
+        ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
+        sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
+        sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
+        match(T_IDENTIFIER, &sel->selector_argument_list->value->name_token);
+        node->method_selector = sel;
         return true;
     }
 
     case Token_setter: {
         node->attribute_identifier_token = consumeToken();
         match(T_EQUAL, &node->equals_token);
-        ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST;
-        selector->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
-        selector->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
-        match(T_IDENTIFIER, &selector->selector_argument_list->value->name_token);
-        match(T_COLON, &selector->selector_argument_list->value->colon_token);
-        node->method_selector = selector;
+        ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
+        sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
+        sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
+        match(T_IDENTIFIER, &sel->selector_argument_list->value->name_token);
+        match(T_COLON, &sel->selector_argument_list->value->colon_token);
+        node->method_selector = sel;
         return true;
     }
 
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index d8d6d6617e9..9e663042039 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -160,9 +160,6 @@ const Name *Semantic::check(NameAST *name, Scope *scope)
 const Name *Semantic::check(NestedNameSpecifierListAST *name, Scope *scope)
 { return d->checkName->check(name, scope); }
 
-const Name *Semantic::check(ObjCSelectorAST *args, Scope *scope)
-{ return d->checkName->check(args, scope); }
-
 bool Semantic::skipFunctionBodies() const
 { return d->skipFunctionBodies; }
 
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index 60f82b892e0..af11f7a2b4b 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -87,7 +87,6 @@ public:
 
     const Name *check(NestedNameSpecifierListAST *name, Scope *scope);
 
-    const Name *check(ObjCSelectorAST *args, Scope *scope);
     FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope);
 
     void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope);
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index 14e82b6e8b0..2873c3689cf 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -741,8 +741,9 @@ void tst_AST::objc_method_attributes_1()
     QCOMPARE(unit->tokenKind(foo->method_type_token), (int) T_MINUS);
     QVERIFY(foo->type_name);
     QVERIFY(foo->selector);
-    QVERIFY(foo->selector->asObjCSelectorWithoutArguments());
-    QCOMPARE(unit->spell(foo->selector->asObjCSelectorWithoutArguments()->name_token), "foo");
+    QVERIFY(foo->selector->selector_argument_list->value);
+    QVERIFY(!foo->selector->selector_argument_list->next);
+    QCOMPARE(unit->spell(foo->selector->selector_argument_list->value->name_token), "foo");
     QVERIFY(foo->attribute_list);
     QVERIFY(foo->attribute_list->value);
     QVERIFY(! (foo->attribute_list->next));
@@ -767,8 +768,10 @@ void tst_AST::objc_method_attributes_1()
     QCOMPARE(unit->tokenKind(bar->method_type_token), (int) T_PLUS);
     QVERIFY(bar->type_name);
     QVERIFY(bar->selector);
-    QVERIFY(bar->selector->asObjCSelectorWithoutArguments());
-    QCOMPARE(unit->spell(bar->selector->asObjCSelectorWithoutArguments()->name_token), "bar");
+    QVERIFY(bar->selector->selector_argument_list);
+    QVERIFY(bar->selector->selector_argument_list->value);
+    QVERIFY(!bar->selector->selector_argument_list->next);
+    QCOMPARE(unit->spell(bar->selector->selector_argument_list->value->name_token), "bar");
     QVERIFY(bar->attribute_list);
     QVERIFY(bar->attribute_list->value);
     QVERIFY(! (bar->attribute_list->next));
@@ -954,9 +957,11 @@ void tst_AST::objc_msg_send_expression()
         QVERIFY(msgExpr->argument_list == 0);
 
         QVERIFY(msgExpr->selector);
-        ObjCSelectorWithoutArgumentsAST *sel = msgExpr->selector->asObjCSelectorWithoutArguments();
-        QVERIFY(sel);
-        QCOMPARE(QLatin1String(unit->identifier(sel->name_token)->chars()), QLatin1String("description"));
+        ObjCSelectorArgumentListAST *args = msgExpr->selector->selector_argument_list;
+        QVERIFY(args);
+        QVERIFY(args->value);
+        QVERIFY(! args->next);
+        QCOMPARE(QLatin1String(unit->identifier(args->value->name_token)->chars()), QLatin1String("description"));
     }
 }
 
diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp
index 2f6bcf47433..8823faf0c84 100644
--- a/tests/auto/cplusplus/semantic/tst_semantic.cpp
+++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp
@@ -667,8 +667,7 @@ public:
         return selectors;
     }
 
-    virtual bool visit(ObjCSelectorWithArgumentsAST *ast) {selectors.append(ast); return false;}
-    virtual bool visit(ObjCSelectorWithoutArgumentsAST *ast) {selectors.append(ast); return false;}
+    virtual bool visit(ObjCSelectorAST *ast) {selectors.append(ast); return false;}
 
 private:
     QList<ObjCSelectorAST *> selectors;
@@ -694,10 +693,10 @@ void tst_Semantic::objcSelector_2()
     QList<ObjCSelectorAST*>selectors = CollectSelectors(doc->unit)();
     QCOMPARE(selectors.size(), 2);
 
-    ObjCSelectorWithArgumentsAST *sel = selectors.at(1)->asObjCSelectorWithArguments();
+    ObjCSelectorAST *sel = selectors.at(1)->asObjCSelector();
     QVERIFY(sel);
 
-    const SelectorNameId *selId = sel->selector_name->asSelectorNameId();
+    const SelectorNameId *selId = sel->name->asSelectorNameId();
     QVERIFY(selId);
     QCOMPARE(selId->nameCount(), 3U);
     QCOMPARE(selId->nameAt(0)->identifier()->chars(), "a");
-- 
GitLab