From cf125618afe323da0b1d63eb01ff70fbbaaef3d0 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Wed, 24 Mar 2010 14:56:30 +0100
Subject: [PATCH] Accepts trailing return types.

---
 src/shared/cplusplus/AST.cpp        | 5 ++++-
 src/shared/cplusplus/AST.h          | 2 ++
 src/shared/cplusplus/ASTClone.cpp   | 2 ++
 src/shared/cplusplus/ASTMatcher.cpp | 5 +++++
 src/shared/cplusplus/ASTVisit.cpp   | 1 +
 src/shared/cplusplus/Parser.cpp     | 6 ++++++
 6 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 76771804550..5963dae91be 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1014,7 +1014,10 @@ unsigned FunctionDeclaratorAST::firstToken() const
 
 unsigned FunctionDeclaratorAST::lastToken() const
 {
-    if (exception_specification)
+    if (trailing_return_type)
+        return trailing_return_type->lastToken();
+
+    else if (exception_specification)
         return exception_specification->lastToken();
 
     else if (cv_qualifier_list)
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 6335fce4ba3..82cae89361a 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -1421,6 +1421,7 @@ public:
     unsigned rparen_token;
     SpecifierListAST *cv_qualifier_list;
     ExceptionSpecificationAST *exception_specification;
+    TrailingReturnTypeAST *trailing_return_type;
     ExpressionAST *as_cpp_initializer;
 
 public: // annotations
@@ -1433,6 +1434,7 @@ public:
         , rparen_token(0)
         , cv_qualifier_list(0)
         , exception_specification(0)
+        , trailing_return_type(0)
         , as_cpp_initializer(0)
         , symbol(0)
     {}
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 425c81c76eb..bd143b45fc7 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -474,6 +474,8 @@ FunctionDeclaratorAST *FunctionDeclaratorAST::clone(MemoryPool *pool) const
         *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
     if (exception_specification)
         ast->exception_specification = exception_specification->clone(pool);
+    if (trailing_return_type)
+        ast->trailing_return_type = trailing_return_type->clone(pool);
     if (as_cpp_initializer)
         ast->as_cpp_initializer = as_cpp_initializer->clone(pool);
     return ast;
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index 75ec26467dc..d08bfffc0e9 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -780,6 +780,11 @@ bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *patte
     else if (! AST::match(node->exception_specification, pattern->exception_specification, this))
         return false;
 
+    if (! pattern->trailing_return_type)
+        pattern->trailing_return_type = node->trailing_return_type;
+    else if (! AST::match(node->trailing_return_type, pattern->trailing_return_type, this))
+        return false;
+
     if (! pattern->as_cpp_initializer)
         pattern->as_cpp_initializer = node->as_cpp_initializer;
     else if (! AST::match(node->as_cpp_initializer, pattern->as_cpp_initializer, this))
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 9e3b249ef3a..d2a0812db48 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -350,6 +350,7 @@ void FunctionDeclaratorAST::accept0(ASTVisitor *visitor)
         accept(parameters, visitor);
         accept(cv_qualifier_list, visitor);
         accept(exception_specification, visitor);
+        accept(trailing_return_type, visitor);
         accept(as_cpp_initializer, visitor);
     }
     visitor->endVisit(this);
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index dc9d2da509c..a3599dc14e6 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -1315,8 +1315,14 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer)
             }
 
             ast->rparen_token = consumeToken();
+            // ### parse attributes
             parseCvQualifiers(ast->cv_qualifier_list);
+            // ### parse ref-qualifiers
             parseExceptionSpecification(ast->exception_specification);
+
+            if (_cxx0xEnabled && ! node->ptr_operator_list && LA() == T_ARROW)
+                parseTrailingReturnType(ast->trailing_return_type);
+
             *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
             postfix_ptr = &(*postfix_ptr)->next;
         } else if (LA() == T_LBRACKET) {
-- 
GitLab