From ef58d082ea6498f3c2bafeb68d8bd2359ec241c1 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Thu, 16 Jul 2009 12:44:47 +0200
Subject: [PATCH] Added ObjC encode expressions.

---
 src/shared/cplusplus/AST.cpp      | 32 +++++++++++++++++++++++++
 src/shared/cplusplus/AST.h        | 40 +++++++++++++++++++++++++++++++
 src/shared/cplusplus/ASTClone.cpp | 18 ++++++++++++++
 src/shared/cplusplus/ASTVisit.cpp | 22 +++++++++++++++++
 src/shared/cplusplus/ASTVisitor.h |  4 ++++
 src/shared/cplusplus/ASTfwd.h     |  2 ++
 src/shared/cplusplus/Parser.cpp   | 32 ++++++++++++++-----------
 src/shared/cplusplus/Parser.h     |  4 ++--
 8 files changed, 138 insertions(+), 16 deletions(-)

diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index eca2e200961..946ecf5cb53 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2123,4 +2123,36 @@ unsigned ObjCProtocolExpressionAST::lastToken() const
     return protocol_token + 1;
 }
 
+unsigned ObjCTypeNameAST::firstToken() const
+{
+    return lparen_token;
+}
+
+unsigned ObjCTypeNameAST::lastToken() const
+{
+    if (rparen_token)
+        return rparen_token + 1;
+
+    if (type_id)
+        return type_id->lastToken();
+
+    if (type_qualifier)
+        return type_qualifier + 1;
+
+    return lparen_token + 1;
+}
+
+unsigned ObjCEncodeExpressionAST::firstToken() const
+{
+    return encode_token;
+}
+
+unsigned ObjCEncodeExpressionAST::lastToken() const
+{
+    if (type_name)
+        return type_name->lastToken();
+
+    return encode_token + 1;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 981bb29b159..290a84324ba 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -2674,6 +2674,46 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT ObjCTypeNameAST: public AST
+{
+public:
+    unsigned lparen_token;
+    unsigned type_qualifier;
+    ExpressionAST *type_id;
+    unsigned rparen_token;
+
+public:
+    virtual ObjCTypeNameAST *asObjCTypeName()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCTypeNameAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST
+{
+public:
+    unsigned encode_token;
+    ObjCTypeNameAST *type_name;
+
+public:
+    virtual ObjCEncodeExpressionAST *asObjCEncodeExpression()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCEncodeExpressionAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
 
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index e12967651da..abc89510a5d 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1321,4 +1321,22 @@ ObjCProtocolExpressionAST *ObjCProtocolExpressionAST::clone(MemoryPool *pool) co
     return ast;
 }
 
+ObjCTypeNameAST *ObjCTypeNameAST::clone(MemoryPool *pool) const
+{
+    ObjCTypeNameAST *ast = new (pool) ObjCTypeNameAST;
+    ast->lparen_token = lparen_token;
+    ast->type_qualifier = type_qualifier;
+    if (type_id) ast->type_id = type_id->clone(pool);
+    ast->rparen_token = rparen_token;
+    return ast;
+}
+
+ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const
+{
+    ObjCEncodeExpressionAST *ast = new (pool) ObjCEncodeExpressionAST;
+    ast->encode_token = encode_token;
+    if (type_name) ast->type_name = type_name->clone(pool);
+    return ast;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 1980ec78f9f..02f1218afee 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1243,4 +1243,26 @@ void ObjCProtocolExpressionAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void ObjCTypeNameAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCTypeNameAST
+        if (type_id)
+            accept(type_id, visitor);
+        // visit AST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCEncodeExpressionAST
+        if (type_name)
+            accept(type_name, visitor);
+        // visit ExpressionAST
+    }
+    visitor->endVisit(this);
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 6509235f44e..130c6662622 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -207,6 +207,8 @@ public:
     virtual bool visit(ObjCMessageArgumentListAST *) { 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(DeclarationListAST *) { return true; }
     virtual void endVisit(DeclarationListAST *) { }
@@ -325,6 +327,8 @@ public:
     virtual void endVisit(ObjCMessageArgumentListAST *) { }
     virtual void endVisit(ObjCMessageArgumentAST *) { }
     virtual void endVisit(ObjCProtocolExpressionAST *) { }
+    virtual void endVisit(ObjCTypeNameAST *) { }
+    virtual void endVisit(ObjCEncodeExpressionAST *) { }
 
 private:
     Control *_control;
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index a70ad55da5d..f25e293282e 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -180,6 +180,8 @@ class ObjCMessageExpressionAST;
 class ObjCMessageArgumentListAST;
 class ObjCMessageArgumentAST;
 class ObjCProtocolExpressionAST;
+class ObjCTypeNameAST;
+class ObjCEncodeExpressionAST;
 
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 6ba6541068d..571ceaa074a 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2839,13 +2839,15 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
     return true;
 }
 
-bool Parser::parseObjCEncodeExpression(ExpressionAST *&)
+bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
 {
     if (LA() != T_AT_ENCODE)
         return false;
 
-    /*unsigned encode_token = */ consumeToken();
-    parseObjCTypeName();
+    ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
+    ast->encode_token = consumeToken();
+    parseObjCTypeName(ast->type_name);
+    node = ast;
     return true;
 }
 
@@ -4349,7 +4351,8 @@ bool Parser::parseObjCMethodPrototype()
 
     /*unsigned method_type_token = */ consumeToken();
 
-    parseObjCTypeName();
+    ObjCTypeNameAST *type_name = 0;
+    parseObjCTypeName(type_name);
 
     unsigned selector_token = 0;
 
@@ -4408,17 +4411,17 @@ bool Parser::parseObjCPropertyAttribute()
 
 // objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
 //
-bool Parser::parseObjCTypeName()
+bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
 {
     if (LA() != T_LPAREN)
         return false;
 
-    unsigned lparen_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    parseObjCTypeQualifiers();
-    ExpressionAST *type_id = 0;
-    parseTypeId(type_id);
-    match(T_RPAREN, &rparen_token);
+    ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST;
+    match(T_LPAREN, &(ast->lparen_token));
+    parseObjCTypeQualifiers(ast->type_qualifier);
+    parseTypeId(ast->type_id);
+    match(T_RPAREN, &(ast->rparen_token));
+    node = ast;
     return true;
 }
 
@@ -4446,7 +4449,8 @@ bool Parser::parseObjCKeywordDeclaration()
     unsigned colon_token = 0;
     match(T_COLON, &colon_token);
 
-    parseObjCTypeName();
+    ObjCTypeNameAST *type_name = 0;
+    parseObjCTypeName(type_name);
 
     SpecifierAST *attributes = 0, **attr = &attributes;
     while (parseAttributeSpecifier(*attr))
@@ -4458,7 +4462,7 @@ bool Parser::parseObjCKeywordDeclaration()
     return true;
 }
 
-bool Parser::parseObjCTypeQualifiers()
+bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
 {
     if (LA() != T_IDENTIFIER)
         return false;
@@ -4467,7 +4471,7 @@ bool Parser::parseObjCTypeQualifiers()
     const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
     if (k == Token_identifier)
         return false;
-    consumeToken();
+    type_qualifier = consumeToken();
     return true;
 }
 
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index c81312d94f9..2de07f1bea8 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -240,10 +240,10 @@ public:
     bool parseObjCImplementation(DeclarationAST *&node);
     bool parseObjCMethodPrototype();
     bool parseObjCPropertyAttribute();
-    bool parseObjCTypeName();
+    bool parseObjCTypeName(ObjCTypeNameAST *&node);
     bool parseObjCSelector(unsigned &selector_token);
     bool parseObjCKeywordDeclaration();
-    bool parseObjCTypeQualifiers();
+    bool parseObjCTypeQualifiers(unsigned &type_qualifier);
     bool parseObjCEnd(DeclarationAST *&node);
 
     bool lookAtObjCSelector() const;
-- 
GitLab