From 248480b7c952b2b981e3ec9c40bf0f0761c12ac5 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <qtc-committer@nokia.com>
Date: Tue, 13 Jan 2009 14:58:29 +0100
Subject: [PATCH] Added support for C99 compound literals.

---
 shared/cplusplus/AST.cpp             | 39 ++++++++++++++++++++++++++++
 shared/cplusplus/AST.h               | 19 ++++++++++++++
 shared/cplusplus/ASTVisitor.h        |  1 +
 shared/cplusplus/ASTfwd.h            |  1 +
 shared/cplusplus/CheckExpression.cpp |  7 +++++
 shared/cplusplus/CheckExpression.h   |  1 +
 shared/cplusplus/Parser.cpp          | 27 ++++++++++++++++---
 shared/cplusplus/PrettyPrinter.cpp   | 10 +++++++
 shared/cplusplus/PrettyPrinter.h     |  1 +
 9 files changed, 103 insertions(+), 3 deletions(-)

diff --git a/shared/cplusplus/AST.cpp b/shared/cplusplus/AST.cpp
index 11be99ea48a..6889ba6fa8c 100644
--- a/shared/cplusplus/AST.cpp
+++ b/shared/cplusplus/AST.cpp
@@ -117,6 +117,9 @@ CatchClauseAST *AST::asCatchClause()
 ClassSpecifierAST *AST::asClassSpecifier()
 { return dynamic_cast<ClassSpecifierAST *>(this); }
 
+CompoundLiteralAST *AST::asCompoundLiteral()
+{ return dynamic_cast<CompoundLiteralAST *>(this); }
+
 CompoundStatementAST *AST::asCompoundStatement()
 { return dynamic_cast<CompoundStatementAST *>(this); }
 
@@ -774,6 +777,42 @@ unsigned BoolLiteralAST::lastToken() const
     return token + 1;
 }
 
+CompoundLiteralAST *CompoundLiteralAST::clone(MemoryPool *pool) const
+{
+    CompoundLiteralAST *ast = new (pool) CompoundLiteralAST;
+    ast->lparen_token = lparen_token;
+    if (type_id)
+        ast->type_id = type_id->clone(pool);
+    ast->rparen_token = rparen_token;
+    if (initializer)
+        ast->initializer = initializer->clone(pool);
+    return ast;
+}
+
+void CompoundLiteralAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        accept(type_id, visitor);
+        accept(initializer, visitor);
+    }
+}
+
+unsigned CompoundLiteralAST::firstToken() const
+{
+    return lparen_token;
+}
+
+unsigned CompoundLiteralAST::lastToken() const
+{
+    if (initializer)
+        return initializer->lastToken();
+    else if (rparen_token)
+        return rparen_token + 1;
+    else if (type_id)
+        return type_id->lastToken();
+    return lparen_token + 1;
+}
+
 BreakStatementAST *BreakStatementAST::clone(MemoryPool *pool) const
 {
     BreakStatementAST *ast = new (pool) BreakStatementAST;
diff --git a/shared/cplusplus/AST.h b/shared/cplusplus/AST.h
index 6607e76805b..46322fdd6bc 100644
--- a/shared/cplusplus/AST.h
+++ b/shared/cplusplus/AST.h
@@ -94,6 +94,7 @@ public:
     CastExpressionAST *asCastExpression();
     CatchClauseAST *asCatchClause();
     ClassSpecifierAST *asClassSpecifier();
+    CompoundLiteralAST *asCompoundLiteral();
     CompoundStatementAST *asCompoundStatement();
     ConditionAST *asCondition();
     ConditionalExpressionAST *asConditionalExpression();
@@ -429,6 +430,24 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT CompoundLiteralAST: public ExpressionAST
+{
+public:
+    unsigned lparen_token;
+    ExpressionAST *type_id;
+    unsigned rparen_token;
+    ExpressionAST *initializer;
+
+public:
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual CompoundLiteralAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
 class CPLUSPLUS_EXPORT QtMethodAST: public ExpressionAST
 {
 public:
diff --git a/shared/cplusplus/ASTVisitor.h b/shared/cplusplus/ASTVisitor.h
index 28097c14f70..e7a9aed1584 100644
--- a/shared/cplusplus/ASTVisitor.h
+++ b/shared/cplusplus/ASTVisitor.h
@@ -104,6 +104,7 @@ public:
     virtual bool visit(CastExpressionAST *) { return true; }
     virtual bool visit(CatchClauseAST *) { return true; }
     virtual bool visit(ClassSpecifierAST *) { return true; }
+    virtual bool visit(CompoundLiteralAST *) { return true; }
     virtual bool visit(CompoundStatementAST *) { return true; }
     virtual bool visit(ConditionAST *) { return true; }
     virtual bool visit(ConditionalExpressionAST *) { return true; }
diff --git a/shared/cplusplus/ASTfwd.h b/shared/cplusplus/ASTfwd.h
index 79f794f629e..db68992e022 100644
--- a/shared/cplusplus/ASTfwd.h
+++ b/shared/cplusplus/ASTfwd.h
@@ -77,6 +77,7 @@ class CaseStatementAST;
 class CastExpressionAST;
 class CatchClauseAST;
 class ClassSpecifierAST;
+class CompoundLiteralAST;
 class CompoundStatementAST;
 class ConditionAST;
 class ConditionalExpressionAST;
diff --git a/shared/cplusplus/CheckExpression.cpp b/shared/cplusplus/CheckExpression.cpp
index 9976cbf500e..d5d88c38572 100644
--- a/shared/cplusplus/CheckExpression.cpp
+++ b/shared/cplusplus/CheckExpression.cpp
@@ -333,6 +333,13 @@ bool CheckExpression::visit(QtMethodAST *ast)
     return false;
 }
 
+bool CheckExpression::visit(CompoundLiteralAST *ast)
+{
+    /*FullySpecifiedType exprTy = */ semantic()->check(ast->type_id, _scope);
+    /*FullySpecifiedType initTy = */ semantic()->check(ast->initializer, _scope);
+    return false;
+}
+
 bool CheckExpression::visit(CallAST *ast)
 {
     for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
diff --git a/shared/cplusplus/CheckExpression.h b/shared/cplusplus/CheckExpression.h
index e018e7dc89b..f5c9e7c8e94 100644
--- a/shared/cplusplus/CheckExpression.h
+++ b/shared/cplusplus/CheckExpression.h
@@ -98,6 +98,7 @@ protected:
     virtual bool visit(TypeIdAST *ast);
     virtual bool visit(UnaryExpressionAST *ast);
     virtual bool visit(QtMethodAST *ast);
+    virtual bool visit(CompoundLiteralAST *ast);
 
     //names
     virtual bool visit(QualifiedNameAST *ast);
diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp
index 407cbc36fd8..0e49e9fe88a 100644
--- a/shared/cplusplus/Parser.cpp
+++ b/shared/cplusplus/Parser.cpp
@@ -1621,8 +1621,7 @@ bool Parser::parseInitializerClause(ExpressionAST *&node)
         ArrayInitializerAST *ast = new (_pool) ArrayInitializerAST;
         ast->lbrace_token = consumeToken();
         parseInitializerList(ast->expression_list);
-        if (LA() == T_RBRACE)
-            ast->rbrace_token = consumeToken();
+        match(T_RBRACE, &ast->rbrace_token);
         node = ast;
         return true;
     }
@@ -2702,8 +2701,30 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
                 return true;
             }
         }
-        blockErrors(blocked);
         rewind(start);
+
+        // look for compound literals
+        if (LA() == T_LPAREN) {
+            unsigned lparen_token = consumeToken();
+            ExpressionAST *type_id = 0;
+            if (parseTypeId(type_id) && LA() == T_RPAREN) {
+                unsigned rparen_token = consumeToken();
+                if (LA() == T_LBRACE) {
+                    blockErrors(blocked);
+
+                    CompoundLiteralAST *ast = new (_pool) CompoundLiteralAST;
+                    ast->lparen_token = lparen_token;
+                    ast->type_id = type_id;
+                    ast->rparen_token = rparen_token;
+                    parseInitializerClause(ast->initializer);
+                    node = ast;
+                    return true;
+                }
+            }
+            rewind(start);
+        }
+
+        blockErrors(blocked);
         return parsePrimaryExpression(node);
     }
 }
diff --git a/shared/cplusplus/PrettyPrinter.cpp b/shared/cplusplus/PrettyPrinter.cpp
index 72338576b6b..af80cee197e 100644
--- a/shared/cplusplus/PrettyPrinter.cpp
+++ b/shared/cplusplus/PrettyPrinter.cpp
@@ -1281,3 +1281,13 @@ bool PrettyPrinter::visit(QtMethodAST *ast)
     out << ')';
     return false;
 }
+
+bool PrettyPrinter::visit(CompoundLiteralAST *ast)
+{
+    out << '(';
+    accept(ast->type_id);
+    out << ')';
+    out << ' ';
+    accept(ast->initializer);
+    return false;
+}
diff --git a/shared/cplusplus/PrettyPrinter.h b/shared/cplusplus/PrettyPrinter.h
index 966ebacd0e6..fc59100a3c1 100644
--- a/shared/cplusplus/PrettyPrinter.h
+++ b/shared/cplusplus/PrettyPrinter.h
@@ -66,6 +66,7 @@ protected:
     virtual bool visit(CastExpressionAST *ast);
     virtual bool visit(CatchClauseAST *ast);
     virtual bool visit(ClassSpecifierAST *ast);
+    virtual bool visit(CompoundLiteralAST *ast);
     virtual bool visit(CompoundStatementAST *ast);
     virtual bool visit(ConditionAST *ast);
     virtual bool visit(ConditionalExpressionAST *ast);
-- 
GitLab